From 17cd230c2553e2df8bc2e19a30d6713080b3b4d8 Mon Sep 17 00:00:00 2001 From: msridhar1 Date: Tue, 13 May 2008 20:52:34 +0000 Subject: [PATCH] generalize getNumberOfImmediateSubclasses to handle array classes git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2816 f5eafffb-2e1d-0410-98e4-8ec43c5233c4 --- .../com/ibm/wala/ipa/cha/ClassHierarchy.java | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/cha/ClassHierarchy.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/cha/ClassHierarchy.java index 7a70b75b7..00bbdc54b 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/cha/ClassHierarchy.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/cha/ClassHierarchy.java @@ -1068,18 +1068,28 @@ public class ClassHierarchy implements IClassHierarchy { /** * @param klass - * @return the number of classes that immediately extend klass. + * @return the number of classes that immediately extend klass. if klass is an array class A[][]...[], we return + * number of immediate subclasses of A. If A is primitive, we return 0. */ public int getNumberOfImmediateSubclasses(IClass klass) { + if (klass.isArrayClass()) { + IClass innermost = getInnermostTypeOfArrayClass(klass); + return innermost == null ? 0 : getNumberOfImmediateSubclasses(innermost); + } Node node = findNode(klass); return node.children.size(); } /** * @param klass - * @return the classes that immediately extend klass. + * @return the classes that immediately extend klass. if klass is an array class A[][]...[], we return array classes + * B[][]...[] (same dimensionality) where B is an immediate subclass of A. If A is primitive, we return the + * empty set. */ public Collection getImmediateSubclasses(IClass klass) { + if (klass.isArrayClass()) { + return getImmediateArraySubclasses(klass); + } Function node2Class = new Function() { public IClass apply(Node n) { return n.klass; @@ -1088,6 +1098,35 @@ public class ClassHierarchy implements IClassHierarchy { return Iterator2Collection.toCollection(new MapIterator(findNode(klass).children.iterator(), node2Class)); } + private Collection getImmediateArraySubclasses(IClass klass) { + IClass innermost = getInnermostTypeOfArrayClass(klass); + if (innermost == null) { + return Collections.emptySet(); + } + Collection innermostSubclasses = getImmediateSubclasses(innermost); + int dim = klass.getReference().getDimensionality(); + Collection result = HashSetFactory.make(); + for (IClass k : innermostSubclasses) { + TypeReference ref = k.getReference(); + for (int i = 0; i < dim; i++) { + ref = ref.getArrayTypeForElementType(); + } + result.add(lookupClass(ref)); + } + return result; + } + + /** + * for an array class, get the innermost type, or null if it's primitive + */ + private IClass getInnermostTypeOfArrayClass(IClass klass) { + TypeReference result = klass.getReference(); + while (result.isArrayType()) { + result = result.getArrayElementType(); + } + return result.isPrimitiveType() ? null : lookupClass(result); + } + /** * @return a ClassHierarchy object representing the analysis scope * @throws ClassHierarchyException