bug fix and related API changes for interface type tests

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2104 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2007-12-05 19:49:03 +00:00
parent fe69687001
commit 6723d33683
12 changed files with 39 additions and 77 deletions

View File

@ -66,7 +66,7 @@ public class PointType extends TypeAbstraction {
if (type.getClassHierarchy().isSubclassOf(typeKlass, other.getType())) { if (type.getClassHierarchy().isSubclassOf(typeKlass, other.getType())) {
return other; return other;
} else if (other.isInterface()) { } else if (other.isInterface()) {
if (type.getClassHierarchy().implementsInterface(typeKlass, T)) { if (type.getClassHierarchy().implementsInterface(typeKlass, other.getType())) {
return other; return other;
} }
} }

View File

@ -68,20 +68,16 @@ public interface IClass extends IClassHierarchyDweller {
/** /**
* @return Collection of (IClass) interfaces this class directly implements * @return Collection of (IClass) interfaces this class directly implements
* If this class is an interface, returns the interfaces it immediately extends.
*/ */
Collection<IClass> getDirectInterfaces() throws ClassHierarchyException; Collection<IClass> getDirectInterfaces() throws ClassHierarchyException;
/** /**
* @return Collection of (IClass) interfaces this class implements, including * @return Collection of (IClass) interfaces this class implements, including
* all ancestors of interfaces immediately implemented * all ancestors of interfaces immediately implemented.
*/ */
Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException; Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException;
/**
* @return Collection of (IClass) interfaces this class extends, including
* transitive ancestors
*/
Collection<IClass> getAllAncestorInterfaces() throws ClassHierarchyException;
/** /**
* Finds method matching signature. Delegates to superclass if not * Finds method matching signature. Delegates to superclass if not

View File

@ -503,8 +503,7 @@ public final class ShrikeClass implements IClass {
// didn't find it yet. special logic for interfaces // didn't find it yet. special logic for interfaces
try { try {
if (isInterface() || isAbstract()) { if (isInterface() || isAbstract()) {
final Iterator<IClass> it = (isInterface()) ? getAllAncestorInterfaces().iterator() : getAllImplementedInterfaces() final Iterator<IClass> it = getAllImplementedInterfaces().iterator();
.iterator();
// try each superinterface // try each superinterface
while (it.hasNext()) { while (it.hasNext()) {
IClass k = it.next(); IClass k = it.next();
@ -544,8 +543,7 @@ public final class ShrikeClass implements IClass {
} }
// try superinterfaces // try superinterfaces
try { try {
Collection<IClass> ifaces = isInterface() ? getAllAncestorInterfaces() : getAllImplementedInterfaces(); for (IClass i : getAllImplementedInterfaces()) {
for (IClass i : ifaces) {
f = i.getField(name); f = i.getField(name);
if (f != null) { if (f != null) {
fieldMap.put(name, f); fieldMap.put(name, f);
@ -604,26 +602,6 @@ public final class ShrikeClass implements IClass {
} }
public Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException { public Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException {
if (Assertions.verifyAssertions) {
if (isInterface()) {
Assertions.UNREACHABLE("shouldn't ask for implemented interfaces of an interface " + this);
}
}
if (allInterfaces != null) {
return allInterfaces;
} else {
Collection<IClass> C = computeAllInterfacesAsCollection();
allInterfaces = Collections.unmodifiableCollection(C);
return allInterfaces;
}
}
public Collection<IClass> getAllAncestorInterfaces() throws ClassHierarchyException {
if (Assertions.verifyAssertions) {
if (!isInterface()) {
Assertions.UNREACHABLE();
}
}
if (allInterfaces != null) { if (allInterfaces != null) {
return allInterfaces; return allInterfaces;
} else { } else {

View File

@ -118,7 +118,7 @@ public class ClassHierarchyMethodTargetSelector implements MethodTargetSelector
return false; return false;
} else { } else {
if (resolvedType.isInterface()) { if (resolvedType.isInterface()) {
return cha.implementsInterface(dispatchType,resolvedType.getReference()); return cha.implementsInterface(dispatchType,resolvedType);
} else { } else {
return cha.isSubclassOf(dispatchType,resolvedType); return cha.isSubclassOf(dispatchType,resolvedType);
} }

View File

@ -55,16 +55,16 @@ public class ContainerUtil {
} }
if (ClassLoaderReference.Primordial.equals(C.getClassLoader().getReference())&& if (ClassLoaderReference.Primordial.equals(C.getClassLoader().getReference())&&
TypeReference.JavaUtilCollection.getName().getPackage().equals(C.getReference().getName().getPackage())) { TypeReference.JavaUtilCollection.getName().getPackage().equals(C.getReference().getName().getPackage())) {
IClass collection = cha.lookupClass(TypeReference.JavaUtilCollection);
IClass map = cha.lookupClass(TypeReference.JavaUtilMap);
if (C.isInterface()) { if (C.isInterface()) {
IClass collection = cha.lookupClass(TypeReference.JavaUtilCollection);
IClass map = cha.lookupClass(TypeReference.JavaUtilMap);
if (Assertions.verifyAssertions) { if (Assertions.verifyAssertions) {
Assertions._assert(collection != null); Assertions._assert(collection != null);
Assertions._assert(map != null); Assertions._assert(map != null);
} }
Collection s; Collection s;
try { try {
s = C.getAllAncestorInterfaces(); s = C.getAllImplementedInterfaces();
} catch (ClassHierarchyException e) { } catch (ClassHierarchyException e) {
// give up // give up
return false; return false;
@ -73,7 +73,7 @@ public class ContainerUtil {
return true; return true;
} }
} else { } else {
if (cha.implementsInterface(C, TypeReference.JavaUtilCollection) || cha.implementsInterface(C, TypeReference.JavaUtilMap)) { if (cha.implementsInterface(C, collection) || cha.implementsInterface(C, map)) {
return true; return true;
} }
} }

View File

@ -402,7 +402,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
if (klass.isInterface()) { if (klass.isInterface()) {
for (Iterator it = rhsSet.iterator(); it.hasNext();) { for (Iterator it = rhsSet.iterator(); it.hasNext();) {
InstanceKey ik = (InstanceKey) it.next(); InstanceKey ik = (InstanceKey) it.next();
if (getCallGraph().getClassHierarchy().implementsInterface(ik.getConcreteType(), klass.getReference())) { if (getCallGraph().getClassHierarchy().implementsInterface(ik.getConcreteType(), klass)) {
S.add(getInstanceKeyMapping().getMappedIndex(ik)); S.add(getInstanceKeyMapping().getMappedIndex(ik));
} }
} }

View File

@ -1601,7 +1601,7 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
} }
PointerKey p = getPointerKeyForArrayContents(I); PointerKey p = getPointerKeyForArrayContents(I);
if (contents.isInterface()) { if (contents.isInterface()) {
if (getClassHierarchy().implementsInterface(instance.getConcreteType(), contents.getReference())) { if (getClassHierarchy().implementsInterface(instance.getConcreteType(), contents)) {
sideEffect.b |= system.newConstraint(p, instance); sideEffect.b |= system.newConstraint(p, instance);
} }
} else { } else {

View File

@ -487,7 +487,7 @@ public class PropagationSystem extends DefaultFixedPointSolver<PointsToSetVariab
private void registerArrayInstanceWithAllInterfacesOfElement(int index, IClass elementClass, int dim) { private void registerArrayInstanceWithAllInterfacesOfElement(int index, IClass elementClass, int dim) {
Collection ifaces = null; Collection ifaces = null;
try { try {
ifaces = (elementClass.isInterface()) ? elementClass.getAllAncestorInterfaces() : elementClass.getAllImplementedInterfaces(); ifaces = elementClass.getAllImplementedInterfaces();
} catch (ClassHierarchyException e) { } catch (ClassHierarchyException e) {
Warnings.add(ClassHierarchyWarning.create(e.getMessage())); Warnings.add(ClassHierarchyWarning.create(e.getMessage()));
return; return;

View File

@ -833,7 +833,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
if (cls.isInterface()) { if (cls.isInterface()) {
for (int i = 0; i < ik.length; i++) { for (int i = 0; i < ik.length; i++) {
system.findOrCreateIndexForInstanceKey(ik[i]); system.findOrCreateIndexForInstanceKey(ik[i]);
if (getClassHierarchy().implementsInterface(ik[i].getConcreteType(), cls.getReference())) { if (getClassHierarchy().implementsInterface(ik[i].getConcreteType(), cls)) {
system.newConstraint(result, ik[i]); system.newConstraint(result, ik[i]);
} }
} }

View File

@ -249,7 +249,7 @@ public class ClassHierarchy implements IClassHierarchy {
Collection loadedSuperInterfaces; Collection loadedSuperInterfaces;
try { try {
loadedSuperclasses = computeSuperclasses(klass); loadedSuperclasses = computeSuperclasses(klass);
loadedSuperInterfaces = klass.isInterface() ? null : klass.getAllImplementedInterfaces(); loadedSuperInterfaces = klass.getAllImplementedInterfaces();
} catch (ClassHierarchyException e) { } catch (ClassHierarchyException e) {
// a little cleanup // a little cleanup
if (klass instanceof ShrikeClass) { if (klass instanceof ShrikeClass) {
@ -399,10 +399,9 @@ public class ClassHierarchy implements IClassHierarchy {
} }
for (Iterator it = impls.iterator(); it.hasNext();) { for (Iterator it = impls.iterator(); it.hasNext();) {
IClass klass = (IClass) it.next(); IClass klass = (IClass) it.next();
if (Assertions.verifyAssertions) { if (!klass.isInterface()) {
Assertions._assert(!klass.isInterface()); result.addAll(computeTargetsNotInterface(ref, klass));
} }
result.addAll(computeTargetsNotInterface(ref, klass));
} }
return result; return result;
} else { } else {
@ -932,24 +931,17 @@ public class ClassHierarchy implements IClassHierarchy {
} }
/** /**
* Does c implement T? * Does c implement i?
* *
* @param c * @return true iff i is an interface and c is a class that implements i, r
* @param T * c is an interface that extends i.
* @return true iff T is an interface and c is a class that implements T,
* *
*/ */
public boolean implementsInterface(IClass c, TypeReference T) { public boolean implementsInterface(IClass c, IClass i) {
IClass tClass = lookupClass(T); if (!i.isInterface()) {
if (Assertions.verifyAssertions) {
if (tClass == null) {
Assertions._assert(false, "null klass for " + T);
}
}
if (!tClass.isInterface()) {
return false; return false;
} }
Set impls = implementors.get(tClass); Set impls = implementors.get(i);
if (impls != null && impls.contains(c)) { if (impls != null && impls.contains(c)) {
return true; return true;
} }
@ -1204,11 +1196,7 @@ public class ClassHierarchy implements IClassHierarchy {
throw new IllegalArgumentException("c1 is null"); throw new IllegalArgumentException("c1 is null");
} }
if (c1.isInterface()) { if (c1.isInterface()) {
if (c2.isInterface()) { return implementsInterface(c2, c1);
return isSubclassOf(c2, c1);
} else {
return implementsInterface(c2, c1.getReference());
}
} else { } else {
if (c2.isInterface()) { if (c2.isInterface()) {
return c1.equals(getRootClass()); return c1.equals(getRootClass());

View File

@ -126,11 +126,11 @@ public interface IClassHierarchy extends Iterable<IClass> {
public boolean isSubclassOf(IClass c, IClass T); public boolean isSubclassOf(IClass c, IClass T);
/** /**
* Does c implement T? * Does c implement i?
* *
* @return true iff T is an interface and c is a class that implements T, * @return true iff i is an interface and c is a class that implements i,
*/ */
public boolean implementsInterface(IClass c, TypeReference T); public boolean implementsInterface(IClass c, IClass i);
/** /**
* Return set of all subclasses of type in the Class Hierarchy * Return set of all subclasses of type in the Class Hierarchy

View File

@ -90,7 +90,7 @@ public class BypassSyntheticClass extends SyntheticClass {
* @see com.ibm.wala.classLoader.IClass#getAllInterfaces() * @see com.ibm.wala.classLoader.IClass#getAllInterfaces()
*/ */
public Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException { public Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException {
Collection<IClass> realIfaces = realType.isInterface() ? realType.getAllAncestorInterfaces() : realType.getAllImplementedInterfaces(); Collection<IClass> realIfaces = realType.getAllImplementedInterfaces();
if (realType.isInterface()) { if (realType.isInterface()) {
HashSet<IClass> result = HashSetFactory.make(realIfaces); HashSet<IClass> result = HashSetFactory.make(realIfaces);
result.add(realType); result.add(realType);
@ -100,17 +100,17 @@ public class BypassSyntheticClass extends SyntheticClass {
} }
} }
/* // /*
* @see com.ibm.wala.classLoader.IClass#getAllInterfaces() // * @see com.ibm.wala.classLoader.IClass#getAllInterfaces()
*/ // */
public Collection<IClass> getAllAncestorInterfaces() throws ClassHierarchyException { // public Collection<IClass> getAllAncestorInterfaces() throws ClassHierarchyException {
if (Assertions.verifyAssertions) { // if (Assertions.verifyAssertions) {
Assertions._assert(realType.isInterface()); // Assertions._assert(realType.isInterface());
} // }
HashSet<IClass> result = HashSetFactory.make(realType.getAllAncestorInterfaces().size() + 1); // HashSet<IClass> result = HashSetFactory.make(realType.getAllAncestorInterfaces().size() + 1);
result.addAll(realType.getAllAncestorInterfaces()); // result.addAll(realType.getAllImplementedInterfaces()());
return result; // return result;
} // }
/* /*
* @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector) * @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector)