more work for reuse
make synthetic code better support non-Java languages
This commit is contained in:
parent
81a6e67b4b
commit
6c1d0d9cb6
|
@ -94,7 +94,6 @@ public class CAstAnalysisScope extends AnalysisScope {
|
|||
*/
|
||||
@Override
|
||||
public ClassLoaderReference getSyntheticLoader() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ abstract public class AstClass implements IClass, ClassConstants {
|
|||
return getField(name);
|
||||
}
|
||||
@Override
|
||||
public Collection<IMethod> getDeclaredMethods() {
|
||||
public Collection<? extends IMethod> getDeclaredMethods() {
|
||||
return declaredMethods.values();
|
||||
}
|
||||
|
||||
|
@ -235,7 +235,7 @@ abstract public class AstClass implements IClass, ClassConstants {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<IMethod> getAllMethods() {
|
||||
public Collection<? extends IMethod> getAllMethods() {
|
||||
Collection<IMethod> result = HashSetFactory.make();
|
||||
for (IMethod iMethod : getDeclaredMethods()) {
|
||||
result.add(iMethod);
|
||||
|
|
|
@ -88,4 +88,45 @@ public class AstDynamicField implements IField {
|
|||
public Collection<Annotation> getAnnotations() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cls == null) ? 0 : cls.hashCode());
|
||||
result = prime * result + ((descriptor == null) ? 0 : descriptor.hashCode());
|
||||
result = prime * result + (isStatic ? 1231 : 1237);
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AstDynamicField other = (AstDynamicField) obj;
|
||||
if (cls == null) {
|
||||
if (other.cls != null)
|
||||
return false;
|
||||
} else if (!cls.equals(other.cls))
|
||||
return false;
|
||||
if (descriptor == null) {
|
||||
if (other.descriptor != null)
|
||||
return false;
|
||||
} else if (!descriptor.equals(other.descriptor))
|
||||
return false;
|
||||
if (isStatic != other.isStatic)
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.ibm.wala.classLoader.ClassLoaderFactory;
|
|||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ipa.summaries.BypassSyntheticClassLoader;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
|
@ -28,8 +29,13 @@ public abstract class SingleClassLoaderFactory implements ClassLoaderFactory {
|
|||
*/
|
||||
private IClassLoader THE_LOADER = null;
|
||||
|
||||
/**
|
||||
* Support synthetic classes
|
||||
*/
|
||||
private IClassLoader syntheticLoader;
|
||||
|
||||
@Override
|
||||
public IClassLoader getLoader(ClassLoaderReference classLoaderReference, IClassHierarchy cha, AnalysisScope scope) {
|
||||
public IClassLoader getLoader(ClassLoaderReference classLoaderReference, IClassHierarchy cha, AnalysisScope scope) {
|
||||
if (THE_LOADER == null) {
|
||||
THE_LOADER = makeTheLoader(cha);
|
||||
try {
|
||||
|
@ -39,9 +45,14 @@ public abstract class SingleClassLoaderFactory implements ClassLoaderFactory {
|
|||
}
|
||||
}
|
||||
|
||||
assert classLoaderReference.equals(getTheReference());
|
||||
|
||||
return THE_LOADER;
|
||||
if (classLoaderReference.equals(scope.getSyntheticLoader())) {
|
||||
syntheticLoader = new BypassSyntheticClassLoader(scope.getSyntheticLoader(), THE_LOADER, scope.getExclusions(), cha);
|
||||
return syntheticLoader;
|
||||
|
||||
} else {
|
||||
assert classLoaderReference.equals(getTheReference());
|
||||
return THE_LOADER;
|
||||
}
|
||||
}
|
||||
|
||||
public IClassLoader getTheLoader() {
|
||||
|
|
|
@ -86,7 +86,7 @@ public class DefaultMethodsTest extends WalaTestCase {
|
|||
TypeReference test1Type = TypeReference.findOrCreate(ClassLoaderReference.Application, "LdefaultMethods/DefaultMethods$Test1");
|
||||
IClass test1Class = cha.lookupClass(test1Type);
|
||||
|
||||
Collection<IMethod> allMethods = test1Class.getAllMethods();
|
||||
Collection<? extends IMethod> allMethods = test1Class.getAllMethods();
|
||||
IMethod defaultMethod = test1Class.getMethod(t1m.getSelector());
|
||||
Assert.assertTrue("Expecting default methods to show up in IClass.allMethods()", allMethods.contains(defaultMethod));
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ public class GetMethodContextInterpreter implements SSAContextInterpreter {
|
|||
*/
|
||||
private static Collection<IMethod> getAllNormalPublicMethods(IClass cls,Atom name) {
|
||||
Collection<IMethod> result = HashSetFactory.make();
|
||||
Collection<IMethod> allMethods = null;
|
||||
Collection<? extends IMethod> allMethods = null;
|
||||
allMethods = cls.getAllMethods();
|
||||
for (IMethod m : allMethods) {
|
||||
if (!m.isInit() && !m.isClinit() && m.isPublic() && m.getSelector().getName().equals(name)) {
|
||||
|
|
|
@ -239,7 +239,7 @@ public class JavaLangClassContextInterpreter implements SSAContextInterpreter {
|
|||
*/
|
||||
private static Collection<IMethod> getAllNormalPublicMethods(IClass cls) {
|
||||
Collection<IMethod> result = HashSetFactory.make();
|
||||
Collection<IMethod> allMethods = null;
|
||||
Collection<? extends IMethod> allMethods = null;
|
||||
allMethods = cls.getAllMethods();
|
||||
for (IMethod m : allMethods) {
|
||||
if (!m.isInit() && !m.isClinit() && m.isPublic()) {
|
||||
|
|
|
@ -343,7 +343,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
* @see com.ibm.wala.classLoader.IClass#getAllMethods()
|
||||
*/
|
||||
@Override
|
||||
public Collection<IMethod> getAllMethods() {
|
||||
public Collection<? extends IMethod> getAllMethods() {
|
||||
return loader.lookupClass(getClassLoader().getLanguage().getRootType().getName()).getAllMethods();
|
||||
}
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
}
|
||||
IClass s = getSuperclass();
|
||||
while (s != null) {
|
||||
Iterator<IMethod> superDeclaredMethods = s.getDeclaredMethods().iterator();
|
||||
Iterator<? extends IMethod> superDeclaredMethods = s.getDeclaredMethods().iterator();
|
||||
while (superDeclaredMethods.hasNext()) {
|
||||
result.add(superDeclaredMethods.next());
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ public interface IClass extends IClassHierarchyDweller {
|
|||
/**
|
||||
* @return an Iterator of the IMethods declared by this class.
|
||||
*/
|
||||
Collection<IMethod> getDeclaredMethods();
|
||||
Collection<? extends IMethod> getDeclaredMethods();
|
||||
|
||||
/**
|
||||
* Compute the instance fields declared by this class or any of its superclasses.
|
||||
|
@ -155,7 +155,7 @@ public interface IClass extends IClassHierarchyDweller {
|
|||
/**
|
||||
* Compute the methods declared by this class or any of its superclasses.
|
||||
*/
|
||||
Collection<IMethod> getAllMethods();
|
||||
Collection<? extends IMethod> getAllMethods();
|
||||
|
||||
/**
|
||||
* Compute the instance fields declared by this class.
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.types.annotations.Annotation;
|
||||
|
@ -77,7 +76,7 @@ public abstract class SyntheticClass implements IClass {
|
|||
*/
|
||||
@Override
|
||||
public IClassLoader getClassLoader() {
|
||||
return cha.getLoader(ClassLoaderReference.Primordial);
|
||||
return cha.getLoader(T.getClassLoader());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -112,7 +112,14 @@ public class BypassMethodTargetSelector implements MethodTargetSelector {
|
|||
IMethod target = (chaTarget == null) ? findOrCreateSyntheticMethod(ref, site.isStatic()) : findOrCreateSyntheticMethod(chaTarget,
|
||||
site.isStatic());
|
||||
|
||||
|
||||
// try synthetic method that matches receiver type
|
||||
if (dispatchType != null) {
|
||||
ref = MethodReference.findOrCreate(dispatchType.getReference(), ref.getSelector());
|
||||
chaTarget = chaMethodTargetSelector.getCalleeTarget(caller, site, dispatchType);
|
||||
target = (chaTarget == null) ? findOrCreateSyntheticMethod(ref, site.isStatic()) : findOrCreateSyntheticMethod(chaTarget,
|
||||
site.isStatic());
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println("target is initially " + target);
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ public class BypassSyntheticClass extends SyntheticClass {
|
|||
* @see com.ibm.wala.classLoader.IClass#getDeclaredMethods()
|
||||
*/
|
||||
@Override
|
||||
public Collection<IMethod> getDeclaredMethods() {
|
||||
public Collection<? extends IMethod> getDeclaredMethods() {
|
||||
return realType.getDeclaredMethods();
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ public class BypassSyntheticClass extends SyntheticClass {
|
|||
* @see com.ibm.wala.classLoader.IClass#getAllMethods()
|
||||
*/
|
||||
@Override
|
||||
public Collection<IMethod> getAllMethods() {
|
||||
public Collection<? extends IMethod> getAllMethods() {
|
||||
return realType.getAllMethods();
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ import com.ibm.wala.util.strings.Atom;
|
|||
*
|
||||
* Code that wants to introduce synthetic classes uses the registerClass method,
|
||||
* giving it an Atom which is the class name, and an IClass which is the class
|
||||
* to load. Since the synthetic loader musat be a child of the others, it would
|
||||
* to load. Since the synthetic loader must be a child of the others, it would
|
||||
* be very bad to use an existing name for a new synthetic class.
|
||||
*
|
||||
* Class lookup works just as for any other classloader.
|
||||
|
@ -148,7 +148,7 @@ public class BypassSyntheticClassLoader implements IClassLoader {
|
|||
*/
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return Language.JAVA;
|
||||
return parent.getLanguage();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -54,8 +54,8 @@ public class JUnitEntryPoints {
|
|||
System.out.println("application class: " + klass);
|
||||
|
||||
// return all the tests methods
|
||||
Collection<IMethod> methods = klass.getAllMethods();
|
||||
Iterator<IMethod> methodsIt = methods.iterator();
|
||||
Collection<? extends IMethod> methods = klass.getAllMethods();
|
||||
Iterator<? extends IMethod> methodsIt = methods.iterator();
|
||||
|
||||
while (methodsIt.hasNext()) {
|
||||
IMethod m = methodsIt.next();
|
||||
|
|
|
@ -248,7 +248,7 @@ nextMethod:
|
|||
// Don't consider internal overrides
|
||||
continue;
|
||||
}
|
||||
final Collection<IMethod> methods = candid.getDeclaredMethods();
|
||||
final Collection<? extends IMethod> methods = candid.getDeclaredMethods();
|
||||
for (final IMethod method : methods) {
|
||||
|
||||
|
||||
|
@ -329,7 +329,7 @@ nextMethod:
|
|||
{ // Overridden methods
|
||||
if (isAPIComponent(appClass)) continue;
|
||||
if (isExcluded(appClass)) continue;
|
||||
final Collection<IMethod> methods = appClass.getDeclaredMethods();
|
||||
final Collection<? extends IMethod> methods = appClass.getDeclaredMethods();
|
||||
for (final IMethod method : methods) {
|
||||
if ((method.isInit() || method.isClinit()) && (! this.flags.contains(LocatorFlags.WITH_CTOR))) {
|
||||
logger.debug("Skipping constructor of {}", method);
|
||||
|
@ -359,7 +359,7 @@ nextMethod:
|
|||
}
|
||||
if (isExcluded(iFace)) continue;
|
||||
logger.debug("Searching Interface {}", iFace);
|
||||
final Collection<IMethod> ifMethods = iFace.getDeclaredMethods();
|
||||
final Collection<? extends IMethod> ifMethods = iFace.getDeclaredMethods();
|
||||
for (final IMethod ifMethod : ifMethods) {
|
||||
final IMethod method = appClass.getMethod(ifMethod.getSelector());
|
||||
if (method != null && method.getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application)) {
|
||||
|
|
|
@ -85,7 +85,7 @@ public class MethodNamePattern {
|
|||
Collection<IMethod> matching = new LinkedList<>();
|
||||
Atom atom = Atom.findOrCreateUnicodeAtom(memberName);
|
||||
Descriptor desc = descriptor == null ? null : Descriptor.findOrCreateUTF8(descriptor);
|
||||
Collection<IMethod> allMethods = c.getAllMethods();
|
||||
Collection<? extends IMethod> allMethods = c.getAllMethods();
|
||||
for(IMethod m: allMethods) {
|
||||
if(m.getName().equals(atom) && (desc == null || m.getDescriptor().equals(desc))) {
|
||||
matching.add(m);
|
||||
|
|
Loading…
Reference in New Issue