Example usage for org.objectweb.asm.tree MethodNode accept

List of usage examples for org.objectweb.asm.tree MethodNode accept

Introduction

In this page you can find the example usage for org.objectweb.asm.tree MethodNode accept.

Prototype

public void accept(final MethodVisitor methodVisitor) 

Source Link

Document

Makes the given method visitor visit this method.

Usage

From source file:com.android.build.gradle.internal.incremental.InstantRunMethodVerifier.java

License:Apache License

/**
 * Verifies a method implementation against the blacklisted list of APIs.
 * @param method the method to verify/*from   w  w w. ja  v  a 2 s. c  om*/
 * @return a {@link InstantRunVerifierStatus} instance or null if the method is not making any
 * blacklisted calls.
 */
@NonNull
public static InstantRunVerifierStatus verifyMethod(MethodNode method) {

    VerifierMethodVisitor mv = new VerifierMethodVisitor(method);
    method.accept(mv);
    return mv.incompatibleChange.or(InstantRunVerifierStatus.COMPATIBLE);
}

From source file:com.android.build.gradle.internal2.incremental.IncrementalSupportVisitor.java

License:Apache License

/**
 * Insert Constructor specific logic({@link ConstructorRedirection} and
 * {@link ConstructorBuilder}) for constructor redirecting or
 * normal method redirecting ({@link MethodRedirection}) for other methods.
 *///from  w w  w .  ja  va2  s .co  m
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

    access = transformAccessForInstantRun(access);

    MethodVisitor defaultVisitor = super.visitMethod(access, name, desc, signature, exceptions);
    MethodNode method = getMethodByNameInClass(name, desc, classNode);
    // does the method use blacklisted APIs.
    boolean hasIncompatibleChange = InstantRunMethodVerifier
            .verifyMethod(method) != InstantRunVerifierStatus.COMPATIBLE;

    if (hasIncompatibleChange || disableRedirectionForClass || !isAccessCompatibleWithInstantRun(access)
            || name.equals(ByteCodeUtils.CLASS_INITIALIZER)) {
        return defaultVisitor;
    } else {
        ArrayList<Type> args = new ArrayList<Type>(Arrays.asList(Type.getArgumentTypes(desc)));
        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
        if (!isStatic) {
            args.add(0, Type.getType(Object.class));
        }

        ISMethodVisitor mv = new ISMethodVisitor(defaultVisitor, access, name, desc);
        if (name.equals(ByteCodeUtils.CONSTRUCTOR)) {
            Constructor constructor = ConstructorBuilder.build(visitedClassName, method);
            LabelNode start = new LabelNode();
            method.instructions.insert(constructor.loadThis, start);
            if (constructor.lineForLoad != -1) {
                // Record the line number from the start of LOAD_0 for uninitialized 'this'.
                // This allows a breakpoint to be set at the line with this(...) or super(...)
                // call in the constructor.
                method.instructions.insert(constructor.loadThis,
                        new LineNumberNode(constructor.lineForLoad, start));
            }
            mv.addRedirection(new ConstructorRedirection(start, constructor, args));
        } else {
            mv.addRedirection(new MethodRedirection(new LabelNode(mv.getStartLabel()), name + "." + desc, args,
                    Type.getReturnType(desc)));
        }
        method.accept(mv);
        return null;
    }
}

From source file:com.android.builder.shrinker.Shrinker.java

License:Apache License

@NonNull
private Set<Dependency<T>> getDependencies(MethodNode methodNode) {
    final Set<Dependency<T>> deps = Sets.newHashSet();
    methodNode.accept(new DependencyFinderVisitor<T>(mGraph, null, null, null, null) {
        @Override/*w  w  w. j  av  a 2 s  . c  o m*/
        protected void handleDependency(T source, T target, DependencyType type) {
            deps.add(new Dependency<T>(target, type));
        }
    });
    return deps;
}

From source file:com.codename1.tools.ikvm.Parser.java

/**
 * Parses an InputStream containing a class.
 * @param input The input stream with a class.
 * @return If a transformation occurred, the bytes for the changed class will be returned.  Otherwise null will be returned.
 * @throws Exception //from   w  ww. j  av a 2  s.  com
 */
public static byte[] parse(InputStream input, ClassLoader classLoader) throws Exception {
    ClassReader r = new ClassReader(input);
    Parser p = new Parser();
    //ClassWriter w = new ClassWriter(r, 0);
    ClassNode classNode = new ClassNode();
    //p.classNode = classNode;

    r.accept(classNode, 0);
    //r.accept(p, ClassReader.EXPAND_FRAMES)

    List<MethodNode> methodsToAdd = new ArrayList<MethodNode>();
    int methodNum = 0;
    for (Object o : classNode.methods) {
        methodNum++;
        MethodNode methodNode = (MethodNode) o;
        boolean synchronizedMethod = (methodNode.access & Opcodes.ACC_SYNCHRONIZED) == Opcodes.ACC_SYNCHRONIZED;
        if (synchronizedMethod) {
            // Check for a try statement
            final boolean[] tryCatchFound = new boolean[1];
            //System.out.println("Found sync method "+methodNode.name+". Checking for try blocks");
            methodNode.accept(new MethodVisitor(Opcodes.ASM5) {

                @Override
                public void visitTryCatchBlock(Label label, Label label1, Label label2, String string) {
                    tryCatchFound[0] = true;
                }

            });
            if (!tryCatchFound[0]) {
                continue;
            }

            //System.out.println("Instructions: "+Arrays.toString(methodNode.instructions.toArray()));

            System.out.println("Transforming method " + methodNode.name + " of class " + classNode.name);
            MethodDescriptor md = new MethodDescriptor(methodNode.access, methodNode.name, methodNode.desc);
            //methodNode.access = methodNode.access & ~Opcodes.ACC_SYNCHRONIZED;
            String privateMethodName = (md.constructor ? "___cn1init__" : methodNode.name) + "___cn1sync"
                    + (methodNum);
            MethodNode syncMethod = new MethodNode(methodNode.access, methodNode.name, methodNode.desc,
                    methodNode.signature,
                    (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()]));

            methodNode.name = privateMethodName;
            methodNode.access = (methodNode.access | Opcodes.ACC_PRIVATE) & ~Opcodes.ACC_PUBLIC
                    & ~Opcodes.ACC_PROTECTED & ~Opcodes.ACC_SYNCHRONIZED;
            LabelNode startLabel = new LabelNode();
            syncMethod.instructions.add(startLabel);
            LabelNode endLabel = new LabelNode();

            int argIndex = 0;
            if (!md.staticMethod) {
                //System.out.println(methodNode.name + " is not static");
                syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex),
                        "L" + classNode.name + ";", null, startLabel, endLabel, argIndex));
                syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++));

            }

            for (ByteCodeMethodArg arg : md.arguments) {
                char typeChar = arg.type;
                if (arg.dim > 0) {
                    typeChar = 'L';
                }
                if (arg.desc == null || arg.desc.isEmpty()) {
                    throw new RuntimeException(
                            "Invalid arg description for arg " + argIndex + " of method " + methodNode.name);
                }
                syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex), arg.desc, arg.desc,
                        startLabel, endLabel, argIndex));

                switch (typeChar) {
                case 'L':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++));
                    //syncMethod.localVariables.add(new LocalVariableNode("arg"+(argIndex-1), arg.desc, null, startLabel, endLabel, argIndex-1));
                    break;
                case 'S':
                case 'I':
                case 'B':
                case 'Z':
                case 'C':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.ILOAD, argIndex++));
                    break;
                case 'J':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.LLOAD, argIndex++));
                    argIndex++; // arg index increments 2 for double size args
                    break;
                case 'F':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.FLOAD, argIndex++));
                    break;
                case 'D':
                    syncMethod.instructions.add(new VarInsnNode(Opcodes.DLOAD, argIndex++));
                    argIndex++;// arg index increments 2 for double size args
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported argument type " + arg.type);
                }
            }

            if (md.staticMethod) {
                syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name,
                        privateMethodName, methodNode.desc));
            } else {
                syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.name,
                        privateMethodName, methodNode.desc));
            }

            if (md.returnType != null) {
                char typeChar = md.returnType.type;
                if (md.returnType.dim > 0) {
                    typeChar = 'L';
                }
                switch (typeChar) {
                case 'L':
                    syncMethod.instructions.add(new InsnNode(Opcodes.ARETURN));
                    break;
                case 'S':
                case 'I':
                case 'B':
                case 'Z':
                case 'C':
                    syncMethod.instructions.add(new InsnNode(Opcodes.IRETURN));
                    break;
                case 'J':
                    syncMethod.instructions.add(new InsnNode(Opcodes.LRETURN));
                    break;
                case 'F':
                    syncMethod.instructions.add(new InsnNode(Opcodes.FRETURN));
                    break;
                case 'D':
                    syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN));
                    break;
                case 'V':
                    syncMethod.instructions.add(new InsnNode(Opcodes.RETURN));
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported argument type " + md.returnType.type);
                }
            } else {
                syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN));
            }

            syncMethod.instructions.add(endLabel);

            methodsToAdd.add(syncMethod);

        }
    }
    if (!methodsToAdd.isEmpty()) {
        changed = true;
        System.out
                .println("Transforming " + methodsToAdd.size() + " synchronized methods in " + classNode.name);
        classNode.methods.addAll(methodsToAdd);
        ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(w);
        byte[] out = w.toByteArray();
        if (verify) {
            verify(out, classLoader);
        }
        return out;
    } else {
        ClassWriter w = new ClassWriter(0);
        classNode.accept(w);
        byte[] out = w.toByteArray();
        return out;
    }

}

From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java

License:Open Source License

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
        final String[] exceptions) {
    if ((access & ACC_STATIC) != 0 || (access & ACC_ABSTRACT) != 0)
        return super.visitMethod(access, name, desc, signature, exceptions);

    final MethodNode methodNode = new MethodNode(access, name, desc, signature, exceptions);

    return new MethodVisitor(ASM5, methodNode) {
        @Override/*from w  ww  . ja va2  s . c  o  m*/
        public void visitEnd() {
            super.visitEnd();
            processMethod(methodNode);

            if (name.equals("setup") && desc.equals("()V"))
                setupMethod = methodNode;
            else
                methodNode.accept(SystemProcessor.super.visitMethod(access, name, desc, signature, exceptions));
        }
    };
}

From source file:com.github.fge.grappa.transform.AsmTestUtils.java

License:Apache License

public static String getMethodInstructionList(MethodNode methodNode) {
    Preconditions.checkNotNull(methodNode, "methodNode");
    Printer printer = new NonMaxTextifier();
    TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer);
    methodNode.accept(traceMethodVisitor);
    StringWriter stringWriter = new StringWriter();
    PrintWriter printWriter = new PrintWriter(stringWriter);
    printer.print(printWriter);//from   w  ww  .  ja va2 s.  co m
    printWriter.flush();
    String[] lines = PATTERN.split(stringWriter.toString());
    int lineNr = 0;
    for (int i = 0; i < lines.length; i++) {
        if (!lines[i].startsWith("  @")) {
            lines[i] = String.format("%2d %s", lineNr++, lines[i]);
        }
    }
    return "Method '" + methodNode.name + "':\n" + NEWLINE.join(lines) + '\n';
}

From source file:com.github.fge.grappa.transform.AsmTestUtils.java

License:Apache License

public static void assertTraceDumpEquality(MethodNode method, String traceDump) throws Exception {
    Preconditions.checkNotNull(method, "method");
    Printer printer = new NonMaxTextifier();
    TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer);
    // MethodAdapter checkMethodAdapter = new MethodAdapter(traceMethodVisitor);
    MethodVisitor checkMethodAdapter = new CheckMethodAdapter(traceMethodVisitor);
    method.accept(checkMethodAdapter);
    StringWriter stringWriter = new StringWriter();
    PrintWriter printWriter = new PrintWriter(stringWriter);
    printer.print(printWriter);/*from w ww  .  jav  a  2s.  com*/
    printWriter.flush();

    assertEquals(stringWriter.toString(), traceDump);
}

From source file:com.github.veithen.cosmos.osgi.runtime.MemberInjector.java

License:Apache License

@Override
public void visitEnd() {
    for (MethodNode method : classNode.methods) {
        method.accept(new RelocatingClassVisitor(cv, classNode.name, name));
    }/*from   w w w.  java 2s .  c  om*/
    super.visitEnd();
}

From source file:com.google.java.contract.core.agent.SpecificationClassAdapter.java

License:Open Source License

@Override
public void visitEnd() {
    if (contracts != null) {
        List<ClassContractHandle> synths = new ArrayList<ClassContractHandle>();
        synths.addAll(contracts.getClassHandles(ContractKind.ACCESS));
        synths.addAll(contracts.getClassHandles(ContractKind.LAMBDA));
        for (ClassContractHandle h : synths) {
            h.getContractMethod().accept(cv);
        }/*from  w  ww  .ja  va  2s .c  o  m*/

        List<ClassContractHandle> helpers = contracts.getClassHandles(ContractKind.HELPER);
        for (ClassContractHandle h : helpers) {
            MethodNode methodNode = h.getContractMethod();
            DebugUtils.info("instrument",
                    "helper method " + className + "." + methodNode.name + methodNode.desc);
            ClassVisitor visitor = cv;
            List<Long> lineNumbers = h.getLineNumbers();
            if (lineNumbers != null) {
                visitor = new LineNumberingClassAdapter(visitor, lineNumbers);
            }
            methodNode.accept(new ContractFixingClassAdapter(visitor));
            h.setInjected(true);
        }
    }
    super.visitEnd();
}

From source file:com.google.java.contract.core.agent.SpecificationMethodAdapter.java

License:Open Source License

/**
 * Injects the specified contract method code into the current
 * class, and returns a new Method object representing the injected
 * method. This is done by bypassing the SpecificationClassAdapter
 * and talking directly to its parent (usually, a class writer).
 *
 * @param handle the handle from the code pool that holds code and
 * meta-information about the contract method
 * @return the method node to invoke/*ww w  .  j  av a 2  s  .  c om*/
 */
@Requires("handle != null")
@Ensures("result != null")
protected MethodNode injectContractMethod(ContractHandle handle) {
    MethodNode methodNode = handle.getContractMethod();

    if (!handle.isInjected()) {
        DebugUtils.info("instrument", "contract method " + className + "." + methodNode.name + methodNode.desc);
        ClassVisitor cv = classAdapter.getParent();
        List<Long> lineNumbers = handle.getLineNumbers();
        if (lineNumbers != null) {
            cv = new LineNumberingClassAdapter(cv, lineNumbers);
        }
        methodNode.accept(new ContractFixingClassAdapter(cv));
        handle.setInjected(true);
    }

    return methodNode;
}