use of soot.tagkit.AnnotationArrayElem in project robovm by robovm.
the class Bro method getArrayDimensions.
public static int[] getArrayDimensions(SootMethod method, int paramIndex) {
AnnotationTag annotation = paramIndex == -1 ? getArrayAnnotation(method) : getArrayAnnotation(method, paramIndex);
if (annotation == null) {
return null;
}
ArrayList<AnnotationElem> values = ((AnnotationArrayElem) annotation.getElemAt(0)).getValues();
int[] dims = new int[values.size()];
for (int i = 0; i < dims.length; i++) {
dims[i] = ((AnnotationIntElem) values.get(i)).getValue();
}
return dims;
}
use of soot.tagkit.AnnotationArrayElem in project robovm by robovm.
the class Annotations method getMarshalerAnnotations.
public static List<AnnotationTag> getMarshalerAnnotations(SootClass clazz) {
List<AnnotationTag> tags = new ArrayList<AnnotationTag>();
AnnotationTag marshaler = getAnnotation(clazz, MARSHALER);
if (marshaler != null) {
tags.add(marshaler);
} else {
AnnotationTag marshalers = getAnnotation(clazz, MARSHALERS);
if (marshalers != null) {
for (AnnotationElem e : ((AnnotationArrayElem) marshalers.getElemAt(0)).getValues()) {
AnnotationAnnotationElem elem = (AnnotationAnnotationElem) e;
tags.add(elem.getValue());
}
}
}
return tags;
}
use of soot.tagkit.AnnotationArrayElem in project soot by Sable.
the class Util method createElementTags.
private ArrayList<AnnotationElem> createElementTags(int count, ClassFile coffiClass, element_value[] elems) {
ArrayList<AnnotationElem> list = new ArrayList<AnnotationElem>();
for (int j = 0; j < count; j++) {
element_value ev = elems[j];
char kind = ev.tag;
String elemName = "default";
if (ev.name_index != 0) {
elemName = ((CONSTANT_Utf8_info) coffiClass.constant_pool[ev.name_index]).convert();
}
if (kind == 'B' || kind == 'C' || kind == 'I' || kind == 'S' || kind == 'Z' || kind == 'D' || kind == 'F' || kind == 'J' || kind == 's') {
constant_element_value cev = (constant_element_value) ev;
if (kind == 'B' || kind == 'C' || kind == 'I' || kind == 'S' || kind == 'Z') {
cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
int constant_val = (int) ((CONSTANT_Integer_info) cval).bytes;
AnnotationIntElem elem = new AnnotationIntElem(constant_val, kind, elemName);
list.add(elem);
} else if (kind == 'D') {
cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
double constant_val = ((CONSTANT_Double_info) cval).convert();
AnnotationDoubleElem elem = new AnnotationDoubleElem(constant_val, kind, elemName);
list.add(elem);
} else if (kind == 'F') {
cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
float constant_val = ((CONSTANT_Float_info) cval).convert();
AnnotationFloatElem elem = new AnnotationFloatElem(constant_val, kind, elemName);
list.add(elem);
} else if (kind == 'J') {
cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
CONSTANT_Long_info lcval = (CONSTANT_Long_info) cval;
long constant_val = (lcval.high << 32) + lcval.low;
AnnotationLongElem elem = new AnnotationLongElem(constant_val, kind, elemName);
list.add(elem);
} else if (kind == 's') {
cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
String constant_val = ((CONSTANT_Utf8_info) cval).convert();
AnnotationStringElem elem = new AnnotationStringElem(constant_val, kind, elemName);
list.add(elem);
}
} else if (kind == 'e') {
enum_constant_element_value ecev = (enum_constant_element_value) ev;
cp_info type_val = coffiClass.constant_pool[ecev.type_name_index];
String type_name = ((CONSTANT_Utf8_info) type_val).convert();
cp_info name_val = coffiClass.constant_pool[ecev.constant_name_index];
String constant_name = ((CONSTANT_Utf8_info) name_val).convert();
AnnotationEnumElem elem = new AnnotationEnumElem(type_name, constant_name, kind, elemName);
list.add(elem);
} else if (kind == 'c') {
class_element_value cev = (class_element_value) ev;
cp_info cval = coffiClass.constant_pool[cev.class_info_index];
CONSTANT_Utf8_info sval = (CONSTANT_Utf8_info) cval;
String desc = sval.convert();
AnnotationClassElem elem = new AnnotationClassElem(desc, kind, elemName);
list.add(elem);
} else if (kind == '[') {
array_element_value aev = (array_element_value) ev;
int num_vals = aev.num_values;
ArrayList<AnnotationElem> elemVals = createElementTags(num_vals, coffiClass, aev.values);
AnnotationArrayElem elem = new AnnotationArrayElem(elemVals, kind, elemName);
list.add(elem);
} else if (kind == '@') {
annotation_element_value aev = (annotation_element_value) ev;
annotation annot = aev.annotation_value;
String annotType = ((CONSTANT_Utf8_info) coffiClass.constant_pool[annot.type_index]).convert();
AnnotationTag annotTag = new AnnotationTag(annotType, createElementTags(annot.num_element_value_pairs, coffiClass, annot.element_value_pairs));
AnnotationAnnotationElem elem = new AnnotationAnnotationElem(annotTag, kind, elemName);
list.add(elem);
}
}
return list;
}
use of soot.tagkit.AnnotationArrayElem in project soot by Sable.
the class DexAnnotation method handleAnnotation.
/**
* @param annotations
* @return
*/
private List<Tag> handleAnnotation(Set<? extends org.jf.dexlib2.iface.Annotation> annotations, String classType) {
if (annotations == null || annotations.size() == 0)
return null;
List<Tag> tags = new ArrayList<Tag>();
// RUNTIME_VISIBLE,
VisibilityAnnotationTag[] vatg = new VisibilityAnnotationTag[3];
for (Annotation a : annotations) {
int v = getVisibility(a.getVisibility());
Tag t = null;
Type atype = DexType.toSoot(a.getType());
String atypes = atype.toString();
int eSize = a.getElements().size();
if (atypes.equals("dalvik.annotation.AnnotationDefault")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation Default. Got " + eSize + " instead.");
// get element
AnnotationElem e = getElements(a.getElements()).get(0);
AnnotationTag adt = new AnnotationTag(a.getType());
adt.addElem(e);
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
vatg[v].addAnnotation(adt);
} else if (atypes.equals("dalvik.annotation.EnclosingClass")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation EnclosingClass. Got " + eSize + " instead.");
for (AnnotationElement elem : a.getElements()) {
String outerClass = ((TypeEncodedValue) elem.getValue()).getValue();
outerClass = Util.dottedClassName(outerClass);
// repair it
if (outerClass.equals(clazz.getName())) {
if (outerClass.contains("$-")) {
/*
* This is a special case for generated lambda
* classes of jack and jill compiler. Generated
* lambda classes may contain '$' which do not
* indicate an inner/outer class separator if the
* '$' occurs after a inner class with a name
* starting with '-'. Thus we search for '$-' and
* anything after it including '-' is the inner
* classes name and anything before it is the outer
* classes name.
*/
outerClass = outerClass.substring(0, outerClass.indexOf("$-"));
} else if (outerClass.contains("$")) {
// remove everything after the last '$' including
// the last '$'
outerClass = outerClass.substring(0, outerClass.lastIndexOf("$"));
}
}
deps.typesToSignature.add(RefType.v(outerClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(outerClass));
assert clazz.getOuterClass() != clazz;
}
// annotation.
continue;
} else if (atypes.equals("dalvik.annotation.EnclosingMethod")) {
// ignore the annotation
if (eSize == 0)
continue;
// If the pointer is ambiguous, we are in trouble
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation EnclosingMethod. Got " + eSize + " instead.");
AnnotationStringElem e = (AnnotationStringElem) getElements(a.getElements()).get(0);
String[] split1 = e.getValue().split("\\ \\|");
String classString = split1[0];
String methodString = split1[1];
String parameters = split1[2];
String returnType = split1[3];
String methodSigString = "(" + parameters + ")" + returnType;
t = new EnclosingMethodTag(classString, methodString, methodSigString);
String outerClass = classString.replace("/", ".");
deps.typesToSignature.add(RefType.v(outerClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(outerClass));
assert clazz.getOuterClass() != clazz;
} else if (atypes.equals("dalvik.annotation.InnerClass")) {
// access flags of the inner class
int accessFlags = -1;
// name of the inner class
String name = null;
for (AnnotationElem ele : getElements(a.getElements())) {
if (ele instanceof AnnotationIntElem && ele.getName().equals("accessFlags"))
accessFlags = ((AnnotationIntElem) ele).getValue();
else if (ele instanceof AnnotationStringElem && ele.getName().equals("name"))
name = ((AnnotationStringElem) ele).getValue();
else
throw new RuntimeException("Unexpected inner class annotation element");
}
// outer class name
String outerClass;
if (clazz.hasOuterClass()) {
// If we have already set an outer class from some other
// annotation, we use that
// one.
outerClass = clazz.getOuterClass().getName();
} else if (classType.contains("$-")) {
/*
* This is a special case for generated lambda classes of
* jack and jill compiler. Generated lambda classes may
* contain '$' which do not indicate an inner/outer class
* separator if the '$' occurs after a inner class with a
* name starting with '-'. Thus we search for '$-' and
* anything after it including '-' is the inner classes name
* and anything before it is the outer classes name.
*/
outerClass = classType.substring(0, classType.indexOf("$-"));
if (Util.isByteCodeClassName(classType))
outerClass += ";";
} else if (classType.contains("$")) {
// remove everything after the last '$' including the last
// '$'
outerClass = classType.substring(0, classType.lastIndexOf("$")) + ";";
if (Util.isByteCodeClassName(classType))
outerClass += ";";
} else {
// Make sure that no funny business is going on if the
// annotation is broken and does not end in $nn.
outerClass = null;
}
Tag innerTag = new InnerClassTag(DexType.toSootICAT(classType), outerClass == null ? null : DexType.toSootICAT(outerClass), name, accessFlags);
tags.add(innerTag);
if (outerClass != null && !clazz.hasOuterClass()) {
String sootOuterClass = Util.dottedClassName(outerClass);
deps.typesToSignature.add(RefType.v(sootOuterClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(sootOuterClass));
assert clazz.getOuterClass() != clazz;
}
continue;
} else if (atypes.equals("dalvik.annotation.MemberClasses")) {
AnnotationArrayElem e = (AnnotationArrayElem) getElements(a.getElements()).get(0);
for (AnnotationElem ae : e.getValues()) {
AnnotationClassElem c = (AnnotationClassElem) ae;
String innerClass = c.getDesc();
String outerClass;
String name;
if (innerClass.contains("$-")) {
/*
* This is a special case for generated lambda classes
* of jack and jill compiler. Generated lambda classes
* may contain '$' which do not indicate an inner/outer
* class separator if the '$' occurs after a inner class
* with a name starting with '-'. Thus we search for
* '$-' and anything after it including '-' is the inner
* classes name and anything before it is the outer
* classes name.
*/
int i = innerClass.indexOf("$-");
outerClass = innerClass.substring(0, i);
name = innerClass.substring(i + 2).replaceAll(";$", "");
} else if (innerClass.contains("$")) {
// remove everything after the last '$' including the
// last '$'
int i = innerClass.lastIndexOf("$");
outerClass = innerClass.substring(0, i);
name = innerClass.substring(i + 1).replaceAll(";$", "");
} else {
// Make sure that no funny business is going on if the
// annotation is broken and does not end in $nn.
outerClass = null;
name = null;
}
if (// anonymous or
name != null && name.matches("^\\d*$"))
// local inner
// classes
name = null;
// seems like this information is lost
int accessFlags = 0;
// during the .class -- dx --> .dex
// process.
Tag innerTag = new InnerClassTag(DexType.toSootICAT(innerClass), outerClass == null ? null : DexType.toSootICAT(outerClass), name, accessFlags);
tags.add(innerTag);
}
continue;
} else if (atypes.equals("dalvik.annotation.Signature")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation Signature. Got " + eSize + " instead.");
AnnotationArrayElem e = (AnnotationArrayElem) getElements(a.getElements()).get(0);
String sig = "";
for (AnnotationElem ae : e.getValues()) {
AnnotationStringElem s = (AnnotationStringElem) ae;
sig += s.getValue();
}
t = new SignatureTag(sig);
} else if (atypes.equals("dalvik.annotation.Throws")) {
// this is handled in soot.dexpler.DexMethod
continue;
} else if (atypes.equals("java.lang.Deprecated")) {
if (eSize != 0)
throw new RuntimeException("error: expected 1 element for annotation Deprecated. Got " + eSize + " instead.");
t = new DeprecatedTag();
AnnotationTag adt = new AnnotationTag("Ljava/lang/Deprecated;");
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
vatg[v].addAnnotation(adt);
} else {
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
AnnotationTag tag = new AnnotationTag(a.getType());
for (AnnotationElem e : getElements(a.getElements())) tag.addElem(e);
vatg[v].addAnnotation(tag);
}
tags.add(t);
}
for (VisibilityAnnotationTag vat : vatg) if (vat != null)
tags.add(vat);
return tags;
}
use of soot.tagkit.AnnotationArrayElem in project soot by Sable.
the class AbstractASMBackend method generateAnnotationElems.
/**
* Emits the bytecode for the values of an annotation
* @param av The AnnotationVisitor to emit the bytecode to
* @param elements A collection of AnnatiotionElem that are the values of the annotation
* @param addName True, if the name of the annotation has to be added, false otherwise (should be false only in recursive calls!)
*/
protected void generateAnnotationElems(AnnotationVisitor av, Collection<AnnotationElem> elements, boolean addName) {
if (av != null) {
Iterator<AnnotationElem> it = elements.iterator();
while (it.hasNext()) {
AnnotationElem elem = it.next();
if (elem instanceof AnnotationEnumElem) {
AnnotationEnumElem enumElem = (AnnotationEnumElem) elem;
av.visitEnum(enumElem.getName(), enumElem.getTypeName(), enumElem.getConstantName());
} else if (elem instanceof AnnotationArrayElem) {
AnnotationArrayElem arrayElem = (AnnotationArrayElem) elem;
AnnotationVisitor arrayVisitor = av.visitArray(arrayElem.getName());
generateAnnotationElems(arrayVisitor, arrayElem.getValues(), false);
} else if (elem instanceof AnnotationAnnotationElem) {
AnnotationAnnotationElem aElem = (AnnotationAnnotationElem) elem;
AnnotationVisitor aVisitor = av.visitAnnotation(aElem.getName(), aElem.getValue().getType());
generateAnnotationElems(aVisitor, aElem.getValue().getElems(), true);
} else {
Object val = null;
if (elem instanceof AnnotationIntElem) {
AnnotationIntElem intElem = (AnnotationIntElem) elem;
int value = intElem.getValue();
switch(intElem.getKind()) {
case 'B':
val = (byte) value;
break;
case 'Z':
val = (value == 1);
break;
case 'I':
val = value;
break;
case 'S':
val = (short) value;
break;
}
} else if (elem instanceof AnnotationBooleanElem) {
AnnotationBooleanElem booleanElem = (AnnotationBooleanElem) elem;
val = booleanElem.getValue();
} else if (elem instanceof AnnotationFloatElem) {
AnnotationFloatElem floatElem = (AnnotationFloatElem) elem;
val = floatElem.getValue();
} else if (elem instanceof AnnotationLongElem) {
AnnotationLongElem longElem = (AnnotationLongElem) elem;
val = longElem.getValue();
} else if (elem instanceof AnnotationDoubleElem) {
AnnotationDoubleElem doubleElem = (AnnotationDoubleElem) elem;
val = doubleElem.getValue();
} else if (elem instanceof AnnotationStringElem) {
AnnotationStringElem stringElem = (AnnotationStringElem) elem;
val = stringElem.getValue();
} else if (elem instanceof AnnotationClassElem) {
AnnotationClassElem classElem = (AnnotationClassElem) elem;
val = org.objectweb.asm.Type.getType(classElem.getDesc());
}
if (addName) {
av.visit(elem.getName(), val);
} else {
av.visit(null, val);
}
}
}
av.visitEnd();
}
}
Aggregations