generalize getNumberOfImmediateSubclasses to handle array classes
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2816 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
88607a3247
commit
17cd230c25
|
@ -1068,18 +1068,28 @@ public class ClassHierarchy implements IClassHierarchy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param klass
|
* @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) {
|
public int getNumberOfImmediateSubclasses(IClass klass) {
|
||||||
|
if (klass.isArrayClass()) {
|
||||||
|
IClass innermost = getInnermostTypeOfArrayClass(klass);
|
||||||
|
return innermost == null ? 0 : getNumberOfImmediateSubclasses(innermost);
|
||||||
|
}
|
||||||
Node node = findNode(klass);
|
Node node = findNode(klass);
|
||||||
return node.children.size();
|
return node.children.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param klass
|
* @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<IClass> getImmediateSubclasses(IClass klass) {
|
public Collection<IClass> getImmediateSubclasses(IClass klass) {
|
||||||
|
if (klass.isArrayClass()) {
|
||||||
|
return getImmediateArraySubclasses(klass);
|
||||||
|
}
|
||||||
Function<Node, IClass> node2Class = new Function<Node, IClass>() {
|
Function<Node, IClass> node2Class = new Function<Node, IClass>() {
|
||||||
public IClass apply(Node n) {
|
public IClass apply(Node n) {
|
||||||
return n.klass;
|
return n.klass;
|
||||||
|
@ -1088,6 +1098,35 @@ public class ClassHierarchy implements IClassHierarchy {
|
||||||
return Iterator2Collection.toCollection(new MapIterator<Node, IClass>(findNode(klass).children.iterator(), node2Class));
|
return Iterator2Collection.toCollection(new MapIterator<Node, IClass>(findNode(klass).children.iterator(), node2Class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<IClass> getImmediateArraySubclasses(IClass klass) {
|
||||||
|
IClass innermost = getInnermostTypeOfArrayClass(klass);
|
||||||
|
if (innermost == null) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
Collection<IClass> innermostSubclasses = getImmediateSubclasses(innermost);
|
||||||
|
int dim = klass.getReference().getDimensionality();
|
||||||
|
Collection<IClass> 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
|
* @return a ClassHierarchy object representing the analysis scope
|
||||||
* @throws ClassHierarchyException
|
* @throws ClassHierarchyException
|
||||||
|
|
Loading…
Reference in New Issue