package soot.JastAddJ;
import java.util.HashSet;import java.util.LinkedHashSet;import java.io.File;import java.util.*;import beaver.*;import java.util.ArrayList;import java.util.zip.*;import java.io.*;import java.io.FileNotFoundException;import java.util.Collection;import soot.*;import soot.util.*;import soot.jimple.*;import soot.coffi.ClassFile;import soot.coffi.method_info;import soot.coffi.CONSTANT_Utf8_info;import soot.tagkit.SourceFileTag;import soot.coffi.CoffiMethodSource;
// 9.7 Annotations
public class Annotation extends Modifier implements Cloneable {
public void flushCache() {
super.flushCache();
decl_computed = false;
decl_value = null;
}
public void flushCollectionCache() {
super.flushCollectionCache();
}
@SuppressWarnings({"unchecked", "cast"}) public Annotation clone() throws CloneNotSupportedException {
Annotation node = (Annotation)super.clone();
node.decl_computed = false;
node.decl_value = null;
node.in$Circle(false);
node.is$Final(false);
return node;
}
@SuppressWarnings({"unchecked", "cast"}) public Annotation copy() {
try {
Annotation node = (Annotation)clone();
if(children != null) node.children = (ASTNode[])children.clone();
return node;
} catch (CloneNotSupportedException e) {
}
System.err.println("Error: Could not clone node of type " + getClass().getName() + "!");
return null;
}
@SuppressWarnings({"unchecked", "cast"}) public Annotation fullCopy() {
Annotation res = (Annotation)copy();
for(int i = 0; i < getNumChildNoTransform(); i++) {
ASTNode node = getChildNoTransform(i);
if(node != null) node = node.fullCopy();
res.setChild(node, i);
}
return res;
}
// Declared in Annotations.jrag at line 41
// 9.6 Annotation Types
/* The Identifier in an annotation type declaration specifies the name of the
annotation type. A compile-time error occurs if an annotation type has the same
simple name as any of its enclosing classes or interfaces.
Comment: This is common for all type declarations and need thus no specific
implementation. */
// 9.6.1.1
/* If an annotation a on an annotation declaration corresponds to an
annotation type T, and T has a (meta-)annotation m that corresponds to
annotation.Target, then m must have either an element whose matches the
annotated declaration, or a compile-time error occurs.*/
public void checkModifiers() {
super.checkModifiers();
if(decl() instanceof AnnotationDecl) {
AnnotationDecl T = (AnnotationDecl)decl();
Annotation m = T.annotation(lookupType("java.lang.annotation", "Target"));
if(m != null && m.getNumElementValuePair() == 1 && m.getElementValuePair(0).getName().equals("value")) {
ElementValue v = m.getElementValuePair(0).getElementValue();
//System.out.println("ElementValue: \n" + v.dumpTree());
//System.out.println("Annotation: \n" + dumpTree());
if(!v.validTarget(this))
error("annotation type " + T.typeName() + " is not applicable to this kind of declaration");
}
}
}
// Declared in Annotations.jrag at line 241
// 9.6.1.4 Override
public void checkOverride() {
if(decl().fullName().equals("java.lang.Override") && enclosingBodyDecl() instanceof MethodDecl) {
MethodDecl m = (MethodDecl)enclosingBodyDecl();
if(!m.hostType().isClassDecl())
error("override annotation not valid for interface methods");
else {
boolean found = false;
for(Iterator iter = m.hostType().ancestorMethods(m.signature()).iterator(); iter.hasNext(); ) {
MethodDecl decl = (MethodDecl)iter.next();
if(m.overrides(decl) && decl.hostType().isClassDecl())
found = true;
}
if(!found)
error("method does not override a method from its superclass");
}
}
}
// Declared in Annotations.jrag at line 383
// 9.7 Annotations
public void typeCheck() {
if(!decl().isAnnotationDecl()) {
/* TypeName names the annotation type corresponding to the annotation. It is a
compile-time error if TypeName does not name an annotation type.*/
if(!decl().isUnknown())
error(decl().typeName() + " is not an annotation type");
} else {
TypeDecl typeDecl = decl();
/* It is a compile-time error if a declaration is annotated with more than one
annotation for a given annotation type.*/
if(lookupAnnotation(typeDecl) != this)
error("duplicate annotation " + typeDecl.typeName());
/* Annotations must contain an element-value pair for every element of the
corresponding annotation type, except for those elements with default
values, or a compile-time error occurs. Annotations may, but are not
required to, contain element-value pairs for elements with default values.*/
for(int i = 0; i < typeDecl.getNumBodyDecl(); i++) {
if(typeDecl.getBodyDecl(i) instanceof MethodDecl) {
MethodDecl decl = (MethodDecl)typeDecl.getBodyDecl(i);
if(elementValueFor(decl.name()) == null && (!(decl instanceof AnnotationMethodDecl) || !((AnnotationMethodDecl)decl).hasDefaultValue()))
error("missing value for " + decl.name());
}
}
/* The Identifier in an ElementValuePair must be the simple name of one of the
elements of the annotation type identified by TypeName in the containing
annotation. Otherwise, a compile-time error occurs. (In other words, the
identifier in an element-value pair must also be a method name in the interface
identified by TypeName.) */
for(int i = 0; i < getNumElementValuePair(); i++) {
ElementValuePair pair = getElementValuePair(i);
if(typeDecl.memberMethods(pair.getName()).isEmpty())
error("can not find element named " + pair.getName() + " in " + typeDecl.typeName());
}
}
checkOverride();
}
// Declared in Annotations.jrag at line 578
public void toString(StringBuffer s) {
s.append("@");
getAccess().toString(s);
s.append("(");
for(int i = 0; i < getNumElementValuePair(); i++) {
if(i != 0)
s.append(", ");
getElementValuePair(i).toString(s);
}
s.append(")");
}
// Declared in AnnotationsCodegen.jrag at line 305
// 4.8.15
public void appendAsAttributeTo(Collection list) {
soot.tagkit.AnnotationTag tag = new soot.tagkit.AnnotationTag(decl().typeDescriptor(), getNumElementValuePair());
ArrayList elements = new ArrayList(getNumElementValuePair());
for(int i = 0; i < getNumElementValuePair(); i++) {
String name = getElementValuePair(i).getName();
ElementValue value = getElementValuePair(i).getElementValue();
value.appendAsAttributeTo(elements, name);
}
tag.setElems(elements);
list.add(tag);
}
// Declared in Annotations.ast at line 3
// Declared in Annotations.ast line 6
public Annotation() {
super();
setChild(new List(), 1);
}
// Declared in Annotations.ast at line 11
// Declared in Annotations.ast line 6
public Annotation(String p0, Access p1, List<ElementValuePair> p2) {
setID(p0);
setChild(p1, 0);
setChild(p2, 1);
}
// Declared in Annotations.ast at line 18
// Declared in Annotations.ast line 6
public Annotation(beaver.Symbol p0, Access p1, List<ElementValuePair> p2) {
setID(p0);
setChild(p1, 0);
setChild(p2, 1);
}
// Declared in Annotations.ast at line 24
protected int numChildren() {
return 2;
}
// Declared in Annotations.ast at line 27
public boolean mayHaveRewrite() {
return false;
}
// Declared in Annotations.ast at line 2
// Declared in Annotations.ast line 6
public void setID(String value) {
tokenString_ID = value;
}
// Declared in Annotations.ast at line 5
public void setID(beaver.Symbol symbol) {
if(symbol.value != null && !(symbol.value instanceof String))
throw new UnsupportedOperationException("setID is only valid for String lexemes");
tokenString_ID = (String)symbol.value;
IDstart = symbol.getStart();
IDend = symbol.getEnd();
}
// Declared in Annotations.ast at line 12
public String getID() {
return tokenString_ID != null ? tokenString_ID : "";
}
// Declared in Annotations.ast at line 2
// Declared in Annotations.ast line 6
public void setAccess(Access node) {
setChild(node, 0);
}
// Declared in Annotations.ast at line 5
public Access getAccess() {
return (Access)getChild(0);
}
// Declared in Annotations.ast at line 9
public Access getAccessNoTransform() {
return (Access)getChildNoTransform(0);
}
// Declared in Annotations.ast at line 2
// Declared in Annotations.ast line 6
public void setElementValuePairList(List<ElementValuePair> list) {
setChild(list, 1);
}
// Declared in Annotations.ast at line 6
public int getNumElementValuePair() {
return getElementValuePairList().getNumChild();
}
// Declared in Annotations.ast at line 10
@SuppressWarnings({"unchecked", "cast"}) public ElementValuePair getElementValuePair(int i) {
return (ElementValuePair)getElementValuePairList().getChild(i);
}
// Declared in Annotations.ast at line 14
public void addElementValuePair(ElementValuePair node) {
List<ElementValuePair> list = (parent == null || state == null) ? getElementValuePairListNoTransform() : getElementValuePairList();
list.addChild(node);
}
// Declared in Annotations.ast at line 19
public void addElementValuePairNoTransform(ElementValuePair node) {
List<ElementValuePair> list = getElementValuePairListNoTransform();
list.addChild(node);
}
// Declared in Annotations.ast at line 24
public void setElementValuePair(ElementValuePair node, int i) {
List<ElementValuePair> list = getElementValuePairList();
list.setChild(node, i);
}
// Declared in Annotations.ast at line 28
public List<ElementValuePair> getElementValuePairs() {
return getElementValuePairList();
}
// Declared in Annotations.ast at line 31
public List<ElementValuePair> getElementValuePairsNoTransform() {
return getElementValuePairListNoTransform();
}
// Declared in Annotations.ast at line 35
@SuppressWarnings({"unchecked", "cast"}) public List<ElementValuePair> getElementValuePairList() {
List<ElementValuePair> list = (List<ElementValuePair>)getChild(1);
list.getNumChild();
return list;
}
// Declared in Annotations.ast at line 41
@SuppressWarnings({"unchecked", "cast"}) public List<ElementValuePair> getElementValuePairListNoTransform() {
return (List<ElementValuePair>)getChildNoTransform(1);
}
protected boolean decl_computed = false;
protected TypeDecl decl_value;
// Declared in Annotations.jrag at line 420
@SuppressWarnings({"unchecked", "cast"}) public TypeDecl decl() {
if(decl_computed) {
return decl_value;
}
ASTNode$State state = state();
int num = state.boundariesCrossed;
boolean isFinal = this.is$Final();
decl_value = decl_compute();
if(isFinal && num == state().boundariesCrossed)
decl_computed = true;
return decl_value;
}
private TypeDecl decl_compute() { return getAccess().type(); }
// Declared in Annotations.jrag at line 432
@SuppressWarnings({"unchecked", "cast"}) public ElementValue elementValueFor(String name) {
ASTNode$State state = state();
ElementValue elementValueFor_String_value = elementValueFor_compute(name);
return elementValueFor_String_value;
}
private ElementValue elementValueFor_compute(String name) {
for(int i = 0; i < getNumElementValuePair(); i++) {
ElementValuePair pair = getElementValuePair(i);
if(pair.getName().equals(name))
return pair.getElementValue();
}
return null;
}
// Declared in Annotations.jrag at line 510
@SuppressWarnings({"unchecked", "cast"}) public TypeDecl type() {
ASTNode$State state = state();
TypeDecl type_value = type_compute();
return type_value;
}
private TypeDecl type_compute() { return getAccess().type(); }
// Declared in Annotations.jrag at line 539
@SuppressWarnings({"unchecked", "cast"}) public boolean isMetaAnnotation() {
ASTNode$State state = state();
boolean isMetaAnnotation_value = isMetaAnnotation_compute();
return isMetaAnnotation_value;
}
private boolean isMetaAnnotation_compute() { return hostType().isAnnotationDecl(); }
// Declared in AnnotationsCodegen.jrag at line 144
@SuppressWarnings({"unchecked", "cast"}) public boolean isRuntimeVisible() {
ASTNode$State state = state();
boolean isRuntimeVisible_value = isRuntimeVisible_compute();
return isRuntimeVisible_value;
}
private boolean isRuntimeVisible_compute() {
Annotation a = decl().annotation(lookupType("java.lang.annotation", "Retention"));
if(a == null) return false;
ElementConstantValue value = (ElementConstantValue)a.getElementValuePair(0).getElementValue();
Variable v = value.getExpr().varDecl();
return v != null && v.name().equals("RUNTIME");
}
// Declared in AnnotationsCodegen.jrag at line 154
@SuppressWarnings({"unchecked", "cast"}) public boolean isRuntimeInvisible() {
ASTNode$State state = state();
boolean isRuntimeInvisible_value = isRuntimeInvisible_compute();
return isRuntimeInvisible_value;
}
private boolean isRuntimeInvisible_compute() {
Annotation a = decl().annotation(lookupType("java.lang.annotation", "Retention"));
if(a == null) return true; // default bahavior if not annotated
ElementConstantValue value = (ElementConstantValue)a.getElementValuePair(0).getElementValue();
Variable v = value.getExpr().varDecl();
return v != null && v.name().equals("CLASS");
}
// Declared in Annotations.jrag at line 55
@SuppressWarnings({"unchecked", "cast"}) public TypeDecl lookupType(String packageName, String typeName) {
ASTNode$State state = state();
TypeDecl lookupType_String_String_value = getParent().Define_TypeDecl_lookupType(this, null, packageName, typeName);
return lookupType_String_String_value;
}
// Declared in Annotations.jrag at line 69
@SuppressWarnings({"unchecked", "cast"}) public boolean mayUseAnnotationTarget(String name) {
ASTNode$State state = state();
boolean mayUseAnnotationTarget_String_value = getParent().Define_boolean_mayUseAnnotationTarget(this, null, name);
return mayUseAnnotationTarget_String_value;
}
// Declared in Annotations.jrag at line 258
@SuppressWarnings({"unchecked", "cast"}) public BodyDecl enclosingBodyDecl() {
ASTNode$State state = state();
BodyDecl enclosingBodyDecl_value = getParent().Define_BodyDecl_enclosingBodyDecl(this, null);
return enclosingBodyDecl_value;
}
// Declared in Annotations.jrag at line 422
@SuppressWarnings({"unchecked", "cast"}) public Annotation lookupAnnotation(TypeDecl typeDecl) {
ASTNode$State state = state();
Annotation lookupAnnotation_TypeDecl_value = getParent().Define_Annotation_lookupAnnotation(this, null, typeDecl);
return lookupAnnotation_TypeDecl_value;
}
// Declared in Annotations.jrag at line 540
@SuppressWarnings({"unchecked", "cast"}) public TypeDecl hostType() {
ASTNode$State state = state();
TypeDecl hostType_value = getParent().Define_TypeDecl_hostType(this, null);
return hostType_value;
}
// Declared in Annotations.jrag at line 460
public TypeDecl Define_TypeDecl_enclosingAnnotationDecl(ASTNode caller, ASTNode child) {
if(caller == getElementValuePairListNoTransform()) {
int childIndex = caller.getIndexOfChild(child);
return decl();
}
return getParent().Define_TypeDecl_enclosingAnnotationDecl(this, caller);
}
// Declared in Annotations.jrag at line 545
public NameType Define_NameType_nameType(ASTNode caller, ASTNode child) {
if(caller == getAccessNoTransform()) {
return NameType.TYPE_NAME;
}
return getParent().Define_NameType_nameType(this, caller);
}
public ASTNode rewriteTo() {
return super.rewriteTo();
}
}