Search in sources :

Example 1 with AnnotationsList

use of com.android.dx.rop.annotation.AnnotationsList in project buck by facebook.

the class CfTranslator method processMethods.

/**
     * Processes the methods of the given class.
     *
     * @param context
     * @param cf {@code non-null;} class being translated
     * @param cfOptions {@code non-null;} options for class translation
     * @param dexOptions {@code non-null;} options for dex output
     * @param out {@code non-null;} output class
     * @param dexFile {@code non-null;} dex output
     */
private static void processMethods(DxContext context, DirectClassFile cf, CfOptions cfOptions, DexOptions dexOptions, ClassDefItem out, DexFile dexFile) {
    CstType thisClass = cf.getThisClass();
    MethodList methods = cf.getMethods();
    int sz = methods.size();
    for (int i = 0; i < sz; i++) {
        Method one = methods.get(i);
        try {
            CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());
            int accessFlags = one.getAccessFlags();
            boolean isStatic = AccessFlags.isStatic(accessFlags);
            boolean isPrivate = AccessFlags.isPrivate(accessFlags);
            boolean isNative = AccessFlags.isNative(accessFlags);
            boolean isAbstract = AccessFlags.isAbstract(accessFlags);
            boolean isConstructor = meth.isInstanceInit() || meth.isClassInit();
            DalvCode code;
            if (isNative || isAbstract) {
                // There's no code for native or abstract methods.
                code = null;
            } else {
                ConcreteMethod concrete = new ConcreteMethod(one, cf, (cfOptions.positionInfo != PositionList.NONE), cfOptions.localInfo);
                TranslationAdvice advice;
                advice = DexTranslationAdvice.THE_ONE;
                RopMethod rmeth = Ropper.convert(concrete, advice, methods);
                RopMethod nonOptRmeth = null;
                int paramSize;
                paramSize = meth.getParameterWordCount(isStatic);
                String canonicalName = thisClass.getClassType().getDescriptor() + "." + one.getName().getString();
                if (cfOptions.optimize && context.optimizerOptions.shouldOptimize(canonicalName)) {
                    if (DEBUG) {
                        System.err.println("Optimizing " + canonicalName);
                    }
                    nonOptRmeth = rmeth;
                    rmeth = Optimizer.optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
                    if (DEBUG) {
                        context.optimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
                    }
                    if (cfOptions.statistics) {
                        context.codeStatistics.updateRopStatistics(nonOptRmeth, rmeth);
                    }
                }
                LocalVariableInfo locals = null;
                if (cfOptions.localInfo) {
                    locals = LocalVariableExtractor.extract(rmeth);
                }
                code = RopTranslator.translate(rmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
                if (cfOptions.statistics && nonOptRmeth != null) {
                    updateDexStatistics(context, cfOptions, dexOptions, rmeth, nonOptRmeth, locals, paramSize, concrete.getCode().size());
                }
            }
            // Preserve the synchronized flag as its "declared" variant...
            if (AccessFlags.isSynchronized(accessFlags)) {
                accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;
                /*
                     * ...but only native methods are actually allowed to be
                     * synchronized.
                     */
                if (!isNative) {
                    accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;
                }
            }
            if (isConstructor) {
                accessFlags |= AccessFlags.ACC_CONSTRUCTOR;
            }
            TypeList exceptions = AttributeTranslator.getExceptions(one);
            EncodedMethod mi = new EncodedMethod(meth, accessFlags, code, exceptions);
            if (meth.isInstanceInit() || meth.isClassInit() || isStatic || isPrivate) {
                out.addDirectMethod(mi);
            } else {
                out.addVirtualMethod(mi);
            }
            Annotations annotations = AttributeTranslator.getMethodAnnotations(one);
            if (annotations.size() != 0) {
                out.addMethodAnnotations(meth, annotations, dexFile);
            }
            AnnotationsList list = AttributeTranslator.getParameterAnnotations(one);
            if (list.size() != 0) {
                out.addParameterAnnotations(meth, list, dexFile);
            }
            dexFile.getMethodIds().intern(meth);
        } catch (RuntimeException ex) {
            String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
            throw ExceptionWithContext.withContext(ex, msg);
        }
    }
}
Also used : DalvCode(com.android.dx.dex.code.DalvCode) RopMethod(com.android.dx.rop.code.RopMethod) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) MethodList(com.android.dx.cf.iface.MethodList) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) EncodedMethod(com.android.dx.dex.file.EncodedMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) Method(com.android.dx.cf.iface.Method) CstString(com.android.dx.rop.cst.CstString) CstMethodRef(com.android.dx.rop.cst.CstMethodRef) LocalVariableInfo(com.android.dx.rop.code.LocalVariableInfo) Annotations(com.android.dx.rop.annotation.Annotations) EncodedMethod(com.android.dx.dex.file.EncodedMethod) CstType(com.android.dx.rop.cst.CstType) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) TypeList(com.android.dx.rop.type.TypeList)

Example 2 with AnnotationsList

use of com.android.dx.rop.annotation.AnnotationsList in project buck by facebook.

the class AnnotationParser method parseAnnotationsList.

/**
     * Parses a list of annotation lists.
     *
     * @param visibility {@code non-null;} visibility of the parsed annotations
     * @return {@code non-null;} the list of annotation lists read from the attribute
     * data
     */
private AnnotationsList parseAnnotationsList(AnnotationVisibility visibility) throws IOException {
    int count = input.readUnsignedByte();
    if (observer != null) {
        parsed(1, "num_parameters: " + Hex.u1(count));
    }
    AnnotationsList outerList = new AnnotationsList(count);
    for (int i = 0; i < count; i++) {
        if (observer != null) {
            parsed(0, "parameter_annotations[" + i + "]:");
            changeIndent(1);
        }
        Annotations annotations = parseAnnotations(visibility);
        outerList.set(i, annotations);
        if (observer != null) {
            observer.changeIndent(-1);
        }
    }
    outerList.setImmutable();
    return outerList;
}
Also used : Annotations(com.android.dx.rop.annotation.Annotations) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList)

Example 3 with AnnotationsList

use of com.android.dx.rop.annotation.AnnotationsList in project buck by facebook.

the class StdAttributeFactory method runtimeVisibleParameterAnnotations.

/**
     * Parses a {@code RuntimeVisibleParameterAnnotations} attribute.
     */
private Attribute runtimeVisibleParameterAnnotations(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 2) {
        throwSeverelyTruncated();
    }
    AnnotationParser ap = new AnnotationParser(cf, offset, length, observer);
    AnnotationsList list = ap.parseParameterAttribute(AnnotationVisibility.RUNTIME);
    return new AttRuntimeVisibleParameterAnnotations(list, length);
}
Also used : AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) AttRuntimeVisibleParameterAnnotations(com.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations)

Example 4 with AnnotationsList

use of com.android.dx.rop.annotation.AnnotationsList in project buck by facebook.

the class Main method dumpMethod.

/**
     * Dumps any method with the given name in the given file.
     *
     * @param dex {@code non-null;} the dex file
     * @param fqName {@code non-null;} the fully-qualified name of the
     * method(s)
     * @param out {@code non-null;} where to dump to
     */
private void dumpMethod(DexFile dex, String fqName, OutputStreamWriter out) {
    boolean wildcard = fqName.endsWith("*");
    int lastDot = fqName.lastIndexOf('.');
    if ((lastDot <= 0) || (lastDot == (fqName.length() - 1))) {
        context.err.println("bogus fully-qualified method name: " + fqName);
        return;
    }
    String className = fqName.substring(0, lastDot).replace('.', '/');
    String methodName = fqName.substring(lastDot + 1);
    ClassDefItem clazz = dex.getClassOrNull(className);
    if (clazz == null) {
        context.err.println("no such class: " + className);
        return;
    }
    if (wildcard) {
        methodName = methodName.substring(0, methodName.length() - 1);
    }
    ArrayList<EncodedMethod> allMeths = clazz.getMethods();
    TreeMap<CstNat, EncodedMethod> meths = new TreeMap<CstNat, EncodedMethod>();
    /*
         * Figure out which methods to include in the output, and get them
         * all sorted, so that the printout code is robust with respect to
         * changes in the underlying order.
         */
    for (EncodedMethod meth : allMeths) {
        String methName = meth.getName().getString();
        if ((wildcard && methName.startsWith(methodName)) || (!wildcard && methName.equals(methodName))) {
            meths.put(meth.getRef().getNat(), meth);
        }
    }
    if (meths.size() == 0) {
        context.err.println("no such method: " + fqName);
        return;
    }
    PrintWriter pw = new PrintWriter(out);
    for (EncodedMethod meth : meths.values()) {
        // TODO: Better stuff goes here, perhaps.
        meth.debugPrint(pw, args.verboseDump);
        /*
             * The (default) source file is an attribute of the class, but
             * it's useful to see it in method dumps.
             */
        CstString sourceFile = clazz.getSourceFile();
        if (sourceFile != null) {
            pw.println("  source file: " + sourceFile.toQuoted());
        }
        Annotations methodAnnotations = clazz.getMethodAnnotations(meth.getRef());
        AnnotationsList parameterAnnotations = clazz.getParameterAnnotations(meth.getRef());
        if (methodAnnotations != null) {
            pw.println("  method annotations:");
            for (Annotation a : methodAnnotations.getAnnotations()) {
                pw.println("    " + a);
            }
        }
        if (parameterAnnotations != null) {
            pw.println("  parameter annotations:");
            int sz = parameterAnnotations.size();
            for (int i = 0; i < sz; i++) {
                pw.println("    parameter " + i);
                Annotations annotations = parameterAnnotations.get(i);
                for (Annotation a : annotations.getAnnotations()) {
                    pw.println("      " + a);
                }
            }
        }
    }
    pw.flush();
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) CstString(com.android.dx.rop.cst.CstString) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) CstString(com.android.dx.rop.cst.CstString) TreeMap(java.util.TreeMap) Annotation(com.android.dx.rop.annotation.Annotation) Annotations(com.android.dx.rop.annotation.Annotations) ClassDefItem(com.android.dx.dex.file.ClassDefItem) EncodedMethod(com.android.dx.dex.file.EncodedMethod) PrintWriter(java.io.PrintWriter)

Example 5 with AnnotationsList

use of com.android.dx.rop.annotation.AnnotationsList in project buck by facebook.

the class StdAttributeFactory method runtimeInvisibleParameterAnnotations.

/**
     * Parses a {@code RuntimeInvisibleParameterAnnotations} attribute.
     */
private Attribute runtimeInvisibleParameterAnnotations(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 2) {
        throwSeverelyTruncated();
    }
    AnnotationParser ap = new AnnotationParser(cf, offset, length, observer);
    AnnotationsList list = ap.parseParameterAttribute(AnnotationVisibility.BUILD);
    return new AttRuntimeInvisibleParameterAnnotations(list, length);
}
Also used : AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) AttRuntimeInvisibleParameterAnnotations(com.android.dx.cf.attrib.AttRuntimeInvisibleParameterAnnotations)

Aggregations

AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)5 Annotations (com.android.dx.rop.annotation.Annotations)3 EncodedMethod (com.android.dx.dex.file.EncodedMethod)2 CstString (com.android.dx.rop.cst.CstString)2 AttRuntimeInvisibleParameterAnnotations (com.android.dx.cf.attrib.AttRuntimeInvisibleParameterAnnotations)1 AttRuntimeVisibleParameterAnnotations (com.android.dx.cf.attrib.AttRuntimeVisibleParameterAnnotations)1 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)1 Method (com.android.dx.cf.iface.Method)1 MethodList (com.android.dx.cf.iface.MethodList)1 DalvCode (com.android.dx.dex.code.DalvCode)1 ClassDefItem (com.android.dx.dex.file.ClassDefItem)1 Annotation (com.android.dx.rop.annotation.Annotation)1 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)1 LocalVariableInfo (com.android.dx.rop.code.LocalVariableInfo)1 RopMethod (com.android.dx.rop.code.RopMethod)1 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)1 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)1 CstNat (com.android.dx.rop.cst.CstNat)1 CstType (com.android.dx.rop.cst.CstType)1 TypeList (com.android.dx.rop.type.TypeList)1