Search in sources :

Example 1 with AnnotationStringElem

use of soot.tagkit.AnnotationStringElem in project robovm by robovm.

the class ObjCMemberPlugin method addTypeEncodingAnnotation.

static void addTypeEncodingAnnotation(SootMethod method, String encoding) {
    AnnotationTag annotationTag = new AnnotationTag(TYPE_ENCODING, 1);
    annotationTag.addElem(new AnnotationStringElem(encoding, 's', "value"));
    addRuntimeVisibleAnnotation(method, annotationTag);
}
Also used : AnnotationStringElem(soot.tagkit.AnnotationStringElem) AnnotationTag(soot.tagkit.AnnotationTag)

Example 2 with AnnotationStringElem

use of soot.tagkit.AnnotationStringElem 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;
}
Also used : AnnotationStringElem(soot.tagkit.AnnotationStringElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) ArrayList(java.util.ArrayList) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) AnnotationFloatElem(soot.tagkit.AnnotationFloatElem) AnnotationElem(soot.tagkit.AnnotationElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) AnnotationLongElem(soot.tagkit.AnnotationLongElem) AnnotationArrayElem(soot.tagkit.AnnotationArrayElem) AnnotationEnumElem(soot.tagkit.AnnotationEnumElem) AnnotationDoubleElem(soot.tagkit.AnnotationDoubleElem) AnnotationIntElem(soot.tagkit.AnnotationIntElem) AnnotationClassElem(soot.tagkit.AnnotationClassElem)

Example 3 with AnnotationStringElem

use of soot.tagkit.AnnotationStringElem 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;
}
Also used : AnnotationStringElem(soot.tagkit.AnnotationStringElem) DeprecatedTag(soot.tagkit.DeprecatedTag) ArrayList(java.util.ArrayList) AnnotationArrayElem(soot.tagkit.AnnotationArrayElem) Annotation(org.jf.dexlib2.iface.Annotation) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) InnerClassTag(soot.tagkit.InnerClassTag) RefType(soot.RefType) Type(soot.Type) ArrayType(soot.ArrayType) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) AnnotationIntElem(soot.tagkit.AnnotationIntElem) AnnotationElement(org.jf.dexlib2.iface.AnnotationElement) AnnotationClassElem(soot.tagkit.AnnotationClassElem) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) SignatureTag(soot.tagkit.SignatureTag) Tag(soot.tagkit.Tag) ParamNamesTag(soot.tagkit.ParamNamesTag) DeprecatedTag(soot.tagkit.DeprecatedTag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) InnerClassTag(soot.tagkit.InnerClassTag) SignatureTag(soot.tagkit.SignatureTag) AnnotationTag(soot.tagkit.AnnotationTag) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) AnnotationElem(soot.tagkit.AnnotationElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem)

Example 4 with AnnotationStringElem

use of soot.tagkit.AnnotationStringElem 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();
    }
}
Also used : AnnotationStringElem(soot.tagkit.AnnotationStringElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) AnnotationBooleanElem(soot.tagkit.AnnotationBooleanElem) AnnotationArrayElem(soot.tagkit.AnnotationArrayElem) AnnotationLongElem(soot.tagkit.AnnotationLongElem) AnnotationEnumElem(soot.tagkit.AnnotationEnumElem) AnnotationDoubleElem(soot.tagkit.AnnotationDoubleElem) AnnotationIntElem(soot.tagkit.AnnotationIntElem) AnnotationFloatElem(soot.tagkit.AnnotationFloatElem) AnnotationClassElem(soot.tagkit.AnnotationClassElem) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) AnnotationElem(soot.tagkit.AnnotationElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem)

Example 5 with AnnotationStringElem

use of soot.tagkit.AnnotationStringElem in project robovm by robovm.

the class ObjCMemberPlugin method addNotImplementedAnnotation.

static void addNotImplementedAnnotation(SootMethod method, String selectorName) {
    AnnotationTag annotationTag = new AnnotationTag(NOT_IMPLEMENTED, 1);
    annotationTag.addElem(new AnnotationStringElem(selectorName, 's', "value"));
    addRuntimeVisibleAnnotation(method, annotationTag);
}
Also used : AnnotationStringElem(soot.tagkit.AnnotationStringElem) AnnotationTag(soot.tagkit.AnnotationTag)

Aggregations

AnnotationStringElem (soot.tagkit.AnnotationStringElem)10 AnnotationAnnotationElem (soot.tagkit.AnnotationAnnotationElem)7 AnnotationArrayElem (soot.tagkit.AnnotationArrayElem)7 AnnotationTag (soot.tagkit.AnnotationTag)7 AnnotationClassElem (soot.tagkit.AnnotationClassElem)6 AnnotationElem (soot.tagkit.AnnotationElem)6 AnnotationIntElem (soot.tagkit.AnnotationIntElem)6 ArrayList (java.util.ArrayList)5 AnnotationDoubleElem (soot.tagkit.AnnotationDoubleElem)5 AnnotationFloatElem (soot.tagkit.AnnotationFloatElem)5 AnnotationLongElem (soot.tagkit.AnnotationLongElem)5 AnnotationEnumElem (soot.tagkit.AnnotationEnumElem)4 VisibilityAnnotationTag (soot.tagkit.VisibilityAnnotationTag)4 VisibilityParameterAnnotationTag (soot.tagkit.VisibilityParameterAnnotationTag)4 AnnotationElement (org.jf.dexlib2.iface.AnnotationElement)2 List (java.util.List)1 Annotation (org.jf.dexlib2.iface.Annotation)1 MethodParameter (org.jf.dexlib2.iface.MethodParameter)1 FieldReference (org.jf.dexlib2.iface.reference.FieldReference)1 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)1