diff --git a/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java b/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java index a12e648a7..c72bd5e54 100644 --- a/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java +++ b/com.ibm.wala.cast.java.polyglot/source/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java @@ -124,6 +124,7 @@ import com.ibm.wala.cast.java.loader.Util; import com.ibm.wala.cast.java.translator.JavaProcedureEntity; import com.ibm.wala.cast.java.types.JavaType; import com.ibm.wala.cast.tree.CAst; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstControlFlowMap; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstNode; @@ -1399,6 +1400,11 @@ public class PolyglotJava2CAstTranslator { return null; } + @Override + public Collection getAnnotations() { + return null; + } + public CAstControlFlowMap getControlFlow() { Assertions.UNREACHABLE("CompilationUnitEntity.getControlFlow()"); return null; @@ -1578,6 +1584,11 @@ public class PolyglotJava2CAstTranslator { return null; } + @Override + public Collection getAnnotations() { + return null; + } + public Map> getAllScopedEntities() { return Collections.singletonMap(null, fEntities); } @@ -1805,6 +1816,11 @@ public class PolyglotJava2CAstTranslator { } }; } + + @Override + public Collection getAnnotations() { + return null; + } } protected final class FieldEntity implements CAstEntity { @@ -1856,6 +1872,11 @@ public class PolyglotJava2CAstTranslator { return null; } + @Override + public Collection getAnnotations() { + return null; + } + public CAstControlFlowMap getControlFlow() { // No AST for a field decl; initializers folded into // constructor processing... diff --git a/com.ibm.wala.cast.java.test.data/src/javaonepointfive/Annotations.java b/com.ibm.wala.cast.java.test.data/src/javaonepointfive/Annotations.java index cf93e4364..cedbde22e 100644 --- a/com.ibm.wala.cast.java.test.data/src/javaonepointfive/Annotations.java +++ b/com.ibm.wala.cast.java.test.data/src/javaonepointfive/Annotations.java @@ -6,6 +6,7 @@ package javaonepointfive; String date(); } +@TestAnnotation (doSomething="The class", count=-1, date="09-09-2001") public class Annotations { @TestAnnotation (doSomething="What to do", count=1, date="09-09-2005") diff --git a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/IRTests.java b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/IRTests.java index 903edf3b5..636d822db 100644 --- a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/IRTests.java +++ b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/IRTests.java @@ -49,6 +49,7 @@ import com.ibm.wala.types.ClassLoaderReference; import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.CancelException; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.collections.Pair; @@ -250,6 +251,63 @@ public abstract class IRTests { } } + protected static class AnnotationAssertions implements IRAssertion { + + public static class ClassAnnotation { + private final String className; + private final String annotationTypeName; + + public ClassAnnotation(String className, String annotationTypeName) { + super(); + this.className = className; + this.annotationTypeName = annotationTypeName; + } + } + + public static class MethodAnnotation { + private final String methodSig; + private final String annotationTypeName; + + public MethodAnnotation(String methodSig, String annotationTypeName) { + super(); + this.methodSig = methodSig; + this.annotationTypeName = annotationTypeName; + } + } + + public final Set classAnnotations = HashSetFactory.make(); + public final Set methodAnnotations = HashSetFactory.make(); + + public void check(CallGraph cg) { + classes: for(ClassAnnotation ca : classAnnotations) { + IClass cls = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ca.className)); + IClass at = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ca.annotationTypeName)); + for(Annotation a : cls.getAnnotations()) { + if (a.getType().equals(at.getReference())) { + continue classes; + } + } + + Assert.assertFalse("cannot find " + at + " in " + cls, false); + } + + for(MethodAnnotation ma : methodAnnotations) { + IClass at = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ma.annotationTypeName)); + annot: for(CGNode n : cg) { + if (n.getMethod().getSignature().equals(ma.methodSig)) { + for(Annotation a : n.getMethod().getAnnotations()) { + if (a.getType().equals(at.getReference())) { + continue annot; + } + } + + Assert.assertFalse("cannot find " + at, false); + } + } + } + } + } + protected Collection singleTestSrc() { return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaInputForTest()); } diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/loader/JavaSourceLoaderImpl.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/loader/JavaSourceLoaderImpl.java index 7bb538dc6..cc449f972 100644 --- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/loader/JavaSourceLoaderImpl.java +++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/loader/JavaSourceLoaderImpl.java @@ -42,6 +42,7 @@ import com.ibm.wala.cast.loader.AstClass; import com.ibm.wala.cast.loader.AstField; import com.ibm.wala.cast.loader.AstMethod; import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstQualifier; import com.ibm.wala.cast.tree.CAstSourcePositionMap; @@ -61,6 +62,8 @@ import com.ibm.wala.classLoader.ModuleEntry; import com.ibm.wala.classLoader.NewSiteReference; import com.ibm.wala.ipa.callgraph.impl.SetOfClasses; import com.ibm.wala.ipa.cha.IClassHierarchy; +import com.ibm.wala.shrikeCT.AnnotationsReader.ElementValue; +import com.ibm.wala.shrikeCT.AnnotationsReader.ConstantElementValue; import com.ibm.wala.shrikeCT.ClassConstants; import com.ibm.wala.ssa.SSAThrowInstruction; import com.ibm.wala.ssa.SymbolTable; @@ -71,7 +74,9 @@ import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.strings.Atom; @@ -92,11 +97,18 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl { protected final Collection superTypeNames; + private final Collection annotations; + public JavaClass(String typeName, Collection superTypeNames, CAstSourcePositionMap.Position position, Collection qualifiers, - JavaSourceLoaderImpl loader, IClass enclosingClass) { + JavaSourceLoaderImpl loader, IClass enclosingClass, Collection annotations) { super(position, TypeName.string2TypeName(typeName), loader, (short) mapToInt(qualifiers), new HashMap(), new HashMap()); this.superTypeNames = superTypeNames; this.enclosingClass = enclosingClass; + this.annotations = annotations; + } + + public Collection getAnnotations() { + return annotations; } public IClassHierarchy getClassHierarchy() { @@ -157,7 +169,7 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl { } private void addField(CAstEntity fieldEntity) { - declaredFields.put(Util.fieldEntityToAtom(fieldEntity), new JavaField(fieldEntity, JavaSourceLoaderImpl.this, this)); + declaredFields.put(Util.fieldEntityToAtom(fieldEntity), new JavaField(fieldEntity, JavaSourceLoaderImpl.this, this, JavaSourceLoaderImpl.this.getAnnotations(fieldEntity))); } public IClass getEnclosingClass() { @@ -165,24 +177,53 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl { } public String toString() { - if (enclosingClass == null) { - return ""; - } else { - return ""; + StringBuffer sb = new StringBuffer(" getAnnotations(CAstEntity e) { + Collection annotations = e.getAnnotations(); + if (annotations == null || annotations.isEmpty()) { + return null; + } else { + Collection result = HashSetFactory.make(); + for(CAstAnnotation ca : annotations) { + TypeName walaTypeName = toWALATypeName(ca.getType()); + TypeReference ref = TypeReference.findOrCreate(getReference(), walaTypeName); + if (ca.getArguments() == null || ca.getArguments().isEmpty()) { + result.add(Annotation.make(ref)); + } else { + Map args = HashMapFactory.make(); + for(Map.Entry a : ca.getArguments().entrySet()) { + args.put(a.getKey(), new ConstantElementValue(a.getValue())); + } + result.add(Annotation.makeWithNamed(ref, args)); + } + } + return result; + } + } + /** * DOMO representation of a field on a Java type that resides in a source file * * @author rfuhrer */ private class JavaField extends AstField { - private JavaField(CAstEntity fieldEntity, IClassLoader loader, IClass declaringClass) { + private JavaField(CAstEntity fieldEntity, IClassLoader loader, IClass declaringClass, Collection annotations) { super(FieldReference.findOrCreate(declaringClass.getReference(), Atom.findOrCreateUnicodeAtom(fieldEntity.getName()), TypeReference.findOrCreate(loader.getReference(), TypeName.string2TypeName(fieldEntity.getType().getName()))), - fieldEntity.getQualifiers(), declaringClass, declaringClass.getClassHierarchy()); + fieldEntity.getQualifiers(), declaringClass, declaringClass.getClassHierarchy(), annotations); } } @@ -200,14 +241,14 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl { public JavaEntityMethod(CAstEntity methodEntity, IClass owner, AbstractCFG cfg, SymbolTable symtab, boolean hasCatchBlock, TypeReference[][] catchTypes, boolean hasMonitorOp, AstLexicalInformation lexicalInfo, DebuggingInformation debugInfo) { super(owner, methodEntity.getQualifiers(), cfg, symtab, MethodReference.findOrCreate(owner.getReference(), Util - .methodEntityToSelector(methodEntity)), hasCatchBlock, catchTypes, hasMonitorOp, lexicalInfo, debugInfo); + .methodEntityToSelector(methodEntity)), hasCatchBlock, catchTypes, hasMonitorOp, lexicalInfo, debugInfo, JavaSourceLoaderImpl.this.getAnnotations(methodEntity)); this.parameterTypes = computeParameterTypes(methodEntity); this.exceptionTypes = computeExceptionTypes(methodEntity); } public JavaEntityMethod(CAstEntity methodEntity, IClass owner) { super(owner, methodEntity.getQualifiers(), MethodReference.findOrCreate(owner.getReference(), Util - .methodEntityToSelector(methodEntity))); + .methodEntityToSelector(methodEntity)), JavaSourceLoaderImpl.this.getAnnotations(methodEntity)); this.parameterTypes = computeParameterTypes(methodEntity); this.exceptionTypes = computeExceptionTypes(methodEntity); } @@ -449,14 +490,18 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl { ((JavaClass) owner).addField(n); } + private TypeName toWALATypeName(CAstType type) { + return TypeName.string2TypeName(type.getName()); + } + public IClass defineType(CAstEntity type, String typeName, CAstEntity owner) { Collection superTypeNames = new ArrayList(); for (Iterator superTypes = type.getType().getSupertypes().iterator(); superTypes.hasNext();) { - superTypeNames.add(TypeName.string2TypeName(((CAstType) superTypes.next()).getName())); + superTypeNames.add(toWALATypeName(((CAstType) superTypes.next()))); } JavaClass javaClass = new JavaClass(typeName, superTypeNames, type.getPosition(), type.getQualifiers(), this, - (owner != null) ? (JavaClass) fTypeMap.get(owner) : (JavaClass) null); + (owner != null) ? (JavaClass) fTypeMap.get(owner) : (JavaClass) null, getAnnotations(type)); if (getParent().lookupClass(javaClass.getName()) != null) { return null; diff --git a/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java b/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java index 8722ee8b1..b61fa350b 100755 --- a/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java +++ b/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java @@ -91,6 +91,7 @@ import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder; import com.ibm.wala.cast.js.loader.JavaScriptLoader; import com.ibm.wala.cast.js.types.JavaScriptTypes; import com.ibm.wala.cast.tree.CAst; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstControlFlowMap; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstNode; @@ -466,6 +467,10 @@ public class RhinoToAstTranslator { return null; } + public Collection getAnnotations() { + return null; + } + public Collection getQualifiers() { Assertions.UNREACHABLE("JuliansUnnamedCAstEntity$2.getQualifiers()"); return null; diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/correlations/extraction/ExtractedFunction.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/correlations/extraction/ExtractedFunction.java index 4596f8b32..ce8e39cae 100644 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/correlations/extraction/ExtractedFunction.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/correlations/extraction/ExtractedFunction.java @@ -17,6 +17,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstControlFlowMap; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstNode; @@ -162,6 +163,11 @@ class ExtractedFunction implements CAstEntity { } @Override + public Collection getAnnotations() { + return null; + } + + @Override public String toString() { return ""; } diff --git a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java index efd0d7378..e94fcda98 100755 --- a/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java +++ b/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java @@ -115,6 +115,7 @@ import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.strings.Atom; @@ -627,6 +628,11 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader { public IClass getSuperclass() { return superClass; } + + @Override + public Collection getAnnotations() { + return Collections.emptySet(); + } } class JavaScriptRootClass extends AstDynamicPropertyClass { @@ -652,6 +658,11 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader { public IClass getSuperclass() { return null; } + + @Override + public Collection getAnnotations() { + return Collections.emptySet(); + } } class JavaScriptCodeBody extends AstFunctionClass { @@ -676,6 +687,11 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader { codeBody.translationContext = translationContext; return codeBody; } + + @Override + public Collection getAnnotations() { + return Collections.emptySet(); + } } private static final Set functionQualifiers; @@ -693,7 +709,7 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader { JavaScriptMethodObject(IClass cls, AbstractCFG cfg, SymbolTable symtab, boolean hasCatchBlock, TypeReference[][] caughtTypes, boolean hasMonitorOp, AstLexicalInformation lexicalInfo, DebuggingInformation debugInfo) { super(cls, functionQualifiers, cfg, symtab, AstMethodReference.fnReference(cls.getReference()), hasCatchBlock, caughtTypes, - hasMonitorOp, lexicalInfo, debugInfo); + hasMonitorOp, lexicalInfo, debugInfo, null); // force creation of these constants by calling the getter methods symtab.getNullConstant(); diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AbstractEntity.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AbstractEntity.java index 52bef503c..f0c9c99e9 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AbstractEntity.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AbstractEntity.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.Map; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstNode; import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position; @@ -29,6 +30,11 @@ public abstract class AbstractEntity implements CAstEntity { return null; } + + public Collection getAnnotations() { + return null; + } + public void setPosition(Position pos) { sourcePosition = pos; } diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstDynamicPropertyClass.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstDynamicPropertyClass.java index 4fd5aeef2..91093f3cb 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstDynamicPropertyClass.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstDynamicPropertyClass.java @@ -10,6 +10,8 @@ *****************************************************************************/ package com.ibm.wala.cast.loader; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -23,6 +25,7 @@ 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.types.annotations.Annotation; import com.ibm.wala.util.strings.Atom; public abstract class AstDynamicPropertyClass extends AstClass { @@ -89,6 +92,10 @@ public abstract class AstDynamicPropertyClass extends AstClass { public IClassHierarchy getClassHierarchy() { return AstDynamicPropertyClass.this.getClassHierarchy(); } + + public Collection getAnnotations() { + return Collections.emptySet(); + } }); return declaredFields.get(name); diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstField.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstField.java index 7055522af..65fd4a827 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstField.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstField.java @@ -19,6 +19,7 @@ import com.ibm.wala.classLoader.IField; import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.types.FieldReference; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.strings.Atom; public class AstField implements IField { @@ -26,16 +27,24 @@ public class AstField implements IField { private final FieldReference ref; private final IClass declaringClass; private final IClassHierarchy cha; + private final Collection annotations; public AstField(FieldReference ref, Collection qualifiers, IClass declaringClass, - IClassHierarchy cha) + IClassHierarchy cha, + Collection annotations) { this.declaringClass = declaringClass; this.qualifiers = qualifiers; this.ref = ref; this.cha = cha; + this.annotations = annotations; + } + + + public Collection getAnnotations() { + return annotations; } public IClass getDeclaringClass() { diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstMethod.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstMethod.java index 8b6416a00..125b6562f 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstMethod.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/loader/AstMethod.java @@ -26,6 +26,7 @@ import com.ibm.wala.types.Descriptor; import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.collections.Pair; import com.ibm.wala.util.intset.IntSet; import com.ibm.wala.util.strings.Atom; @@ -113,10 +114,11 @@ public abstract class AstMethod implements IMethod { private final TypeReference[][] catchTypes; private final AstLexicalInformation lexicalInfo; private final DebuggingInformation debugInfo; + private final Collection annotations; protected AstMethod(IClass cls, Collection qualifiers, AbstractCFG cfg, SymbolTable symtab, MethodReference ref, boolean hasCatchBlock, TypeReference[][] catchTypes, boolean hasMonitorOp, AstLexicalInformation lexicalInfo, - DebuggingInformation debugInfo) { + DebuggingInformation debugInfo, Collection annotations) { this.cls = cls; this.cfg = cfg; this.ref = ref; @@ -127,12 +129,14 @@ public abstract class AstMethod implements IMethod { this.hasMonitorOp = hasMonitorOp; this.lexicalInfo = lexicalInfo; this.debugInfo = debugInfo; + this.annotations = annotations; } - protected AstMethod(IClass cls, Collection qualifiers, MethodReference ref) { + protected AstMethod(IClass cls, Collection qualifiers, MethodReference ref, Collection annotations) { this.cls = cls; this.qualifiers = qualifiers; this.ref = ref; + this.annotations = annotations; this.cfg = null; this.symtab = null; @@ -173,6 +177,10 @@ public abstract class AstMethod implements IMethod { return debugInfo; } + public Collection getAnnotations() { + return annotations; + } + /** * Parents of this method with respect to lexical scoping, that is, methods * containing state possibly referenced lexically in this method diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstAnnotation.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstAnnotation.java new file mode 100644 index 000000000..eabe004d7 --- /dev/null +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstAnnotation.java @@ -0,0 +1,11 @@ +package com.ibm.wala.cast.tree; + +import java.util.Map; + +public interface CAstAnnotation { + + CAstType getType(); + + Map getArguments(); + +} diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstEntity.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstEntity.java index 5f2460155..541a13c64 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstEntity.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstEntity.java @@ -177,4 +177,10 @@ public interface CAstEntity { * The CAst type of this entity. */ CAstType getType(); + + /** + * Returns the set of any annotations this entity may have + */ + Collection getAnnotations(); + } diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/DelegatingEntity.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/DelegatingEntity.java index 9bd65ec39..047b88a30 100644 --- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/DelegatingEntity.java +++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/impl/DelegatingEntity.java @@ -14,6 +14,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.Map; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstControlFlowMap; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstNode; @@ -89,4 +90,8 @@ public class DelegatingEntity implements CAstEntity { return base.getType(); } + public Collection getAnnotations() { + return base.getAnnotations(); + } + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/ArrayClass.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/ArrayClass.java index 3135e8399..4742d91e8 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/ArrayClass.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/ArrayClass.java @@ -24,6 +24,7 @@ import com.ibm.wala.shrikeBT.Constants; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.debug.UnimplementedError; @@ -332,4 +333,8 @@ public class ArrayClass implements IClass, Constants { return null; } + public Collection getAnnotations() { + return Collections.emptySet(); + } + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/IClass.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/IClass.java index 514e84bc1..c3b8acae5 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/IClass.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/IClass.java @@ -19,6 +19,7 @@ import com.ibm.wala.ipa.cha.IClassHierarchyDweller; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.strings.Atom; /** @@ -178,4 +179,9 @@ public interface IClass extends IClassHierarchyDweller { */ boolean isReferenceType(); + /** + * get annotations, if any + */ + Collection getAnnotations(); + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/IMember.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/IMember.java index 6fe0d690a..0f58c15f8 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/IMember.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/IMember.java @@ -10,7 +10,10 @@ *******************************************************************************/ package com.ibm.wala.classLoader; +import java.util.Collection; + import com.ibm.wala.ipa.cha.IClassHierarchyDweller; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.strings.Atom; /** @@ -38,4 +41,9 @@ public interface IMember extends IClassHierarchyDweller { */ boolean isStatic(); + /** + * Get the annotations on this member, if any + */ + Collection getAnnotations(); + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeCTMethod.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeCTMethod.java index 4423e1254..18fc1b5cd 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeCTMethod.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeCTMethod.java @@ -30,6 +30,7 @@ import com.ibm.wala.shrikeCT.SignatureReader; import com.ibm.wala.types.TypeReference; import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.types.generics.MethodTypeSignature; +import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; /** @@ -354,6 +355,16 @@ public final class ShrikeCTMethod extends ShrikeBTMethod implements IBytecodeMet return Annotation.getAnnotationsFromReader(r, getDeclaringClass().getClassLoader().getReference()); } + public Collection getAnnotations() { + Collection result = HashSetFactory.make(); + try { + result.addAll(getAnnotations(true)); + result.addAll(getAnnotations(false)); + } catch (InvalidClassFileException e) { + + } + return result; + } private static final IndirectionData NO_INDIRECTIONS = new IndirectionData() { diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeClass.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeClass.java index 1528778d7..3aee4ffc7 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeClass.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/ShrikeClass.java @@ -30,6 +30,7 @@ import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.types.generics.ClassSignature; +import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.shrike.ShrikeClassReaderHandle; import com.ibm.wala.util.strings.Atom; @@ -226,6 +227,17 @@ public final class ShrikeClass extends JVMClass { return getAnnotations(false); } + public Collection getAnnotations() { + Collection result = HashSetFactory.make(); + try { + result.addAll(getAnnotations(true)); + result.addAll(getAnnotations(false)); + } catch (InvalidClassFileException e) { + + } + return result; + } + public Collection getAnnotations(boolean runtimeInvisible) throws InvalidClassFileException { AnnotationsReader r = getAnnotationsReader(runtimeInvisible); return Annotation.getAnnotationsFromReader(r, getClassLoader().getReference()); diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticClass.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticClass.java index b3d018818..d38d18ed4 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticClass.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticClass.java @@ -12,11 +12,14 @@ package com.ibm.wala.classLoader; import java.io.InputStream; +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; import com.ibm.wala.util.strings.Atom; /** @@ -129,4 +132,10 @@ public abstract class SyntheticClass implements IClass { public IField getField(Atom name, TypeName typeName) { return getField(name); } + + public Collection getAnnotations() { + return Collections.emptySet(); + } + + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticMethod.java b/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticMethod.java index d8dbce220..d3a3d25e4 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticMethod.java +++ b/com.ibm.wala.core/src/com/ibm/wala/classLoader/SyntheticMethod.java @@ -10,6 +10,9 @@ *******************************************************************************/ package com.ibm.wala.classLoader; +import java.util.Collection; +import java.util.Collections; + import com.ibm.wala.cfg.InducedCFG; import com.ibm.wala.ipa.callgraph.Context; import com.ibm.wala.ipa.callgraph.impl.Everywhere; @@ -22,6 +25,7 @@ import com.ibm.wala.types.Descriptor; import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.bytecode.BytecodeStream; import com.ibm.wala.util.debug.UnimplementedError; import com.ibm.wala.util.strings.Atom; @@ -364,4 +368,8 @@ public class SyntheticMethod implements IMethod { return getDeclaringClass().getClassHierarchy(); } + public Collection getAnnotations() { + return Collections.emptySet(); + } + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/demandpa/util/ArrayContents.java b/com.ibm.wala.core/src/com/ibm/wala/demandpa/util/ArrayContents.java index 6c84d25e5..17e4c55bb 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/demandpa/util/ArrayContents.java +++ b/com.ibm.wala.core/src/com/ibm/wala/demandpa/util/ArrayContents.java @@ -37,11 +37,15 @@ */ package com.ibm.wala.demandpa.util; +import java.util.Collection; +import java.util.Collections; + import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.IField; import com.ibm.wala.ipa.cha.ClassHierarchy; import com.ibm.wala.types.FieldReference; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.debug.UnimplementedError; import com.ibm.wala.util.strings.Atom; @@ -120,4 +124,8 @@ public class ArrayContents implements IField { public FieldReference getReference() { return null; } + + public Collection getAnnotations() { + return Collections.emptySet(); + } } \ No newline at end of file diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/FakeRootClass.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/FakeRootClass.java index 2d14a530d..aa1e82e76 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/FakeRootClass.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/FakeRootClass.java @@ -26,6 +26,7 @@ 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.types.annotations.Annotation; import com.ibm.wala.util.collections.HashMapFactory; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; @@ -104,6 +105,10 @@ public class FakeRootClass extends SyntheticClass { public boolean isPublic() { return false; } + + public Collection getAnnotations() { + return Collections.emptySet(); + } }); } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/summaries/BypassSyntheticClass.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/summaries/BypassSyntheticClass.java index faac7f7a5..2b6d121c8 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/summaries/BypassSyntheticClass.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/summaries/BypassSyntheticClass.java @@ -12,6 +12,7 @@ package com.ibm.wala.ipa.summaries; import java.io.InputStream; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import com.ibm.wala.classLoader.IClass; @@ -23,6 +24,7 @@ import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.types.Selector; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; +import com.ibm.wala.types.annotations.Annotation; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.debug.UnimplementedError; @@ -244,4 +246,8 @@ public class BypassSyntheticClass extends SyntheticClass { return null; } + public Collection getAnnotations() { + return Collections.emptySet(); + } + } diff --git a/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java b/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java index 0007c8058..21603eb39 100644 --- a/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java +++ b/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTJava2CAstTranslator.java @@ -47,11 +47,13 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; @@ -82,6 +84,9 @@ import org.eclipse.jdt.core.dom.ExpressionStatement; import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ForStatement; +import org.eclipse.jdt.core.dom.IAnnotationBinding; +import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.IMemberValuePairBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; @@ -131,6 +136,7 @@ import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl; import com.ibm.wala.cast.java.loader.Util; import com.ibm.wala.cast.java.translator.JavaProcedureEntity; import com.ibm.wala.cast.tree.CAst; +import com.ibm.wala.cast.tree.CAstAnnotation; import com.ibm.wala.cast.tree.CAstControlFlowMap; import com.ibm.wala.cast.tree.CAstEntity; import com.ibm.wala.cast.tree.CAstNode; @@ -152,6 +158,7 @@ import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.TypeReference; import com.ibm.wala.util.collections.EmptyIterator; import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.collections.Pair; import com.ibm.wala.util.debug.Assertions; @@ -268,16 +275,26 @@ public class JDTJava2CAstTranslator { private final JdtPosition fSourcePosition; + private final Set annotations; + public ClassEntity(ITypeBinding jdtType, String name, Collection quals, Collection entities, - JdtPosition pos) { + JdtPosition pos, Set annotations) { fName = name; fQuals = quals; fEntities = entities; fJdtType = jdtType; fSourcePosition = pos; + this.annotations = annotations; } - public int getKind() { + @Override + public Collection getAnnotations() { + // TODO Auto-generated method stub + return null; + } + + + public int getKind() { return TYPE_ENTITY; } @@ -423,8 +440,10 @@ public class JDTJava2CAstTranslator { Collection quals = JDT2CAstUtils.mapModifiersToQualifiers(fieldDecl.getModifiers(), false, false); for (Object f : fieldDecl.fragments()) { VariableDeclarationFragment fieldFrag = (VariableDeclarationFragment) f; - memberEntities.add(new FieldEntity(fieldFrag.getName().getIdentifier(), fieldFrag.resolveBinding().getType(), quals, - makePosition(fieldFrag.getStartPosition(), fieldFrag.getStartPosition() + fieldFrag.getLength()))); + IVariableBinding fieldBinding = fieldFrag.resolveBinding(); + memberEntities.add(new FieldEntity(fieldFrag.getName().getIdentifier(), fieldBinding.getType(), quals, + makePosition(fieldFrag.getStartPosition(), fieldFrag.getStartPosition() + fieldFrag.getLength()), + handleAnnotations(fieldBinding))); } } else if (decl instanceof Initializer) { // Initializers are inserted into constructors when making constructors. @@ -481,11 +500,14 @@ public class JDTJava2CAstTranslator { for (int i = 0; i < staticInits.size(); i++) bodyNodes[i] = visitFieldInitNode(staticInits.get(i), newContext); CAstNode staticInitAst = makeNode(newContext, fFactory, n, CAstNode.BLOCK_STMT, bodyNodes); - memberEntities.add(new ProcedureEntity(staticInitAst, typeBinding, childEntities, newContext)); + memberEntities.add(new ProcedureEntity(staticInitAst, typeBinding, childEntities, newContext, null)); } Collection quals = JDT2CAstUtils.mapModifiersToQualifiers(modifiers, isInterface, isAnnotation); - return new ClassEntity(typeBinding, name, quals, memberEntities, makePosition(n)); + + Set annotations = handleAnnotations(typeBinding); + + return new ClassEntity(typeBinding, name, quals, memberEntities, makePosition(n), annotations); } private CAstEntity visit(AnonymousClassDeclaration n, WalkContext context) { @@ -577,7 +599,7 @@ public class JDTJava2CAstTranslator { // finally, make the procedure entity CAstNode ast = makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, bodyNodes); - return new ProcedureEntity(ast, fakeCtor, newType, memberEntities, context, paramTypes, null); + return new ProcedureEntity(ast, fakeCtor, newType, memberEntities, context, paramTypes, null, null); } @@ -726,7 +748,7 @@ public class JDTJava2CAstTranslator { for (ITypeBinding paramType : overridden.getParameterTypes()) paramCAstTypes.add(fTypeDict.getCAstTypeFor(paramType)); return new ProcedureEntity(mdast, overriding, overridingBinding.getDeclaringClass(), memberEntities, context, paramCAstTypes, - overridden.getReturnType()); + overridden.getReturnType(), null); } /** @@ -754,10 +776,51 @@ public class JDTJava2CAstTranslator { // Polyglot comment: Presumably the MethodContext's parent is a ClassContext, // and he has the list of initializers. Hopefully the following // will glue that stuff in the right place in any constructor body. - - return new ProcedureEntity(mdast, n, classBinding, memberEntities, context); + + Set annotations = null; + if (n.resolveBinding() != null) { + annotations = handleAnnotations(n.resolveBinding()); + } + + return new ProcedureEntity(mdast, n, classBinding, memberEntities, context, annotations); } + private Set handleAnnotations(IBinding binding) { + IAnnotationBinding[] annotations = binding.getAnnotations(); + + if(annotations == null || annotations.length == 0) { + return null; + } + + Set castAnnotations = HashSetFactory.make(); + for(IAnnotationBinding annotation : annotations) { + ITypeBinding annotationTypeBinding = annotation.getAnnotationType(); + final CAstType annotationType = fTypeDict.getCAstTypeFor(annotationTypeBinding); + final Map args = HashMapFactory.make(); + for(IMemberValuePairBinding mvpb : annotation.getAllMemberValuePairs()) { + String name = mvpb.getName(); + Object value = mvpb.getValue(); + args.put(name, value); + } + castAnnotations.add(new CAstAnnotation() { + @Override + public CAstType getType() { + return annotationType; + } + @Override + public Map getArguments() { + return args; + } + @Override + public String toString() { + return annotationType.getName() + args; + } + }); + } + + return castAnnotations; +} + protected final class ProcedureEntity implements JavaProcedureEntity { // TAGALONG (make static, access ast) // From Code Body Entity @@ -795,6 +858,8 @@ public class JDTJava2CAstTranslator { private int fModifiers; + private final Set annotations; + // can be method, constructor, "fake" default constructor, or null decl = static initializer /** * For a static initializer, pass a null decl. @@ -802,22 +867,22 @@ public class JDTJava2CAstTranslator { // FIXME: get rid of decl and pass in everything instead of having to do two different things with parameters // regular case private ProcedureEntity(CAstNode mdast, MethodDeclaration decl, ITypeBinding type, Map entities, - MethodContext context) { - this(mdast, decl, type, entities, context, null, null, decl.getModifiers()); + MethodContext context, Set annotations) { + this(mdast, decl, type, entities, context, null, null, decl.getModifiers(), annotations); } // static init - private ProcedureEntity(CAstNode mdast, ITypeBinding type, Map entities, MethodContext context) { - this(mdast, null, type, entities, context, null, null, 0); + private ProcedureEntity(CAstNode mdast, ITypeBinding type, Map entities, MethodContext context, Set annotations) { + this(mdast, null, type, entities, context, null, null, 0, annotations); } private ProcedureEntity(CAstNode mdast, MethodDeclaration decl, ITypeBinding type, Map entities, - MethodContext context, ArrayList parameterTypes, ITypeBinding returnType) { - this(mdast, decl, type, entities, context, parameterTypes, returnType, decl.getModifiers()); + MethodContext context, ArrayList parameterTypes, ITypeBinding returnType, Set annotations) { + this(mdast, decl, type, entities, context, parameterTypes, returnType, decl.getModifiers(), annotations); } private ProcedureEntity(CAstNode mdast, MethodDeclaration decl, ITypeBinding type, Map entities, - MethodContext context, ArrayList parameterTypes, ITypeBinding returnType, int modifiers) { + MethodContext context, ArrayList parameterTypes, ITypeBinding returnType, int modifiers, Set annotations) { // TypeSystem system, CodeInstance pd, String[] argumentNames, // } // Map entities, MethodContext mc) { @@ -827,6 +892,7 @@ public class JDTJava2CAstTranslator { fType = type; fReturnType = returnType; fModifiers = modifiers; + this.annotations = annotations; // from CodeBodyEntity fEntities = new LinkedHashMap>(); @@ -866,7 +932,12 @@ public class JDTJava2CAstTranslator { } } - public String toString() { + @Override + public Collection getAnnotations() { + return annotations; + } + + public String toString() { return fDecl == null ? "" : fDecl.toString(); } @@ -1034,15 +1105,24 @@ public class JDTJava2CAstTranslator { private final JdtPosition position; - private FieldEntity(String name, ITypeBinding type, Collection quals, JdtPosition position) { + private final Set annotations; + + private FieldEntity(String name, ITypeBinding type, Collection quals, JdtPosition position, Set annotations) { super(); this.type = type; this.quals = quals; this.name = name; this.position = position; + this.annotations = annotations; } - public int getKind() { + + @Override + public Collection getAnnotations() { + return annotations; + } + + public int getKind() { return CAstEntity.FIELD_ENTITY; } @@ -2821,7 +2901,12 @@ public class JDTJava2CAstTranslator { fTopLevelDecls = topLevelDecls; } - public int getKind() { + @Override + public Collection getAnnotations() { + return null; + } + + public int getKind() { return FILE_ENTITY; } @@ -3171,7 +3256,7 @@ public class JDTJava2CAstTranslator { */ private CAstEntity visit(EnumConstantDeclaration decl, WalkContext context) { return new FieldEntity(decl.getName().getIdentifier(), decl.resolveVariable().getType(), enumQuals, makePosition(decl - .getStartPosition(), decl.getStartPosition() + decl.getLength())); + .getStartPosition(), decl.getStartPosition() + decl.getLength()), null); } /** @@ -3248,7 +3333,7 @@ public class JDTJava2CAstTranslator { ArrayList paramTypes = new ArrayList(1); paramTypes.add(fTypeDict.getCAstTypeFor(ast.resolveWellKnownType("java.lang.String"))); - return new ProcedureEntity(bodyNode, fakeMet, enumType, memberEntities, context, paramTypes, enumType, met.getModifiers()); + return new ProcedureEntity(bodyNode, fakeMet, enumType, memberEntities, context, paramTypes, enumType, met.getModifiers(), handleAnnotations(met)); } private CAstEntity createEnumValuesMethod(ITypeBinding enumType, ArrayList constants, WalkContext oldContext) { @@ -3281,7 +3366,7 @@ public class JDTJava2CAstTranslator { ArrayList paramTypes = new ArrayList(0); return new ProcedureEntity(bodyNode, fakeMet, enumType, memberEntities, context, paramTypes, enumType.createArrayType(1), met - .getModifiers()); + .getModifiers(), handleAnnotations(enumType)); } private void doEnumHiddenEntities(ITypeBinding typeBinding, ArrayList staticInits, List memberEntities, @@ -3431,7 +3516,7 @@ public class JDTJava2CAstTranslator { // finally, make the procedure entity CAstNode ast = makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, bodyNodes); - return new ProcedureEntity(ast, fakeCtor, newType, memberEntities, context, paramTypes, null); + return new ProcedureEntity(ast, fakeCtor, newType, memberEntities, context, paramTypes, null, handleAnnotations(ctor)); } diff --git a/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTSourceModuleTranslator.java b/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTSourceModuleTranslator.java index 39538b78d..275e1f82f 100644 --- a/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTSourceModuleTranslator.java +++ b/com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/JDTSourceModuleTranslator.java @@ -117,8 +117,6 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator { // TODO: we might need one AST (-> "Object" class) for all files. // TODO: group by project and send 'em in - System.out.println(modules); - // sort files into projects Map> projectsFiles = new HashMap>(); for (ModuleEntry m : modules) { @@ -131,12 +129,12 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator { projectsFiles.get(proj).put(JavaCore.createCompilationUnitFrom(entry.getIFile()), entry); } - final ASTParser parser = ASTParser.newParser(AST.JLS3); + final ASTParser parser = ASTParser.newParser(AST.JLS4); for (final Map.Entry> proj : projectsFiles.entrySet()) { parser.setProject(JavaCore.create(proj.getKey())); parser.setResolveBindings(true); - + Set units = proj.getValue().keySet(); parser.createASTs(units.toArray(new ICompilationUnit[units.size()]), new String[0], new ASTRequestor() { public void acceptAST(ICompilationUnit source, CompilationUnit ast) {