Nuke ClassHierarchyException from IClass.getSuperclass()
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3539 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
50e093779a
commit
829145e97b
|
@ -519,7 +519,7 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
public IClass getSuperclass() {
|
||||
return superClass;
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
|||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
public IClass getSuperclass() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.ibm.wala.core.tests.util.WalaTestCase;
|
|||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ssa.IRFactory;
|
||||
import com.ibm.wala.ssa.SSAOptions;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
@ -120,8 +119,7 @@ public abstract class TestCAstTranslator extends WalaTestCase {
|
|||
public ClassHierarchy runTranslator(SourceFileModule[] fileNames) throws Exception {
|
||||
SingleClassLoaderFactory loaders = getClassLoaderFactory();
|
||||
|
||||
AnalysisScope scope =
|
||||
Util.makeScope(fileNames, loaders, getLanguage());
|
||||
AnalysisScope scope = Util.makeScope(fileNames, loaders, getLanguage());
|
||||
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope, loaders, getLanguage());
|
||||
|
||||
|
@ -144,8 +142,7 @@ public abstract class TestCAstTranslator extends WalaTestCase {
|
|||
IMethod mth = (IMethod) mths.next();
|
||||
if (mth.isStatic())
|
||||
System.err.print("static ");
|
||||
System.err.println(("method " + mth + " with " +
|
||||
mth.getNumberOfParameters() + " parameters"));
|
||||
System.err.println(("method " + mth + " with " + mth.getNumberOfParameters() + " parameters"));
|
||||
for (int i = 0; i < mth.getNumberOfParameters(); i++) {
|
||||
System.err.println(("param " + i + ": " + mth.getParameterType(i)));
|
||||
}
|
||||
|
@ -168,15 +165,11 @@ public abstract class TestCAstTranslator extends WalaTestCase {
|
|||
clsCount++;
|
||||
Assert.assertTrue("found class " + cls.getName().toString(), classes.contains(cls.getName().toString()));
|
||||
|
||||
try {
|
||||
if (cls.getSuperclass() == null) {
|
||||
Assert.assertTrue(cls.getName() + " has no superclass", supers.get(cls.getName()) == null);
|
||||
} else {
|
||||
Assert.assertTrue("super of " + cls.getName() + " is " + cls.getSuperclass().getName(), supers.get(
|
||||
cls.getName().toString()).equals(cls.getSuperclass().getName().toString()));
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assert.assertTrue(false);
|
||||
if (cls.getSuperclass() == null) {
|
||||
Assert.assertTrue(cls.getName() + " has no superclass", supers.get(cls.getName()) == null);
|
||||
} else {
|
||||
Assert.assertTrue("super of " + cls.getName() + " is " + cls.getSuperclass().getName(), supers
|
||||
.get(cls.getName().toString()).equals(cls.getSuperclass().getName().toString()));
|
||||
}
|
||||
|
||||
for (Iterator<?> flds = cls.getDeclaredInstanceFields().iterator(); flds.hasNext();) {
|
||||
|
|
|
@ -29,7 +29,6 @@ import com.ibm.wala.types.Selector;
|
|||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
abstract public class AstClass implements IClass, ClassConstants {
|
||||
|
@ -66,7 +65,7 @@ abstract public class AstClass implements IClass, ClassConstants {
|
|||
public boolean isPublic() {
|
||||
return (modifiers & ACC_PUBLIC) != 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean isReferenceType() {
|
||||
return true;
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ abstract public class AstClass implements IClass, ClassConstants {
|
|||
public String getSourceFileName() {
|
||||
return sourcePosition.getURL().getFile();
|
||||
}
|
||||
|
||||
|
||||
public InputStream getSource() {
|
||||
return null;
|
||||
}
|
||||
|
@ -107,13 +106,14 @@ abstract public class AstClass implements IClass, ClassConstants {
|
|||
return loader;
|
||||
}
|
||||
|
||||
public abstract IClass getSuperclass() throws ClassHierarchyException;
|
||||
public abstract IClass getSuperclass();
|
||||
|
||||
private Collection<IClass> gatherInterfaces() throws ClassHierarchyException {
|
||||
Set<IClass> result = HashSetFactory.make();
|
||||
result.addAll(getDirectInterfaces());
|
||||
if (getSuperclass() != null)
|
||||
if (getSuperclass() != null) {
|
||||
result.addAll(getSuperclass().getAllImplementedInterfaces());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -128,31 +128,21 @@ abstract public class AstClass implements IClass, ClassConstants {
|
|||
}
|
||||
|
||||
public IMethod getMethod(Selector selector) {
|
||||
try {
|
||||
if (declaredMethods.containsKey(selector)) {
|
||||
return declaredMethods.get(selector);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getMethod(selector);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
if (declaredMethods.containsKey(selector)) {
|
||||
return declaredMethods.get(selector);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getMethod(selector);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IField getField(Atom name) {
|
||||
try {
|
||||
if (declaredFields.containsKey(name)) {
|
||||
return declaredFields.get(name);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getField(name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
if (declaredFields.containsKey(name)) {
|
||||
return declaredFields.get(name);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getField(name);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,11 @@ import com.ibm.wala.classLoader.IClass;
|
|||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.Selector;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public abstract class AstDynamicPropertyClass extends AstClass {
|
||||
|
@ -37,69 +35,65 @@ public abstract class AstDynamicPropertyClass extends AstClass {
|
|||
}
|
||||
|
||||
public IField getField(final Atom name) {
|
||||
try {
|
||||
if (declaredFields.containsKey(name)) {
|
||||
return declaredFields.get(name);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getField(name);
|
||||
} else {
|
||||
final boolean isStatic = isStaticField(name);
|
||||
declaredFields.put(name, new IField() {
|
||||
public String toString() {
|
||||
return "<field " + name + ">";
|
||||
}
|
||||
if (declaredFields.containsKey(name)) {
|
||||
return declaredFields.get(name);
|
||||
} else if (getSuperclass() != null) {
|
||||
return getSuperclass().getField(name);
|
||||
} else {
|
||||
final boolean isStatic = isStaticField(name);
|
||||
declaredFields.put(name, new IField() {
|
||||
public String toString() {
|
||||
return "<field " + name + ">";
|
||||
}
|
||||
|
||||
public IClass getDeclaringClass() {
|
||||
return AstDynamicPropertyClass.this;
|
||||
}
|
||||
public IClass getDeclaringClass() {
|
||||
return AstDynamicPropertyClass.this;
|
||||
}
|
||||
|
||||
public Atom getName() {
|
||||
return name;
|
||||
}
|
||||
public Atom getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public TypeReference getFieldTypeReference() {
|
||||
return defaultDescriptor;
|
||||
}
|
||||
public TypeReference getFieldTypeReference() {
|
||||
return defaultDescriptor;
|
||||
}
|
||||
|
||||
public FieldReference getReference() {
|
||||
return FieldReference.findOrCreate(AstDynamicPropertyClass.this.getReference(), name, defaultDescriptor);
|
||||
}
|
||||
public FieldReference getReference() {
|
||||
return FieldReference.findOrCreate(AstDynamicPropertyClass.this.getReference(), name, defaultDescriptor);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return false;
|
||||
}
|
||||
public boolean isFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return false;
|
||||
}
|
||||
public boolean isPrivate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return false;
|
||||
}
|
||||
public boolean isPublic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return false;
|
||||
}
|
||||
public boolean isVolatile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public IClassHierarchy getClassHierarchy() {
|
||||
return AstDynamicPropertyClass.this.getClassHierarchy();
|
||||
}
|
||||
});
|
||||
public IClassHierarchy getClassHierarchy() {
|
||||
return AstDynamicPropertyClass.this.getClassHierarchy();
|
||||
}
|
||||
});
|
||||
|
||||
return declaredFields.get(name);
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
return declaredFields.get(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected boolean isStaticField(Atom name) {
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.ibm.wala.classLoader.IClass;
|
|||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.shrikeCT.ClassConstants;
|
||||
import com.ibm.wala.types.Selector;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
|
@ -86,7 +85,7 @@ abstract public class AstFunctionClass implements IClass, ClassConstants {
|
|||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
public IClass getSuperclass() {
|
||||
return loader.lookupClass(superReference.getName());
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import com.ibm.wala.ipa.callgraph.CGNode;
|
|||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextUtil;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.summaries.SyntheticIR;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
|
@ -87,8 +86,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
arraycopyDesc);
|
||||
|
||||
/**
|
||||
* If the type is an array, the program counter of the synthesized call to
|
||||
* arraycopy. Doesn't really matter what it is.
|
||||
* If the type is an array, the program counter of the synthesized call to arraycopy. Doesn't really matter what it is.
|
||||
*/
|
||||
private final static int ARRAYCOPY_PC = 3;
|
||||
|
||||
|
@ -103,7 +101,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
final private Map<TypeReference, IR> IRCache = HashMapFactory.make();
|
||||
|
||||
private final SSAInstructionFactory insts = Language.JAVA.instructionFactory();
|
||||
|
||||
|
||||
public IR getIR(CGNode node) {
|
||||
if (node == null) {
|
||||
throw new IllegalArgumentException("node is null");
|
||||
|
@ -153,8 +151,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return an array of statements that encode the behavior of the clone method
|
||||
* for a given type.
|
||||
* @return an array of statements that encode the behavior of the clone method for a given type.
|
||||
*/
|
||||
private SSAInstruction[] makeStatements(IClass klass) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
|
@ -173,7 +170,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
int length = nextLocal++;
|
||||
statements.add(insts.ArrayLengthInstruction(length, 1));
|
||||
int[] sizes = new int[klass.getReference().getDimensionality()];
|
||||
Arrays.fill(sizes,length);
|
||||
Arrays.fill(sizes, length);
|
||||
N = insts.NewInstruction(retValue, ref, sizes);
|
||||
} else {
|
||||
N = insts.NewInstruction(retValue, ref);
|
||||
|
@ -202,11 +199,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
SSAPutInstruction P = insts.PutInstruction(retValue, tempValue, f.getReference());
|
||||
statements.add(P);
|
||||
}
|
||||
try {
|
||||
k = k.getSuperclass();
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
k = k.getSuperclass();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -223,8 +216,7 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return an IR that encodes the behavior of the clone method for a given
|
||||
* type.
|
||||
* @return an IR that encodes the behavior of the clone method for a given type.
|
||||
*/
|
||||
private IR makeIR(IMethod method, Context context, IClass klass) {
|
||||
if (Assertions.verifyAssertions) {
|
||||
|
@ -236,13 +228,12 @@ public class CloneInterpreter implements SSAContextInterpreter {
|
|||
|
||||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#recordFactoryType(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.classLoader.IClass)
|
||||
* com.ibm.wala.classLoader.IClass)
|
||||
*/
|
||||
public boolean recordFactoryType(CGNode node, IClass klass) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public Iterator<FieldReference> iterateFieldsRead(CGNode node) {
|
||||
SSAInstruction[] statements = getIR(node).getInstructions();
|
||||
return CodeScanner.getFieldsRead(statements).iterator();
|
||||
|
|
|
@ -28,9 +28,8 @@ import com.ibm.wala.util.debug.UnimplementedError;
|
|||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
/**
|
||||
* Implementation of {@link IClass} for array classes. Such classes would be
|
||||
* best called 'broken covariant array types', since that is the semantics that
|
||||
* they implement.
|
||||
* Implementation of {@link IClass} for array classes. Such classes would be best called 'broken covariant array types', since that
|
||||
* is the semantics that they implement.
|
||||
*/
|
||||
public class ArrayClass implements IClass, Constants {
|
||||
|
||||
|
@ -107,30 +106,24 @@ public class ArrayClass implements IClass, Constants {
|
|||
* @see com.ibm.wala.classLoader.IClass#getSuperclass()
|
||||
*/
|
||||
public IClass getSuperclass() {
|
||||
try {
|
||||
IClass elt = getElementClass();
|
||||
IClass elt = getElementClass();
|
||||
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(getReference().getArrayElementType().isPrimitiveType() || elt != null);
|
||||
}
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(getReference().getArrayElementType().isPrimitiveType() || elt != null);
|
||||
}
|
||||
|
||||
// super is Ljava/lang/Object in two cases:
|
||||
// 1) [Ljava/lang/Object
|
||||
// 2) [? for primitive arrays (null from getElementClass)
|
||||
if (elt == null || elt.getReference() == getClassLoader().getLanguage().getRootType()) {
|
||||
return loader.lookupClass(getClassLoader().getLanguage().getRootType().getName());
|
||||
}
|
||||
// super is Ljava/lang/Object in two cases:
|
||||
// 1) [Ljava/lang/Object
|
||||
// 2) [? for primitive arrays (null from getElementClass)
|
||||
if (elt == null || elt.getReference() == getClassLoader().getLanguage().getRootType()) {
|
||||
return loader.lookupClass(getClassLoader().getLanguage().getRootType().getName());
|
||||
}
|
||||
|
||||
// else it is array of super of element type (yuck)
|
||||
else {
|
||||
TypeReference eltSuperRef = elt.getSuperclass().getReference();
|
||||
TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef);
|
||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName());
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
// else it is array of super of element type (yuck)
|
||||
else {
|
||||
TypeReference eltSuperRef = elt.getSuperclass().getReference();
|
||||
TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef);
|
||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +218,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
*/
|
||||
public Collection<IClass> getAllImplementedInterfaces() {
|
||||
HashSet<IClass> result = HashSetFactory.make(2);
|
||||
for(TypeReference ref : getClassLoader().getLanguage().getArrayInterfaces()) {
|
||||
for (TypeReference ref : getClassLoader().getLanguage().getArrayInterfaces()) {
|
||||
IClass klass = loader.lookupClass(ref.getName());
|
||||
if (klass != null) {
|
||||
result.add(klass);
|
||||
|
|
|
@ -44,8 +44,8 @@ import com.ibm.wala.util.warnings.Warnings;
|
|||
|
||||
/**
|
||||
* A class representing which originates in some form of bytecode.
|
||||
*
|
||||
* @param <T> type of classloader which loads this format of class.
|
||||
*
|
||||
* @param <T> type of classloader which loads this format of class.
|
||||
*/
|
||||
public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
||||
|
||||
|
@ -151,7 +151,6 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
|
||||
protected abstract IMethod[] computeDeclaredMethods() throws InvalidClassFileException;
|
||||
|
||||
|
||||
public TypeReference getReference() {
|
||||
return typeReference;
|
||||
}
|
||||
|
@ -159,7 +158,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
public String getSourceFileName() {
|
||||
return loader.getSourceFileName(this);
|
||||
}
|
||||
|
||||
|
||||
public InputStream getSource() {
|
||||
return loader.getSource(this);
|
||||
}
|
||||
|
@ -235,12 +234,12 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
superClass = loader.lookupClass(TypeName.findOrCreate(superName));
|
||||
}
|
||||
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
public IClass getSuperclass() {
|
||||
if (!superclassComputed) {
|
||||
computeSuperclass();
|
||||
}
|
||||
if (superClass == null && !getReference().equals(TypeReference.JavaLangObject)) {
|
||||
throw new ClassHierarchyException("No superclass found for " + this+" Superclass name "+superName);
|
||||
throw new IllegalStateException("No superclass found for " + this + " Superclass name " + superName);
|
||||
}
|
||||
return superClass;
|
||||
}
|
||||
|
@ -381,22 +380,18 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
}
|
||||
|
||||
// check parent, caching if found
|
||||
try {
|
||||
if (!selector.equals(MethodReference.clinitSelector) && !selector.equals(MethodReference.initSelector)) {
|
||||
IClass superclass = getSuperclass();
|
||||
if (superclass != null) {
|
||||
IMethod inherit = superclass.getMethod(selector);
|
||||
if (inherit != null) {
|
||||
if (inheritCache == null) {
|
||||
inheritCache = new BimodalMap<Selector, IMethod>(5);
|
||||
}
|
||||
inheritCache.put(selector, inherit);
|
||||
return inherit;
|
||||
if (!selector.equals(MethodReference.clinitSelector) && !selector.equals(MethodReference.initSelector)) {
|
||||
IClass superclass = getSuperclass();
|
||||
if (superclass != null) {
|
||||
IMethod inherit = superclass.getMethod(selector);
|
||||
if (inherit != null) {
|
||||
if (inheritCache == null) {
|
||||
inheritCache = new BimodalMap<Selector, IMethod>(5);
|
||||
}
|
||||
inheritCache.put(selector, inherit);
|
||||
return inherit;
|
||||
}
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
|
||||
// didn't find it yet. special logic for interfaces
|
||||
|
@ -441,7 +436,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
Warnings.add(ClassHierarchyWarning.create("expected an interface " + klass));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// at this point result holds all interfaces the class directly extends.
|
||||
// now expand to a fixed point.
|
||||
Set<IClass> last = null;
|
||||
|
@ -451,15 +446,10 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
|
|||
result.addAll(i.getDirectInterfaces());
|
||||
}
|
||||
} while (last.size() < result.size());
|
||||
|
||||
|
||||
// now add any interfaces implemented by the super class
|
||||
IClass sup = null;
|
||||
try {
|
||||
sup = getSuperclass();
|
||||
} catch (ClassHierarchyException e1) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
sup = getSuperclass();
|
||||
if (sup != null) {
|
||||
result.addAll(sup.getAllImplementedInterfaces());
|
||||
}
|
||||
|
|
|
@ -57,8 +57,9 @@ public interface IClass extends IClassHierarchyDweller {
|
|||
|
||||
/**
|
||||
* @return the superclass, or null if java.lang.Object
|
||||
* @throws IllegalStateException if there's some problem determining the superclass
|
||||
*/
|
||||
IClass getSuperclass() throws ClassHierarchyException;
|
||||
IClass getSuperclass();
|
||||
|
||||
/**
|
||||
* @return Collection of (IClass) interfaces this class directly implements. If this class is an interface, returns the interfaces
|
||||
|
|
|
@ -38,7 +38,6 @@ import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
|||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeWorldClinitMethod;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.ConditionalBranchInstruction;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
|
@ -82,8 +81,8 @@ import com.ibm.wala.util.warnings.Warning;
|
|||
import com.ibm.wala.util.warnings.Warnings;
|
||||
|
||||
/**
|
||||
* This abstract base class provides the general algorithm for a call graph builder that relies on propagation through
|
||||
* an iterative dataflow solver, and constraints generated by statements in SSA form.
|
||||
* This abstract base class provides the general algorithm for a call graph builder that relies on propagation through an iterative
|
||||
* dataflow solver, and constraints generated by statements in SSA form.
|
||||
*
|
||||
* TODO: This implementation currently keeps all points to sets live ... even those for local variables that do not span
|
||||
* interprocedural boundaries. This may be too space-inefficient .. we can consider recomputing local sets on demand.
|
||||
|
@ -116,8 +115,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
*/
|
||||
// private final static boolean OPTIMIZE_WITH_TYPE_INFERENCE = true;
|
||||
/**
|
||||
* An optimization: if we can locally determine the final solution for a points-to set, then don't actually create the
|
||||
* points-to set, but instead short circuit by propagating the final solution to all such uses.
|
||||
* An optimization: if we can locally determine the final solution for a points-to set, then don't actually create the points-to
|
||||
* set, but instead short circuit by propagating the final solution to all such uses.
|
||||
*
|
||||
* String constants are ALWAYS considered invariant, regardless of the value of this flag.
|
||||
*
|
||||
|
@ -128,9 +127,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
private final static boolean SHORT_CIRCUIT_INVARIANT_SETS = true;
|
||||
|
||||
/**
|
||||
* An optimization: if we can locally determine that a particular pointer p has exactly one use, then we don't
|
||||
* actually create the points-to-set for p, but instead short-circuit by propagating the final solution to the unique
|
||||
* use.
|
||||
* An optimization: if we can locally determine that a particular pointer p has exactly one use, then we don't actually create the
|
||||
* points-to-set for p, but instead short-circuit by propagating the final solution to the unique use.
|
||||
*
|
||||
* Doesn't play well with pre-transitive solver; turning off for now.
|
||||
*/
|
||||
|
@ -261,7 +259,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
/**
|
||||
* Add constraints for a particular basic block.
|
||||
*/
|
||||
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, BasicBlock b, ConstraintVisitor v) {
|
||||
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, BasicBlock b,
|
||||
ConstraintVisitor v) {
|
||||
v.setBasicBlock(b);
|
||||
|
||||
// visit each instruction in the basic block.
|
||||
|
@ -278,7 +277,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
addPhiConstraints(node, cfg, b, v);
|
||||
}
|
||||
|
||||
private void addPhiConstraints(CGNode node, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, BasicBlock b, ConstraintVisitor v) {
|
||||
private void addPhiConstraints(CGNode node, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, BasicBlock b,
|
||||
ConstraintVisitor v) {
|
||||
// visit each phi instruction in each successor block
|
||||
for (Iterator sbs = cfg.getSuccNodes(b); sbs.hasNext();) {
|
||||
BasicBlock sb = (BasicBlock) sbs.next();
|
||||
|
@ -333,8 +333,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
List<ProgramCounter> peis = getIncomingPEIs(ir, ir.getExitBlock());
|
||||
PointerKey exception = getPointerKeyForExceptionalReturnValue(node);
|
||||
|
||||
TypeReference throwableType =
|
||||
node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getThrowableType();
|
||||
TypeReference throwableType = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getThrowableType();
|
||||
IClass c = node.getClassHierarchy().lookupClass(throwableType);
|
||||
addExceptionDefConstraints(ir, du, node, peis, exception, Collections.singleton(c));
|
||||
}
|
||||
|
@ -391,7 +390,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
// Account for those exceptions for which we do not actually have a
|
||||
// points-to set for
|
||||
// the pei, but just instance keys
|
||||
Collection<TypeReference> types = pei.getExceptionTypes();
|
||||
Collection<TypeReference> types = pei.getExceptionTypes();
|
||||
if (types != null) {
|
||||
for (Iterator<TypeReference> it2 = types.iterator(); it2.hasNext();) {
|
||||
TypeReference type = it2.next();
|
||||
|
@ -502,8 +501,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
protected static class ConstraintVisitor extends SSAInstruction.Visitor {
|
||||
|
||||
/**
|
||||
* The governing call graph builder. This field is used instead of an inner class in order to allow more flexible
|
||||
* reuse of this visitor in subclasses
|
||||
* The governing call graph builder. This field is used instead of an inner class in order to allow more flexible reuse of this
|
||||
* visitor in subclasses
|
||||
*/
|
||||
protected final SSAPropagationCallGraphBuilder builder;
|
||||
|
||||
|
@ -826,7 +825,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
if (DEBUG) {
|
||||
System.err.println("visitReturn: " + instruction);
|
||||
}
|
||||
|
||||
|
||||
PointerKey returnValue = getPointerKeyForReturnValue();
|
||||
PointerKey result = getPointerKeyForLocal(instruction.getResult());
|
||||
if (contentsAreInvariant(symbolTable, du, instruction.getResult())) {
|
||||
|
@ -1298,8 +1297,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a constraint to the system indicating that the contents of local src flows to dst, with no special type
|
||||
* filter.
|
||||
* Add a constraint to the system indicating that the contents of local src flows to dst, with no special type filter.
|
||||
*/
|
||||
private void addPiAssignment(PointerKey dst, int src) {
|
||||
PointerKey srcKey = getPointerKeyForLocal(src);
|
||||
|
@ -1329,8 +1327,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
/**
|
||||
* Side effect: records invariant parameters as implicit points-to-sets.
|
||||
*
|
||||
* @return if non-null, then result[i] holds the set of instance keys which may be passed as the ith parameter.
|
||||
* (which must be invariant)
|
||||
* @return if non-null, then result[i] holds the set of instance keys which may be passed as the ith parameter. (which must be
|
||||
* invariant)
|
||||
*/
|
||||
protected InstanceKey[][] computeInvariantParameters(SSAAbstractInvokeInstruction call) {
|
||||
InstanceKey[][] constParams = null;
|
||||
|
@ -1357,8 +1355,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
public void visitLoadMetadata(SSALoadMetadataInstruction instruction) {
|
||||
PointerKey def = getPointerKeyForLocal(instruction.getDef());
|
||||
assert instruction.getType() == TypeReference.JavaLangClass;
|
||||
InstanceKey iKey = getInstanceKeyForClassObject((TypeReference)instruction.getToken());
|
||||
IClass klass = getClassHierarchy().lookupClass((TypeReference)instruction.getToken());
|
||||
InstanceKey iKey = getInstanceKeyForClassObject((TypeReference) instruction.getToken());
|
||||
IClass klass = getClassHierarchy().lookupClass((TypeReference) instruction.getToken());
|
||||
if (klass != null) {
|
||||
processClassInitializer(klass);
|
||||
}
|
||||
|
@ -1385,7 +1383,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
if (!getBuilder().getOptions().getHandleStaticInit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (getBuilder().clinitVisited.contains(klass)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1411,13 +1409,9 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
IClass sc = klass.getSuperclass();
|
||||
if (sc != null) {
|
||||
processClassInitializer(sc);
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
IClass sc = klass.getSuperclass();
|
||||
if (sc != null) {
|
||||
processClassInitializer(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1428,10 +1422,9 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
* Side effect: add edge to the call graph.
|
||||
*
|
||||
* @param instruction
|
||||
* @param constParams if non-null, then constParams[i] holds the set of instance keys that are passed as param i, or
|
||||
* null if param i is not invariant
|
||||
* @param uniqueCatchKey if non-null, then this is the unique PointerKey that catches all exceptions from this call
|
||||
* site.
|
||||
* @param constParams if non-null, then constParams[i] holds the set of instance keys that are passed as param i, or null if param
|
||||
* i is not invariant
|
||||
* @param uniqueCatchKey if non-null, then this is the unique PointerKey that catches all exceptions from this call site.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void processResolvedCall(CGNode caller, SSAAbstractInvokeInstruction instruction, CGNode target,
|
||||
|
@ -1572,8 +1565,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
*
|
||||
* This operator will create a new callee context and constraints if necessary.
|
||||
*
|
||||
* N.B: This implementation assumes that the calling context depends solely on the dataflow information computed for
|
||||
* the receiver. TODO: generalize this to have other forms of context selection, such as CPA-style algorithms.
|
||||
* N.B: This implementation assumes that the calling context depends solely on the dataflow information computed for the receiver.
|
||||
* TODO: generalize this to have other forms of context selection, such as CPA-style algorithms.
|
||||
*/
|
||||
final class DispatchOperator extends UnaryOperator<PointsToSetVariable> implements IPointerOperator {
|
||||
private final SSAAbstractInvokeInstruction call;
|
||||
|
@ -1587,8 +1580,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
/**
|
||||
* @param call
|
||||
* @param node
|
||||
* @param constParams if non-null, then constParams[i] holds the String constant that is passed as param i, or null
|
||||
* if param i is not a String constant
|
||||
* @param constParams if non-null, then constParams[i] holds the String constant that is passed as param i, or null if param i
|
||||
* is not a String constant
|
||||
*/
|
||||
DispatchOperator(SSAAbstractInvokeInstruction call, ExplicitCallGraph.ExplicitNode node, InstanceKey[][] constParams,
|
||||
PointerKey uniqueCatch) {
|
||||
|
@ -1605,7 +1598,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
|
||||
/*
|
||||
* @see com.ibm.wala.dataflow.fixpoint.UnaryOperator#evaluate(com.ibm.wala.dataflow.fixpoint.IVariable,
|
||||
* com.ibm.wala.dataflow.fixpoint.IVariable)
|
||||
* com.ibm.wala.dataflow.fixpoint.IVariable)
|
||||
*/
|
||||
@Override
|
||||
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
||||
|
@ -1738,7 +1731,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
throw new IllegalArgumentException("du is null");
|
||||
}
|
||||
if (vn <= 0) {
|
||||
throw new IllegalArgumentException("v is invalid: " + vn);
|
||||
throw new IllegalArgumentException("v is invalid: " + vn);
|
||||
}
|
||||
// todo: enhance this by solving a dead-code elimination
|
||||
// problem.
|
||||
|
@ -1880,8 +1873,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
}
|
||||
|
||||
/**
|
||||
* TODO: enhance this logic using type inference TODO!!!: enhance filtering to consider concrete types, not just
|
||||
* cones. precondition: needs Filter
|
||||
* TODO: enhance this logic using type inference TODO!!!: enhance filtering to consider concrete types, not just cones.
|
||||
* precondition: needs Filter
|
||||
*
|
||||
* @param target
|
||||
* @return an IClass which represents
|
||||
|
@ -1918,8 +1911,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
}
|
||||
|
||||
/**
|
||||
* A value is "invariant" if we can figure out the instances it can ever point to locally, without resorting to
|
||||
* propagation.
|
||||
* A value is "invariant" if we can figure out the instances it can ever point to locally, without resorting to propagation.
|
||||
*
|
||||
* @param valueNumber
|
||||
* @return true iff the contents of the local with this value number can be deduced locally, without propagation
|
||||
|
@ -2012,7 +2004,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A warning for when we fail to resolve the type for a checkcast
|
||||
* A warning for when we fail to resolve the type for a checkcast
|
||||
*/
|
||||
private static class CheckcastFailure extends Warning {
|
||||
|
||||
|
@ -2036,7 +2028,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A warning for when we fail to resolve the type for a field
|
||||
* A warning for when we fail to resolve the type for a field
|
||||
*/
|
||||
private static class FieldResolutionFailure extends Warning {
|
||||
|
||||
|
|
|
@ -29,18 +29,16 @@ import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
|||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SmushedAllocationSiteInstanceKeys;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
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.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* Flexible class to create {@link InstanceKey}s depending on various policies ranging from
|
||||
* class-based (i.e. 0-CFA) to allocation-site-based (0-1-CFA variants).
|
||||
* Flexible class to create {@link InstanceKey}s depending on various policies ranging from class-based (i.e. 0-CFA) to
|
||||
* allocation-site-based (0-1-CFA variants).
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
|
@ -55,7 +53,7 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
|
||||
public final static TypeReference JavaLangStringBuilder = TypeReference.findOrCreate(ClassLoaderReference.Primordial,
|
||||
JavaLangStringBuilderName);
|
||||
|
||||
|
||||
private final static TypeName JavaLangAbstractStringBuilderName = TypeName.string2TypeName("Ljava/lang/AbstractStringBuilder");
|
||||
|
||||
public final static TypeReference JavaLangAbstractStringBuilder = TypeReference.findOrCreate(ClassLoaderReference.Primordial,
|
||||
|
@ -67,35 +65,31 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
public static final int NONE = 0;
|
||||
|
||||
/**
|
||||
* An ALLOCATIONS - based policy distinguishes instances by allocation site.
|
||||
* Otherwise, the policy distinguishes instances by type.
|
||||
* An ALLOCATIONS - based policy distinguishes instances by allocation site. Otherwise, the policy distinguishes instances by
|
||||
* type.
|
||||
*/
|
||||
public static final int ALLOCATIONS = 1;
|
||||
|
||||
/**
|
||||
* A policy variant where String and StringBuffers are NOT disambiguated
|
||||
* according to allocation site.
|
||||
* A policy variant where String and StringBuffers are NOT disambiguated according to allocation site.
|
||||
*/
|
||||
public static final int SMUSH_STRINGS = 2;
|
||||
|
||||
/**
|
||||
* A policy variant where {@link Throwable} instances are NOT disambiguated according
|
||||
* to allocation site.
|
||||
* A policy variant where {@link Throwable} instances are NOT disambiguated according to allocation site.
|
||||
*
|
||||
*/
|
||||
public static final int SMUSH_THROWABLES = 4;
|
||||
|
||||
/**
|
||||
* A policy variant where if a type T has only primitive instance fields, then
|
||||
* instances of type T are NOT disambiguated by allocation site.
|
||||
* A policy variant where if a type T has only primitive instance fields, then instances of type T are NOT disambiguated by
|
||||
* allocation site.
|
||||
*/
|
||||
public static final int SMUSH_PRIMITIVE_HOLDERS = 8;
|
||||
|
||||
/**
|
||||
* This variant counts the N, number of allocation sites of a particular type
|
||||
* T in each method. If N > SMUSH_LIMIT, then these N allocation sites are NOT
|
||||
* distinguished ... instead there is a single abstract allocation site for
|
||||
* <N,T>
|
||||
* This variant counts the N, number of allocation sites of a particular type T in each method. If N > SMUSH_LIMIT, then these N
|
||||
* allocation sites are NOT distinguished ... instead there is a single abstract allocation site for <N,T>
|
||||
*
|
||||
* Probably the best choice in many cases.
|
||||
*/
|
||||
|
@ -107,8 +101,7 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
public static final int CONSTANT_SPECIFIC = 32;
|
||||
|
||||
/**
|
||||
* When using smushing, how many sites in a node will be kept distinct before
|
||||
* smushing?
|
||||
* When using smushing, how many sites in a node will be kept distinct before smushing?
|
||||
*/
|
||||
private final int SMUSH_LIMIT = 25;
|
||||
|
||||
|
@ -128,8 +121,7 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
private final AllocationSiteInNodeFactory siteBased;
|
||||
|
||||
/**
|
||||
* A delegate object to create "abstract allocation site" - based abstract
|
||||
* instances
|
||||
* A delegate object to create "abstract allocation site" - based abstract instances
|
||||
*/
|
||||
private final SmushedAllocationSiteInstanceKeys smushed;
|
||||
|
||||
|
@ -230,15 +222,14 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
smushees.add(e.getKey());
|
||||
}
|
||||
}
|
||||
s = smushees.isEmpty() ? Collections.<IClass>emptySet() : smushees;
|
||||
s = smushees.isEmpty() ? Collections.<IClass> emptySet() : smushees;
|
||||
smushMap.put(node, s);
|
||||
}
|
||||
return s.contains(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Map: IClass -> Integer, the number of allocation sites for each
|
||||
* type.
|
||||
* @return Map: IClass -> Integer, the number of allocation sites for each type.
|
||||
*/
|
||||
private Map<IClass, Integer> countAllocsByType(CGNode node) {
|
||||
Map<IClass, Integer> count = HashMapFactory.make();
|
||||
|
@ -282,8 +273,7 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
|
||||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory#getInstanceKeyForPEI(com.ibm.wala.ipa.callgraph.CGNode,
|
||||
* com.ibm.wala.classLoader.ProgramCounter,
|
||||
* com.ibm.wala.types.TypeReference)
|
||||
* com.ibm.wala.classLoader.ProgramCounter, com.ibm.wala.types.TypeReference)
|
||||
*/
|
||||
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter pei, TypeReference type) {
|
||||
return classBased.getInstanceKeyForPEI(node, pei, type);
|
||||
|
@ -326,33 +316,28 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
return c.getClassHierarchy().isSubclassOf(c, c.getClassHierarchy().lookupClass(TypeReference.JavaLangThrowable));
|
||||
}
|
||||
|
||||
public boolean isStackTraceElement(IClass C) {
|
||||
if (C == null) {
|
||||
public boolean isStackTraceElement(IClass c) {
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("C is null");
|
||||
}
|
||||
return C.getReference().equals(TypeReference.JavaLangStackTraceElement);
|
||||
return c.getReference().equals(TypeReference.JavaLangStackTraceElement);
|
||||
}
|
||||
|
||||
private boolean allFieldsArePrimitive(IClass C) {
|
||||
if (C.isArrayClass()) {
|
||||
TypeReference t = C.getReference().getArrayElementType();
|
||||
private boolean allFieldsArePrimitive(IClass c) {
|
||||
if (c.isArrayClass()) {
|
||||
TypeReference t = c.getReference().getArrayElementType();
|
||||
return t.isPrimitiveType();
|
||||
} else {
|
||||
if (C.getReference().equals(TypeReference.JavaLangObject)) {
|
||||
if (c.getReference().equals(TypeReference.JavaLangObject)) {
|
||||
return true;
|
||||
} else {
|
||||
for (Iterator<IField> it = C.getDeclaredInstanceFields().iterator(); it.hasNext();) {
|
||||
for (Iterator<IField> it = c.getDeclaredInstanceFields().iterator(); it.hasNext();) {
|
||||
IField f = it.next();
|
||||
if (f.getReference().getFieldType().isReferenceType()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return allFieldsArePrimitive(C.getSuperclass());
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
return allFieldsArePrimitive(c.getSuperclass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ import com.ibm.wala.ipa.callgraph.propagation.StandardSolver;
|
|||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DefaultPointerKeyFactory;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DefaultSSAInterpreter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DelegatingSSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
|
@ -55,7 +54,6 @@ import com.ibm.wala.types.FieldReference;
|
|||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
* Abstract superclass of various RTA flavors
|
||||
|
@ -87,10 +85,8 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
*/
|
||||
protected final HashSet<IClass> allocatedClasses = HashSetFactory.make();
|
||||
|
||||
|
||||
/**
|
||||
* set of class names that are implicitly pre-allocated Note: for performance
|
||||
* reasons make sure java.lang.Object comes first
|
||||
* set of class names that are implicitly pre-allocated Note: for performance reasons make sure java.lang.Object comes first
|
||||
*/
|
||||
private final static TypeReference[] PRE_ALLOC = {
|
||||
TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/lang/Object"),
|
||||
|
@ -103,8 +99,8 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/lang/ExceptionInInitializerError"),
|
||||
TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/lang/NullPointerException") };
|
||||
|
||||
protected AbstractRTABuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, ContextSelector appContextSelector,
|
||||
SSAContextInterpreter appContextInterpreter, ReflectionSpecification reflect) {
|
||||
protected AbstractRTABuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
|
||||
ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter, ReflectionSpecification reflect) {
|
||||
super(cha, options, cache, new DefaultPointerKeyFactory());
|
||||
setInstanceKeys(new ClassBasedInstanceKeys(options, cha));
|
||||
setContextSelector(makeContextSelector(appContextSelector));
|
||||
|
@ -116,13 +112,11 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Visit all instructions in a node, and add dataflow constraints induced by
|
||||
* each statement relevat to RTA
|
||||
* Visit all instructions in a node, and add dataflow constraints induced by each statement relevat to RTA
|
||||
*/
|
||||
@Override
|
||||
protected boolean addConstraintsFromNode(CGNode node) {
|
||||
|
||||
|
||||
|
||||
if (haveAlreadyVisited(node)) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -175,8 +169,7 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Is s is a getstatic or putstatic, then potentially add the relevant
|
||||
* <clinit>to the newMethod set.
|
||||
* Is s is a getstatic or putstatic, then potentially add the relevant <clinit>to the newMethod set.
|
||||
*/
|
||||
private void processFieldAccess(CGNode node, FieldReference f) {
|
||||
if (DEBUG) {
|
||||
|
@ -190,9 +183,8 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected void processClassInitializer(IClass klass) {
|
||||
|
||||
|
||||
if (clinitProcessed.contains(klass)) {
|
||||
return;
|
||||
}
|
||||
|
@ -217,8 +209,8 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
processResolvedCall(callGraph.getFakeWorldClinitNode(), s.getCallSite(), target);
|
||||
} catch (CancelException e) {
|
||||
if (DEBUG) {
|
||||
System.err.println("Could not add node for class initializer: " + targetMethod.getSignature() +
|
||||
" due to constraints on the maximum number of nodes in the call graph.");
|
||||
System.err.println("Could not add node for class initializer: " + targetMethod.getSignature()
|
||||
+ " due to constraints on the maximum number of nodes in the call graph.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -226,18 +218,15 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
klass = klass.getSuperclass();
|
||||
if (klass != null && !clinitProcessed.contains(klass))
|
||||
processClassInitializer(klass);
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
klass = klass.getSuperclass();
|
||||
if (klass != null && !clinitProcessed.contains(klass))
|
||||
processClassInitializer(klass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a constraint for a call instruction
|
||||
* @throws IllegalArgumentException if site is null
|
||||
*
|
||||
* @throws IllegalArgumentException if site is null
|
||||
*/
|
||||
public void visitInvoke(CGNode node, CallSiteReference site) {
|
||||
|
||||
|
@ -247,7 +236,7 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
if (DEBUG) {
|
||||
System.err.println(("visitInvoke: " + site));
|
||||
}
|
||||
|
||||
|
||||
// if non-virtual, add callgraph edges directly
|
||||
IInvokeInstruction.IDispatch code = site.getInvocationCode();
|
||||
|
||||
|
@ -286,8 +275,7 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
protected abstract PointerKey getKeyForSite(CallSiteReference site);
|
||||
|
||||
/**
|
||||
* Add constraints for a call site after we have computed a reachable target
|
||||
* for the dispatch
|
||||
* Add constraints for a call site after we have computed a reachable target for the dispatch
|
||||
*
|
||||
* Side effect: add edge to the call graph.
|
||||
*/
|
||||
|
@ -312,7 +300,8 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
|
||||
/**
|
||||
* Add a constraint for an allocate
|
||||
* @throws IllegalArgumentException if newSite is null
|
||||
*
|
||||
* @throws IllegalArgumentException if newSite is null
|
||||
*/
|
||||
public void visitNew(CGNode node, NewSiteReference newSite) {
|
||||
|
||||
|
@ -395,9 +384,10 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
ReflectionSpecification reflect) {
|
||||
|
||||
SSAContextInterpreter defI = new DefaultSSAInterpreter(getOptions(), getAnalysisCache());
|
||||
defI = new DelegatingSSAContextInterpreter(ReflectionContextInterpreter.createReflectionContextInterpreter(cha, getOptions(), getAnalysisCache(), reflect),
|
||||
defI);
|
||||
SSAContextInterpreter contextInterpreter = appContextInterpreter == null ? defI : new DelegatingSSAContextInterpreter(appContextInterpreter, defI);
|
||||
defI = new DelegatingSSAContextInterpreter(ReflectionContextInterpreter.createReflectionContextInterpreter(cha, getOptions(),
|
||||
getAnalysisCache(), reflect), defI);
|
||||
SSAContextInterpreter contextInterpreter = appContextInterpreter == null ? defI : new DelegatingSSAContextInterpreter(
|
||||
appContextInterpreter, defI);
|
||||
return contextInterpreter;
|
||||
}
|
||||
|
||||
|
@ -426,9 +416,8 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder {
|
|||
result.setPeriodicMaintainInterval(PERIODIC_MAINTAIN_INTERVAL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.CallGraphBuilder#getPointerAnalysis()
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -125,17 +125,18 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
private Collection<TypeReference> runtimeExceptionTypeRefs;
|
||||
|
||||
/**
|
||||
* Return a set of IClasses that holds all superclasses of klass
|
||||
* Return a set of {@link IClass} that holds all superclasses of klass
|
||||
*
|
||||
* @param klass class in question
|
||||
* @return Set the result set
|
||||
*/
|
||||
private Set<IClass> computeSuperclasses(IClass klass) throws ClassHierarchyException {
|
||||
private Set<IClass> computeSuperclasses(IClass klass) {
|
||||
if (DEBUG) {
|
||||
System.err.println("computeSuperclasses: " + klass);
|
||||
}
|
||||
|
||||
Set<IClass> result = HashSetFactory.make(3);
|
||||
|
||||
klass = klass.getSuperclass();
|
||||
|
||||
while (klass != null) {
|
||||
|
@ -146,7 +147,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
klass = klass.getSuperclass();
|
||||
if (klass != null && klass.getReference().getName().equals(rootTypeRef.getName())) {
|
||||
if (!klass.getReference().getClassLoader().equals(rootTypeRef.getClassLoader())) {
|
||||
throw new ClassHierarchyException("class " + klass + " is invalid, unexpected classloader");
|
||||
throw new IllegalStateException("class " + klass + " is invalid, unexpected classloader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,7 +231,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
progressMonitor.worked(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new ClassHierarchyException("factory.getLoader failed " + e);
|
||||
} finally {
|
||||
|
@ -293,7 +294,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
try {
|
||||
loadedSuperclasses = computeSuperclasses(klass);
|
||||
loadedSuperInterfaces = klass.getAllImplementedInterfaces();
|
||||
} catch (ClassHierarchyException e) {
|
||||
} catch (Exception e) {
|
||||
// a little cleanup
|
||||
if (klass instanceof ShrikeClass) {
|
||||
if (DEBUG) {
|
||||
|
@ -317,11 +318,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
while (node != null) {
|
||||
IClass c = node.getJavaClass();
|
||||
IClass superclass = null;
|
||||
try {
|
||||
superclass = c.getSuperclass();
|
||||
} catch (ClassHierarchyException e1) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
superclass = c.getSuperclass();
|
||||
if (superclass != null) {
|
||||
workingSuperclasses.remove(superclass);
|
||||
Node supernode = findOrCreateNode(superclass);
|
||||
|
@ -345,7 +342,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
try {
|
||||
// make sure we'll be able to load the interface!
|
||||
computeSuperclasses(iface);
|
||||
} catch (ClassHierarchyException e) {
|
||||
} catch (IllegalStateException e) {
|
||||
Warnings.add(ClassExclusion.create(iface.getReference(), e.getMessage()));
|
||||
continue;
|
||||
}
|
||||
|
@ -553,11 +550,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
return result;
|
||||
} else {
|
||||
IClass superclass = null;
|
||||
try {
|
||||
superclass = receiverClass.getSuperclass();
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
superclass = receiverClass.getSuperclass();
|
||||
if (superclass == null) {
|
||||
if (DEBUG) {
|
||||
System.err.println(("resolveMethod(" + selector + ") failed: method not found"));
|
||||
|
@ -756,13 +749,10 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
superB = null;
|
||||
}
|
||||
while (A != null) {
|
||||
if (superB.contains(A))
|
||||
if (superB.contains(A)) {
|
||||
return A;
|
||||
try {
|
||||
A = A.getSuperclass();
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
A = A.getSuperclass();
|
||||
}
|
||||
Assertions.UNREACHABLE("getLeastCommonSuperclass " + tempA + " " + B);
|
||||
return null;
|
||||
|
@ -833,19 +823,16 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
}
|
||||
|
||||
private boolean slowIsSubclass(IClass sub, IClass sup) {
|
||||
if (sub == sup)
|
||||
if (sub == sup) {
|
||||
return true;
|
||||
else
|
||||
try {
|
||||
IClass parent = sub.getSuperclass();
|
||||
if (parent == null)
|
||||
return false;
|
||||
else
|
||||
return slowIsSubclass(parent, sup);
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
} else {
|
||||
IClass parent = sub.getSuperclass();
|
||||
if (parent == null) {
|
||||
return false;
|
||||
} else {
|
||||
return slowIsSubclass(parent, sup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,20 +23,16 @@ public class ClassHierarchyUtil {
|
|||
* find the root of the inheritance tree for method m.
|
||||
*/
|
||||
public static IMethod getRootOfInheritanceTree(IMethod m) {
|
||||
try {
|
||||
IClass c = m.getDeclaringClass();
|
||||
IClass parent = c.getSuperclass();
|
||||
if (parent == null) {
|
||||
return m;
|
||||
} else {
|
||||
MethodReference ref = MethodReference.findOrCreate(parent.getReference(), m.getSelector());
|
||||
IMethod m2 = m.getClassHierarchy().resolveMethod(ref);
|
||||
if (m2 != null && !m2.equals(m)) {
|
||||
return getRootOfInheritanceTree(m2);
|
||||
}
|
||||
return m;
|
||||
IClass c = m.getDeclaringClass();
|
||||
IClass parent = c.getSuperclass();
|
||||
if (parent == null) {
|
||||
return m;
|
||||
} else {
|
||||
MethodReference ref = MethodReference.findOrCreate(parent.getReference(), m.getSelector());
|
||||
IMethod m2 = m.getClassHierarchy().resolveMethod(ref);
|
||||
if (m2 != null && !m2.equals(m)) {
|
||||
return getRootOfInheritanceTree(m2);
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
@ -45,20 +41,16 @@ public class ClassHierarchyUtil {
|
|||
* Return the method that m overrides, or null if none
|
||||
*/
|
||||
public static IMethod getOverriden(IMethod m) {
|
||||
try {
|
||||
IClass c = m.getDeclaringClass();
|
||||
IClass parent = c.getSuperclass();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
MethodReference ref = MethodReference.findOrCreate(parent.getReference(), m.getSelector());
|
||||
IMethod m2 = m.getClassHierarchy().resolveMethod(ref);
|
||||
if (m2 != null && !m2.equals(m)) {
|
||||
return m2;
|
||||
}
|
||||
return null;
|
||||
IClass c = m.getDeclaringClass();
|
||||
IClass parent = c.getSuperclass();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
MethodReference ref = MethodReference.findOrCreate(parent.getReference(), m.getSelector());
|
||||
IMethod m2 = m.getClassHierarchy().resolveMethod(ref);
|
||||
if (m2 != null && !m2.equals(m)) {
|
||||
return m2;
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,13 +72,13 @@ public class BypassSyntheticClass extends SyntheticClass {
|
|||
/*
|
||||
* @see com.ibm.wala.classLoader.IClass#getSuperclass()
|
||||
*/
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
public IClass getSuperclass() {
|
||||
if (realType.isInterface()) {
|
||||
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
throw new ClassHierarchyException("could not find java.lang.Object");
|
||||
throw new IllegalStateException("could not find java.lang.Object");
|
||||
}
|
||||
} else
|
||||
return realType;
|
||||
|
|
|
@ -131,7 +131,7 @@ public class ActionFormFactoryMethod extends SummarizedMethod {
|
|||
return factoryClassRef.getName();
|
||||
}
|
||||
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
public IClass getSuperclass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
|||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
|
@ -39,9 +38,7 @@ import com.ibm.wala.util.debug.Assertions;
|
|||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
/**
|
||||
* This class provides an iterator of entrypoints that are implementations of org.apache.struts.action.Action
|
||||
*
|
||||
* @author sfink
|
||||
* This class provides an iterator of {@link Entrypoint}s that are implementations of org.apache.struts.action.Action
|
||||
*/
|
||||
public class StrutsEntrypoints implements Iterable<Entrypoint>, EJBConstants {
|
||||
|
||||
|
@ -226,6 +223,7 @@ public class StrutsEntrypoints implements Iterable<Entrypoint>, EJBConstants {
|
|||
* Add any methods that look like they might be DispatchAction targets, based on the method signature.
|
||||
*
|
||||
* TODO: instead, parse the struts xml directly.
|
||||
*
|
||||
* @param klass an Action
|
||||
*/
|
||||
private void addSpeculativeDispatchMethods(IClass klass, IClassHierarchy cha) {
|
||||
|
@ -239,12 +237,7 @@ public class StrutsEntrypoints implements Iterable<Entrypoint>, EJBConstants {
|
|||
entrypoints.put(m, new StrutsActionEntrypoint(klass, M, cha));
|
||||
}
|
||||
}
|
||||
try {
|
||||
c = c.getSuperclass();
|
||||
} catch (ClassHierarchyException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,8 +324,9 @@ public class StrutsEntrypoints implements Iterable<Entrypoint>, EJBConstants {
|
|||
TypeName n = getParameterTypes(i)[0].getName();
|
||||
if (n.equals(actionFormName)) {
|
||||
// invoke a synthetic factory method that creates ActionForm objects
|
||||
MethodReference declaredTarget = MethodReference.findOrCreate(ActionFormFactoryMethod.factoryClassRef, ActionFormFactoryMethod.name, ActionFormFactoryMethod.descr);
|
||||
CallSiteReference site = CallSiteReference.make(0, declaredTarget , IInvokeInstruction.Dispatch.STATIC);
|
||||
MethodReference declaredTarget = MethodReference.findOrCreate(ActionFormFactoryMethod.factoryClassRef,
|
||||
ActionFormFactoryMethod.name, ActionFormFactoryMethod.descr);
|
||||
CallSiteReference site = CallSiteReference.make(0, declaredTarget, IInvokeInstruction.Dispatch.STATIC);
|
||||
SSAInvokeInstruction factoryInv = m.addInvocation(new int[0], site);
|
||||
return factoryInv.getDef();
|
||||
} else {
|
||||
|
@ -373,8 +367,8 @@ public class StrutsEntrypoints implements Iterable<Entrypoint>, EJBConstants {
|
|||
}
|
||||
|
||||
/**
|
||||
* An entrypoint which assumes all ServletRequest and ServletResponses are of the HTTP flavor. TODO: get rid of this
|
||||
* and just use {@link DefaultEntrypoint}? --MS
|
||||
* An entrypoint which assumes all ServletRequest and ServletResponses are of the HTTP flavor. TODO: get rid of this and just use
|
||||
* {@link DefaultEntrypoint}? --MS
|
||||
*/
|
||||
private static class StrutsPlugInEntrypoint extends DefaultEntrypoint {
|
||||
|
||||
|
@ -382,7 +376,7 @@ public class StrutsEntrypoints implements Iterable<Entrypoint>, EJBConstants {
|
|||
super(method, cha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return the set of classes that should be examined when searching for struts entrypoints.
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,6 @@ import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
|||
import com.ibm.wala.ipa.callgraph.ClassTargetSelector;
|
||||
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.j2ee.BeanMetaData;
|
||||
import com.ibm.wala.j2ee.DeploymentMetaData;
|
||||
|
@ -30,7 +29,7 @@ import com.ibm.wala.util.debug.Assertions;
|
|||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
* Miscellaneous J2EE Utilities
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
|
@ -49,9 +48,7 @@ public class Util {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param bean
|
||||
* @param cha
|
||||
* governing class hierarchy
|
||||
* @param cha governing class hierarchy
|
||||
* @return the Set of CMR fields for this bean, including inherited CMRs
|
||||
*/
|
||||
public static Set<Object> getCMRFields(BeanMetaData bean, DeploymentMetaData dmd, ClassHierarchy cha) {
|
||||
|
@ -66,12 +63,8 @@ public class Util {
|
|||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(klass != null);
|
||||
}
|
||||
try {
|
||||
IClass superKlass = klass.getSuperclass();
|
||||
T = (superKlass == null) ? null : superKlass.getReference();
|
||||
} catch (ClassHierarchyException e) {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
IClass superKlass = klass.getSuperclass();
|
||||
T = (superKlass == null) ? null : superKlass.getReference();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue