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:
parent
fe69687001
commit
6723d33683
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue