Search in sources :

Example 16 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project android_frameworks_base by crdroidandroid.

the class DelegateMethodAdapter method generateDelegateCode.

/**
     * Generates the new code for the method.
     * <p/>
     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
     * (since they have no code to visit).
     * <p/>
     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
     */
public void generateDelegateCode() {
    /*
         * The goal is to generate a call to a static delegate method.
         * If this method is non-static, the first parameter will be 'this'.
         * All the parameters must be passed and then the eventual return type returned.
         *
         * Example, let's say we have a method such as
         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
         *
         * We'll want to create a body that calls a delegate method like this:
         *   TheClass_Delegate.myMethod(this, a, b, c);
         *
         * If the method is non-static and the class name is an inner class (e.g. has $ in its
         * last segment), we want to push the 'this' of the outer class first:
         *   OuterClass_InnerClass_Delegate.myMethod(
         *     OuterClass.this,
         *     OuterClass$InnerClass.this,
         *     a, b, c);
         *
         * Only one level of inner class is supported right now, for simplicity and because
         * we don't need more.
         *
         * The generated class name is the current class name with "_Delegate" appended to it.
         * One thing to realize is that we don't care about generics -- since generic types
         * are erased at build time, they have no influence on the method name being called.
         */
    // Add our annotation
    AnnotationVisitor aw = mDelWriter.visitAnnotation(Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), // visible at runtime
    true);
    if (aw != null) {
        aw.visitEnd();
    }
    mDelWriter.visitCode();
    if (mDelegateLineNumber != null) {
        Object[] p = mDelegateLineNumber;
        mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
    }
    ArrayList<Type> paramTypes = new ArrayList<>();
    String delegateClassName = mClassName + DELEGATE_SUFFIX;
    boolean pushedArg0 = false;
    int maxStack = 0;
    // Check if the last segment of the class name has inner an class.
    // Right now we only support one level of inner classes.
    Type outerType = null;
    int slash = mClassName.lastIndexOf('/');
    int dol = mClassName.lastIndexOf('$');
    if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
        String outerClass = mClassName.substring(0, dol);
        outerType = Type.getObjectType(outerClass);
        // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
        delegateClassName = delegateClassName.replace('$', '_');
    }
    // by the 'this' of any outer class, if any.
    if (!mIsStatic) {
        if (outerType != null && !mIsStaticInnerClass) {
            // The first-level inner class has a package-protected member called 'this$0'
            // that points to the outer class.
            // Push this.getField("this$0") on the call stack.
            // var 0 = this
            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
            mDelWriter.visitFieldInsn(Opcodes.GETFIELD, // class where the field is defined
            mClassName, // field name
            "this$0", // type of the field
            outerType.getDescriptor());
            maxStack++;
            paramTypes.add(outerType);
        }
        // Push "this" for the instance method, which is always ALOAD 0
        mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
        maxStack++;
        pushedArg0 = true;
        paramTypes.add(Type.getObjectType(mClassName));
    }
    // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
    Type[] argTypes = Type.getArgumentTypes(mDesc);
    int maxLocals = pushedArg0 ? 1 : 0;
    for (Type t : argTypes) {
        int size = t.getSize();
        mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
        maxLocals += size;
        maxStack += size;
        paramTypes.add(t);
    }
    // Construct the descriptor of the delegate based on the parameters
    // we pushed on the call stack. The return type remains unchanged.
    String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc), paramTypes.toArray(new Type[paramTypes.size()]));
    // Invoke the static delegate
    mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc, false);
    Type returnType = Type.getReturnType(mDesc);
    mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mDelWriter.visitMaxs(maxStack, maxLocals);
    mDelWriter.visitEnd();
    // For debugging now. Maybe we should collect these and store them in
    // a text file for helping create the delegates. We could also compare
    // the text file to a golden and break the build on unsupported changes
    // or regressions. Even better we could fancy-print something that looks
    // like the expected Java method declaration.
    mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}
Also used : LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate) Type(org.objectweb.asm.Type) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ArrayList(java.util.ArrayList)

Example 17 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project drill by apache.

the class CheckMethodVisitorFsm method visitInsnAnnotation.

@Override
public AnnotationVisitor visitInsnAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
    fsmCursor.transition("visitInsnAnnotation");
    final AnnotationVisitor annotationVisitor = super.visitInsnAnnotation(typeRef, typePath, desc, visible);
    // TODO: add CheckAnnotationVisitorFsm
    return annotationVisitor;
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor)

Example 18 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project drill by apache.

the class AloadPopRemover method visitAnnotationDefault.

@Override
public AnnotationVisitor visitAnnotationDefault() {
    processDeferredAload(false);
    final AnnotationVisitor annotationVisitor = super.visitAnnotationDefault();
    return annotationVisitor;
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor)

Example 19 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project drill by apache.

the class AloadPopRemover method visitParameterAnnotation.

@Override
public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) {
    processDeferredAload(false);
    final AnnotationVisitor annotationVisitor = super.visitParameterAnnotation(parameter, desc, visible);
    return annotationVisitor;
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor)

Example 20 with AnnotationVisitor

use of org.objectweb.asm.AnnotationVisitor in project drill by apache.

the class AloadPopRemover method visitTypeAnnotation.

@Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
    processDeferredAload(false);
    final AnnotationVisitor annotationVisitor = super.visitTypeAnnotation(typeRef, typePath, desc, visible);
    return annotationVisitor;
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor)

Aggregations

AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)64 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)12 ArrayList (java.util.ArrayList)9 Type (org.objectweb.asm.Type)9 MethodVisitor (org.objectweb.asm.MethodVisitor)7 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)6 ClassNode (org.codehaus.groovy.ast.ClassNode)6 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)6 InterfaceHelperClassNode (org.codehaus.groovy.ast.InterfaceHelperClassNode)6 ClassVisitor (org.objectweb.asm.ClassVisitor)6 ClassReader (org.objectweb.asm.ClassReader)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 FieldVisitor (org.objectweb.asm.FieldVisitor)3 Label (org.objectweb.asm.Label)3 GroovyRuntimeException (groovy.lang.GroovyRuntimeException)2 InputStream (java.io.InputStream)2 List (java.util.List)2 GroovyBugError (org.codehaus.groovy.GroovyBugError)2 GenericsType (org.codehaus.groovy.ast.GenericsType)2