Search in sources :

Example 36 with AnnotationTag

use of soot.tagkit.AnnotationTag in project soot by Sable.

the class DexAnnotation method handleMethodAnnotation.

/**
 * Converts method and method parameters annotations from Dexlib to Jimple
 *
 * @param h
 * @param method
 */
public void handleMethodAnnotation(Host h, Method method) {
    Set<? extends Annotation> aSet = method.getAnnotations();
    if (!(aSet == null || aSet.isEmpty())) {
        List<Tag> tags = handleAnnotation(aSet, null);
        if (tags != null)
            for (Tag t : tags) if (t != null) {
                h.addTag(t);
            }
    }
    String[] parameterNames = null;
    int i = 0;
    for (MethodParameter p : method.getParameters()) {
        String name = p.getName();
        if (name != null) {
            parameterNames = new String[method.getParameters().size()];
            parameterNames[i] = name;
        }
        i++;
    }
    if (parameterNames != null) {
        h.addTag(new ParamNamesTag(parameterNames));
    }
    // Is there any parameter annotation?
    boolean doParam = false;
    List<? extends MethodParameter> parameters = method.getParameters();
    for (MethodParameter p : parameters) {
        if (p.getAnnotations().size() > 0) {
            doParam = true;
            break;
        }
    }
    if (doParam) {
        VisibilityParameterAnnotationTag tag = new VisibilityParameterAnnotationTag(parameters.size(), AnnotationConstants.RUNTIME_VISIBLE);
        for (MethodParameter p : parameters) {
            List<Tag> tags = handleAnnotation(p.getAnnotations(), null);
            // so that we keep the order intact.
            if (tags == null) {
                tag.addVisibilityAnnotation(null);
                continue;
            }
            VisibilityAnnotationTag paramVat = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_VISIBLE);
            tag.addVisibilityAnnotation(paramVat);
            for (Tag t : tags) {
                if (t == null)
                    continue;
                AnnotationTag vat = null;
                if (!(t instanceof VisibilityAnnotationTag)) {
                    if (t instanceof DeprecatedTag) {
                        vat = new AnnotationTag("Ljava/lang/Deprecated;");
                    } else if (t instanceof SignatureTag) {
                        SignatureTag sig = (SignatureTag) t;
                        ArrayList<AnnotationElem> sigElements = new ArrayList<AnnotationElem>();
                        for (String s : SootToDexUtils.splitSignature(sig.getSignature())) sigElements.add(new AnnotationStringElem(s, 's', "value"));
                        AnnotationElem elem = new AnnotationArrayElem(sigElements, '[', "value");
                        vat = new AnnotationTag("Ldalvik/annotation/Signature;", Collections.singleton(elem));
                    } else {
                        throw new RuntimeException("error: unhandled tag for parameter annotation in method " + h + " (" + t + ").");
                    }
                } else {
                    vat = ((VisibilityAnnotationTag) t).getAnnotations().get(0);
                }
                paramVat.addAnnotation(vat);
            }
        }
        if (tag.getVisibilityAnnotations().size() > 0)
            h.addTag(tag);
    }
}
Also used : DeprecatedTag(soot.tagkit.DeprecatedTag) AnnotationStringElem(soot.tagkit.AnnotationStringElem) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) ArrayList(java.util.ArrayList) AnnotationArrayElem(soot.tagkit.AnnotationArrayElem) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) ParamNamesTag(soot.tagkit.ParamNamesTag) 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) MethodParameter(org.jf.dexlib2.iface.MethodParameter) AnnotationElem(soot.tagkit.AnnotationElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem)

Example 37 with AnnotationTag

use of soot.tagkit.AnnotationTag in project soot by Sable.

the class DexAnnotation method handleClassAnnotation.

/**
 * Converts Class annotations from Dexlib to Jimple.
 *
 * @param h
 * @param classDef
 */
// .annotation "Ldalvik/annotation/AnnotationDefault;"
// .annotation "Ldalvik/annotation/EnclosingClass;"
// .annotation "Ldalvik/annotation/EnclosingMethod;"
// .annotation "Ldalvik/annotation/InnerClass;"
// .annotation "Ldalvik/annotation/MemberClasses;"
// .annotation "Ldalvik/annotation/Signature;"
// .annotation "Ldalvik/annotation/Throws;"
public void handleClassAnnotation(ClassDef classDef) {
    Set<? extends Annotation> aSet = classDef.getAnnotations();
    if (aSet == null || aSet.isEmpty())
        return;
    List<Tag> tags = handleAnnotation(aSet, classDef.getType());
    if (tags == null)
        return;
    InnerClassAttribute ica = null;
    for (Tag t : tags) if (t != null) {
        if (t instanceof InnerClassTag) {
            if (ica == null) {
                // Do we already have an InnerClassAttribute?
                ica = (InnerClassAttribute) clazz.getTag("InnerClassAttribute");
                // If not, create one
                if (ica == null) {
                    ica = new InnerClassAttribute();
                    clazz.addTag(ica);
                }
            }
            ica.add((InnerClassTag) t);
        } else if (t instanceof VisibilityAnnotationTag) {
            // If a dalvik/annotation/AnnotationDefault tag is present
            // in a class, its AnnotationElements must be propagated
            // to methods through the creation of new
            // AnnotationDefaultTag.
            VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t;
            for (AnnotationTag a : vt.getAnnotations()) {
                if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) {
                    for (AnnotationElem ae : a.getElems()) {
                        if (ae instanceof AnnotationAnnotationElem) {
                            AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae;
                            AnnotationTag at = aae.getValue();
                            // extract default elements
                            Map<String, AnnotationElem> defaults = new HashMap<String, AnnotationElem>();
                            for (AnnotationElem aelem : at.getElems()) {
                                defaults.put(aelem.getName(), aelem);
                            }
                            // and add tags on methods
                            for (SootMethod sm : clazz.getMethods()) {
                                String methodName = sm.getName();
                                if (defaults.containsKey(methodName)) {
                                    AnnotationElem e = defaults.get(methodName);
                                    // Okay, the name is the same, but
                                    // is it actually the same type?
                                    Type annotationType = getSootType(e);
                                    boolean isCorrectType = false;
                                    if (annotationType == null) {
                                        // we do not know the type of
                                        // the annotation, so we guess
                                        // it's the correct type.
                                        isCorrectType = true;
                                    } else {
                                        if (annotationType.equals(sm.getReturnType())) {
                                            isCorrectType = true;
                                        } else if (annotationType.equals(ARRAY_TYPE)) {
                                            if (sm.getReturnType() instanceof ArrayType)
                                                isCorrectType = true;
                                        }
                                    }
                                    if (isCorrectType && sm.getParameterCount() == 0) {
                                        e.setName("default");
                                        AnnotationDefaultTag d = new AnnotationDefaultTag(e);
                                        sm.addTag(d);
                                        // In case there is more than
                                        // one matching method, we only
                                        // use the first one
                                        defaults.remove(sm.getName());
                                    }
                                }
                            }
                            for (Entry<String, AnnotationElem> leftOverEntry : defaults.entrySet()) {
                                // We were not able to find a matching
                                // method for the tag, because the
                                // return signature
                                // does not match
                                SootMethod found = clazz.getMethodByNameUnsafe(leftOverEntry.getKey());
                                AnnotationElem element = leftOverEntry.getValue();
                                if (found != null) {
                                    element.setName("default");
                                    AnnotationDefaultTag d = new AnnotationDefaultTag(element);
                                    found.addTag(d);
                                }
                            }
                        }
                    }
                }
            }
            if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE))
                clazz.addTag(vt);
        } else {
            clazz.addTag(t);
        }
    }
}
Also used : InnerClassAttribute(soot.tagkit.InnerClassAttribute) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) HashMap(java.util.HashMap) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) ArrayType(soot.ArrayType) InnerClassTag(soot.tagkit.InnerClassTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) RefType(soot.RefType) Type(soot.Type) ArrayType(soot.ArrayType) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) SootMethod(soot.SootMethod) 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)

Aggregations

AnnotationTag (soot.tagkit.AnnotationTag)37 VisibilityAnnotationTag (soot.tagkit.VisibilityAnnotationTag)22 VisibilityParameterAnnotationTag (soot.tagkit.VisibilityParameterAnnotationTag)20 ArrayList (java.util.ArrayList)15 AnnotationAnnotationElem (soot.tagkit.AnnotationAnnotationElem)11 AnnotationElem (soot.tagkit.AnnotationElem)11 Tag (soot.tagkit.Tag)10 AnnotationClassElem (soot.tagkit.AnnotationClassElem)7 AnnotationDefaultTag (soot.tagkit.AnnotationDefaultTag)7 AnnotationStringElem (soot.tagkit.AnnotationStringElem)7 EnclosingMethodTag (soot.tagkit.EnclosingMethodTag)7 InnerClassTag (soot.tagkit.InnerClassTag)7 SignatureTag (soot.tagkit.SignatureTag)7 AnnotationArrayElem (soot.tagkit.AnnotationArrayElem)6 SootMethod (soot.SootMethod)4 HashSet (java.util.HashSet)3 List (java.util.List)3 AnnotationElement (org.jf.dexlib2.iface.AnnotationElement)3 EncodedValue (org.jf.dexlib2.iface.value.EncodedValue)3 ImmutableAnnotation (org.jf.dexlib2.immutable.ImmutableAnnotation)3