Example usage for org.objectweb.asm MethodVisitor MethodVisitor

List of usage examples for org.objectweb.asm MethodVisitor MethodVisitor

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor MethodVisitor.

Prototype

public MethodVisitor(final int api) 

Source Link

Document

Constructs a new MethodVisitor .

Usage

From source file:org.jooby.internal.RouteMetadata.java

License:Apache License

private static ClassVisitor visitor(final Map<String, Object> md) {
    return new ClassVisitor(Opcodes.ASM5) {

        @Override//from ww w . java  2  s. c  om
        public MethodVisitor visitMethod(final int access, final String name, final String desc,
                final String signature, final String[] exceptions) {
            boolean isPublic = ((access & Opcodes.ACC_PUBLIC) > 0) ? true : false;
            boolean isStatic = ((access & Opcodes.ACC_STATIC) > 0) ? true : false;
            if (!isPublic || isStatic) {
                // ignore
                return null;
            }
            final String seed = name + desc;
            Type[] args = Type.getArgumentTypes(desc);
            String[] names = args.length == 0 ? NO_ARG : new String[args.length];
            md.put(paramsKey(seed), names);

            int minIdx = ((access & Opcodes.ACC_STATIC) > 0) ? 0 : 1;
            int maxIdx = Arrays.stream(args).mapToInt(Type::getSize).sum();

            return new MethodVisitor(Opcodes.ASM5) {

                private int i = 0;

                private boolean skipLocalTable = false;

                @Override
                public void visitParameter(final String name, final int access) {
                    skipLocalTable = true;
                    // save current parameter
                    names[i] = name;
                    // move to next
                    i += 1;
                }

                @Override
                public void visitLineNumber(final int line, final Label start) {
                    // save line number
                    md.putIfAbsent(startAtKey(seed), line);
                }

                @Override
                public void visitLocalVariable(final String name, final String desc, final String signature,
                        final Label start, final Label end, final int index) {
                    if (!skipLocalTable) {
                        if (index >= minIdx && index <= maxIdx) {
                            // save current parameter
                            names[i] = name;
                            // move to next
                            i += 1;
                        }
                    }
                }

            };
        }

    };
}

From source file:org.kohsuke.accmod.impl.Checker.java

License:Open Source License

/**
 * Loads an additional restriction from the specified "META-INF/annotations/org.kohsuke.accmod.Restricted" file.
 *
 * @param isInTheInspectedModule/*w  w  w  . j av a 2  s.  c  o m*/
 *      This value shows up in {@link RestrictedElement#isInTheInspectedModule()}.
 * @param stream
 */
public void loadRestrictions(InputStream stream, final boolean isInTheInspectedModule) throws IOException {
    if (stream == null)
        return;

    BufferedReader r = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
    String className;
    while ((className = r.readLine()) != null) {
        InputStream is = dependencies.getResourceAsStream(className.replace('.', '/') + ".class");
        if (is == null) {
            errorListener.onWarning(null, null, "Failed to find class file for " + className);
            continue;
        }

        try {
            new ClassReader(is).accept(new ClassVisitor(Opcodes.ASM5) {
                private String className;

                @Override
                public void visit(int version, int access, String name, String signature, String superName,
                        String[] interfaces) {
                    this.className = name;
                }

                @Override
                public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                    return onAnnotationFor(className, desc);
                }

                @Override
                public FieldVisitor visitField(int access, final String name, String desc, String signature,
                        Object value) {
                    return new FieldVisitor(Opcodes.ASM5) {
                        @Override
                        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                            return onAnnotationFor(className + '.' + name, desc);
                        }
                    };
                }

                @Override
                public MethodVisitor visitMethod(int access, final String methodName, final String methodDesc,
                        String signature, String[] exceptions) {
                    return new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                            return onAnnotationFor(className + '.' + methodName + methodDesc, desc);
                        }
                    };
                }

                /**
                 * Parse {@link Restricted} annotation on some annotated element.
                 */
                private AnnotationVisitor onAnnotationFor(final String keyName, String desc) {
                    if (RESTRICTED_DESCRIPTOR.equals(desc)) {
                        RestrictedElement target = new RestrictedElement() {
                            public boolean isInTheInspectedModule() {
                                return isInTheInspectedModule;
                            }

                            public String toString() {
                                return keyName;
                            }
                        };
                        return new Parser(target) {
                            @Override
                            public void visitEnd() {
                                try {
                                    restrictions.put(keyName, build(factory));
                                } catch (ClassNotFoundException e) {
                                    failure(e);
                                } catch (InstantiationException e) {
                                    failure(e);
                                } catch (IllegalAccessException e) {
                                    failure(e);
                                }
                            }

                            /**
                             * Fails to load a {@link AccessRestriction} instance.
                             */
                            private void failure(Exception e) {
                                errorListener.onError(e, null, "Failed to load restrictions");
                            }
                        };
                    }
                    return null;
                }
            }, ClassReader.SKIP_CODE);
        } finally {
            is.close();
        }
    }
}

From source file:org.kohsuke.accmod.impl.Checker.java

License:Open Source License

/**
 * Inspects a class for the restriction violations.
 *///  ww w  .j  a  v a 2s. c  o  m
public void checkClass(File clazz) throws IOException {
    FileInputStream in = new FileInputStream(clazz);
    try {
        ClassReader cr = new ClassReader(in);
        cr.accept(new ClassVisitor(Opcodes.ASM5) {
            private String className;
            private String methodName, methodDesc;
            private int line;

            @Override
            public void visit(int version, int access, String name, String signature, String superName,
                    String[] interfaces) {
                this.className = name;

                if (superName != null)
                    getRestrictions(superName).usedAsSuperType(currentLocation, errorListener);

                if (interfaces != null) {
                    for (String intf : interfaces)
                        getRestrictions(intf).usedAsInterface(currentLocation, errorListener);
                }
            }

            @Override
            public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                    String[] exceptions) {
                this.methodName = name;
                this.methodDesc = desc;
                return new MethodVisitor(Opcodes.ASM5) {
                    @Override
                    public void visitLineNumber(int _line, Label start) {
                        line = _line;
                    }

                    public void visitTypeInsn(int opcode, String type) {
                        switch (opcode) {
                        case Opcodes.NEW:
                            getRestrictions(type).instantiated(currentLocation, errorListener);
                        }
                    }

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        getRestrictions(owner + '.' + name + desc).invoked(currentLocation, errorListener);
                    }

                    @Override
                    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                        Restrictions r = getRestrictions(owner + '.' + name);
                        switch (opcode) {
                        case Opcodes.GETSTATIC:
                        case Opcodes.GETFIELD:
                            r.read(currentLocation, errorListener);
                            break;
                        case Opcodes.PUTSTATIC:
                        case Opcodes.PUTFIELD:
                            r.written(currentLocation, errorListener);
                            break;
                        }
                        super.visitFieldInsn(opcode, owner, name, desc);
                    }
                };
            }

            /**
             * Constant that represents the current location.
             */
            private final Location currentLocation = new Location() {
                public String getClassName() {
                    return className.replace('/', '.');
                }

                public String getMethodName() {
                    return methodName;
                }

                public String getMethodDescriptor() {
                    return methodDesc;
                }

                public int getLineNumber() {
                    return line;
                }

                public String toString() {
                    return className + ':' + line;
                }

                public ClassLoader getDependencyClassLoader() {
                    return dependencies;
                }

                public boolean isInTheSameModuleAs(RestrictedElement e) {
                    // TODO
                    throw new UnsupportedOperationException();
                }
            };
        }, SKIP_FRAMES);
    } finally {
        in.close();
    }
}

From source file:org.lwjglx.autostack.Transformer.java

License:Open Source License

public byte[] transform(ClassLoader loader, final String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) {
    try {/*  w  w w.j  a  va  2s .c  o m*/
        if (className == null || className.startsWith("java/") || className.startsWith("sun/")
                || className.startsWith("jdk/internal/") || className.startsWith("org/lwjgl/"))
            return null;
        for (String pack : packages)
            if (!className.startsWith(pack))
                return null;
        ClassReader cr = new ClassReader(classfileBuffer);
        final Map<String, Integer> stackMethods = new HashMap<String, Integer>();
        // Scan all methods that need auto-stack
        if (debugTransform)
            System.out.println("[autostack] scanning methods in class: " + className.replace('/', '.'));
        cr.accept(new ClassVisitor(ASM7) {
            public MethodVisitor visitMethod(final int access, final String methodName, final String methodDesc,
                    String signature, String[] exceptions) {
                if ((access & (ACC_NATIVE | ACC_ABSTRACT)) != 0) {
                    // Don't try to analyze native or abstract methods.
                    return null;
                }
                MethodVisitor mv = new MethodVisitor(ASM7) {
                    boolean mark, catches, notransform, nostackparam, forcestack;

                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc))
                            notransform = true;
                        else if ("Lorg/lwjglx/autostack/NoStackParam;".equals(desc))
                            nostackparam = true;
                        else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc))
                            forcestack = true;
                        return null;
                    }

                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        if (opcode == INVOKESTATIC && !itf && (owner.startsWith("org/lwjgl/")
                                && (name.equals("mallocStack") || name.equals("callocStack"))
                                || owner.equals(MEMORYSTACK) && (name.equals("stackGet")
                                        || name.equals("stackPop") || name.equals("stackPush")
                                        || name.startsWith("stackMalloc") || name.startsWith("stackCalloc")
                                        || name.startsWith("nstackMalloc") || name.startsWith("nstackCalloc")
                                        || name.equals("stackUTF8") || name.equals("stackASCII")
                                        || name.equals("stackUTF16") || name.equals("stackFloats")
                                        || name.equals("stackInts") || name.equals("stackBytes")
                                        || name.equals("stackShorts") || name.equals("stackPointers")
                                        || name.equals("stackLongs")))) {
                            mark = true;
                        }
                    }

                    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
                        catches = true;
                    }

                    public void visitEnd() {
                        int flag = (access & ACC_PRIVATE) != 0 ? 8 : 0;
                        flag |= nostackparam ? 16 : 0;
                        if (mark || notransform || forcestack || nostackparam) {
                            if (notransform) {
                                flag |= 2;
                                if (debugTransform)
                                    System.out.println("[autostack]   will not transform method: "
                                            + className.replace('/', '.') + "." + methodName);
                            } else {
                                if (checkStack)
                                    flag |= 4;
                                flag |= catches ? 1 : 0;
                                if (debugTransform)
                                    System.out.println("[autostack]   will transform method: "
                                            + className.replace('/', '.') + "." + methodName);
                            }
                            stackMethods.put(methodName + methodDesc, Integer.valueOf(flag));
                        }
                    }
                };
                return mv;
            }
        }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
        if (stackMethods.isEmpty())
            return null;

        // Now, transform all such methods
        if (debugTransform)
            System.out.println("[autostack] transforming methods in class: " + className.replace('/', '.'));
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        cr.accept(new ClassVisitor(ASM7, cw) {
            boolean classDefaultNewStack = defaultNewStack;
            boolean classNoTransform;

            @Override
            public void visit(int version, int access, String name, String signature, String superName,
                    String[] interfaces) {
                cv.visit(version, access, name, signature, superName, interfaces);
                if (!checkStack) {
                    return;
                }
                /* Generate simple synthetic "compare stack pointers and throw if not equal" method */
                MethodVisitor mv = cv.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "$checkStack$",
                        "(II)V", null, new String[] { "java/lang/AssertionError" });
                {
                    mv.visitCode();
                    mv.visitVarInsn(ILOAD, 0);
                    mv.visitVarInsn(ILOAD, 1);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IF_ICMPEQ, l0);
                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn("Stack pointers differ: ");
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitVarInsn(ILOAD, 0);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitLdcInsn(" != ");
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                            "()Ljava/lang/String;", false);
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitInsn(ATHROW);
                    mv.visitLabel(l0);
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    mv.visitInsn(RETURN);
                    mv.visitMaxs(5, 2);
                    mv.visitEnd();
                }

                mv = cv.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "$checkStackWithThrowable$",
                        "(Ljava/lang/Throwable;II)Ljava/lang/Throwable;", null, null);
                {
                    mv.visitCode();
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitVarInsn(ILOAD, 2);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IF_ICMPEQ, l0);
                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn("Stack pointers differ: ");
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitLdcInsn(" != ");
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
                    mv.visitVarInsn(ILOAD, 2);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                            "()Ljava/lang/String;", false);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>",
                            "(Ljava/lang/String;Ljava/lang/Throwable;)V", false);
                    mv.visitInsn(ARETURN);
                    mv.visitLabel(l0);
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitInsn(ARETURN);
                    mv.visitMaxs(5, 3);
                    mv.visitEnd();
                }
            }

            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                if ("Lorg/lwjglx/autostack/UseCallerStack;".equals(desc)) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]   class declares to use caller stack for all methods, unless overridden by method");
                    classDefaultNewStack = false;
                    return null;
                } else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc)) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]   class declares to use new stack for all methods, unless overridden by method");
                    classDefaultNewStack = true;
                    return null;
                } else if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc)) {
                    if (debugTransform)
                        System.out.println("[autostack]   class declares to not transform any methods");
                    classNoTransform = true;
                    return null;
                }
                return cv.visitAnnotation(desc, visible);
            }

            public MethodVisitor visitMethod(final int access, final String name, final String desc,
                    String signature, String[] exceptions) {
                Integer info = stackMethods.get(name + desc);
                if (info == null)
                    return super.visitMethod(access, name, desc, signature, exceptions);
                boolean catches = (info.intValue() & 1) == 1;
                final boolean notransform = classNoTransform || (info.intValue() & 2) == 2;
                if (debugTransform && !notransform)
                    System.out.println(
                            "[autostack]   transform method: " + className.replace('/', '.') + "." + name);
                final boolean memoryStackParam = stackAsParameter && (access & ACC_PRIVATE) != 0
                        && (info.intValue() & 16) == 0;
                MethodVisitor mv;
                final Type[] paramTypes = Type.getArgumentTypes(desc);
                final boolean isStatic = (access & ACC_STATIC) != 0;
                final boolean isConstructor = "<init>".equals(name);
                if (memoryStackParam) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]     changing signature of method to add additional MemoryStack parameter");

                    // Add additional MemoryStack parameter to the method signature index of the local stays the same
                    int paramEndIndex = desc.indexOf(')');
                    String beforeDesc = desc.substring(0, paramEndIndex);
                    String afterDesc = desc.substring(paramEndIndex);
                    mv = super.visitMethod(access | ACC_SYNTHETIC, name,
                            beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, signature, exceptions);

                    // Re-introduce the original method which just delegates
                    if (debugTransform)
                        System.out.println("[autostack]     adding delegate method with original signature");
                    MethodVisitor omv = super.visitMethod(access, name, desc, signature, exceptions);
                    omv.visitCode();
                    int param = 0;
                    if (!isStatic) {
                        omv.visitVarInsn(ALOAD, 0);
                        param++;
                    }
                    for (int i = 0; i < paramTypes.length; i++) {
                        omv.visitVarInsn(paramTypes[i].getOpcode(ILOAD), param);
                        param += paramTypes[i].getSize();
                    }
                    omv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet", "()L" + MEMORYSTACK + ";",
                            false);
                    boolean isPrivate = (access & ACC_PRIVATE) != 0;
                    int opcode = isStatic ? INVOKESTATIC : isPrivate ? INVOKESPECIAL : INVOKEVIRTUAL;
                    omv.visitMethodInsn(opcode, className, name,
                            beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, false);
                    Type retType = Type.getReturnType(desc);
                    omv.visitInsn(retType.getOpcode(IRETURN));
                    omv.visitMaxs(-1, -1);
                    omv.visitEnd();
                } else {
                    mv = super.visitMethod(access, name, desc, signature, exceptions);
                }
                if (catches)
                    mv = new TryCatchBlockSorter(mv, access, name, desc, signature, exceptions);
                mv = new MethodVisitor(ASM7, mv) {
                    Label tryLabel = new Label();
                    Label finallyLabel = new Label();
                    int lastLine = 0;
                    boolean newStack = classDefaultNewStack;
                    int stackVarIndex;
                    int stackPointerVarIndex;
                    int firstAdditionalLocal;
                    int additionalLocals;
                    Object[] replacedLocals;

                    public void visitInsn(int opcode) {
                        if (notransform) {
                            mv.visitInsn(opcode);
                            return;
                        }
                        if (opcode >= IRETURN && opcode <= RETURN && (newStack || checkStack)) {
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] restore stack pointer because of return at "
                                        + className.replace('/', '.') + "." + name + ":" + lastLine);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            if (newStack && !checkStack) {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "setPointer", "(I)V", false);
                            } else if (checkStack) {
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, className, "$checkStack$", "(II)V", false);
                            }
                        }
                        mv.visitInsn(opcode);
                    }

                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        if ("Lorg/lwjglx/autostack/UseCallerStack;".equals(desc)) {
                            if (!notransform) {
                                if (debugTransform)
                                    System.out.println("[autostack]     method declares to use caller stack");
                                newStack = false;
                            }
                            return null;
                        } else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc)) {
                            if (!notransform) {
                                if (debugTransform)
                                    System.out.println("[autostack]     method declares to use new stack");
                                newStack = true;
                            }
                            return null;
                        } else if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc)) {
                            return null;
                        } else if ("Lorg/lwjglx/autostack/NoStackParam;".equals(desc)) {
                            return null;
                        }
                        return mv.visitAnnotation(desc, visible);
                    }

                    public void visitVarInsn(int opcode, int var) {
                        if (notransform) {
                            mv.visitVarInsn(opcode, var);
                            return;
                        }
                        if (var >= firstAdditionalLocal)
                            var += additionalLocals;
                        mv.visitVarInsn(opcode, var);
                    }

                    public void visitIincInsn(int var, int increment) {
                        if (notransform) {
                            mv.visitIincInsn(var, increment);
                            return;
                        }
                        if (var >= firstAdditionalLocal)
                            var += additionalLocals;
                        mv.visitIincInsn(var, increment);
                    }

                    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
                        if (notransform) {
                            mv.visitFrame(type, nLocal, local, nStack, stack);
                            return;
                        }
                        if (type == F_FULL) {
                            int noThis = isStatic ? 0 : 1;
                            Object[] locals = new Object[local.length + additionalLocals];
                            if (!isStatic)
                                locals[0] = local[0];
                            int replacementLength = replacedLocals.length;
                            System.arraycopy(replacedLocals, noThis, locals, noThis,
                                    replacementLength - noThis);
                            int len = locals.length - replacementLength;
                            System.arraycopy(local, replacementLength - additionalLocals, locals,
                                    replacementLength, len);
                            mv.visitFrame(type, nLocal + additionalLocals, locals, nStack, stack);
                        } else
                            mv.visitFrame(type, nLocal, local, nStack, stack);
                    }

                    public void visitLocalVariable(String name, String desc, String signature, Label start,
                            Label end, int index) {
                        if (notransform) {
                            mv.visitLocalVariable(name, desc, signature, start, end, index);
                            return;
                        }
                        if (index >= firstAdditionalLocal)
                            index += additionalLocals;
                        mv.visitLocalVariable(name, desc, signature, start, end, index);
                    }

                    private boolean doesNotTakeStackItself(String desc) {
                        return desc.lastIndexOf("L" + MEMORYSTACK + ";)") == -1;
                    }

                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        String completeName = name + desc;
                        Integer info = stackMethods.get(completeName);
                        if (opcode != INVOKESTATIC || notransform) {
                            mv.visitMethodInsn(opcode, owner, name, desc, itf);
                            return;
                        }
                        if (stackAsParameter && info != null && (info.intValue() & 8) != 0
                                && (info.intValue() & 16) == 0) {
                            /* Rewrite invocation to have additional MemoryStack parameter */
                            if (debugTransform)
                                System.out.println(
                                        "[autostack]     rewrite invocation of " + owner.replace('/', '.') + "."
                                                + name + " at line " + lastLine + " --> "
                                                + owner.replace('/', '.') + "." + name + "(..., MemoryStack)");
                            int paramEndIndex = desc.indexOf(')');
                            String beforeDesc = desc.substring(0, paramEndIndex);
                            String afterDesc = desc.substring(paramEndIndex);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitMethodInsn(opcode, owner, name,
                                    beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, itf);
                            return;
                        }
                        if (owner.startsWith("org/lwjgl/")
                                && (name.equals("mallocStack") || name.equals("callocStack"))
                                && doesNotTakeStackItself(desc)) {
                            if (debugTransform)
                                System.out.println(
                                        "[autostack]     rewrite invocation of " + owner.replace('/', '.') + "."
                                                + name + " at line " + lastLine + " --> aload " + stackVarIndex
                                                + "; invokestatic " + owner.replace('/', '.') + "." + name);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            int paramEndIndex = desc.indexOf(')');
                            String beforeDesc = desc.substring(0, paramEndIndex);
                            String afterDesc = desc.substring(paramEndIndex);
                            mv.visitMethodInsn(opcode, owner, name,
                                    beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, false);
                        } else if (owner.equals(MEMORYSTACK) && name.equals("stackGet")) {
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.equals("stackPush") || name.equals("stackPop"))) {
                            String newName = "p" + name.substring(6);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.startsWith("stackMalloc") || name.startsWith("stackCalloc"))) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitInsn(SWAP);
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.startsWith("nstackMalloc") || name.startsWith("nstackCalloc"))) {
                            String newName = "n" + name.substring(6, 7).toLowerCase() + name.substring(7);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            if ("(I)J".equals(desc)) {
                                mv.visitInsn(SWAP);
                            } else {
                                // (II)J
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK) && (name.equals("stackASCII")
                                || name.equals("stackUTF8") || name.equals("stackUTF16"))) {
                            String newName = name.substring(5);
                            boolean withBoolean = desc.startsWith("(Ljava/lang/CharSequence;Z");
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            if (withBoolean) {
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                            } else {
                                mv.visitInsn(SWAP);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.equals("stackFloats") || name.equals("stackInts")
                                        || name.equals("stackBytes") || name.equals("stackShorts")
                                        || name.equals("stackPointers")
                                                && (desc.startsWith("([Lorg/lwjgl/system/Pointer;")
                                                        || desc.startsWith("(Lorg/lwjgl/system/Pointer;")))) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            Type[] argTypes = Type.getArgumentTypes(desc);
                            if (argTypes.length == 1 && argTypes[0].getSort() == Type.ARRAY) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 1) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 2) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 3) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP2_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                                mv.visitInsn(SWAP);
                                mv.visitInsn(POP);
                            } else {
                                if (debugTransform)
                                    System.out.println("[autostack]     failed to rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + ". Not yet implemented.");
                                /* Give up. Not possible without an additional local */
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, name, desc, itf);
                            }
                        } else if (owner.equals(MEMORYSTACK) && name.equals("stackLongs")) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            Type[] argTypes = Type.getArgumentTypes(desc);
                            if (argTypes.length == 1 && argTypes[0].getSort() == Type.ARRAY) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 1) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else {
                                if (debugTransform)
                                    System.out.println("[autostack]     failed to rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + ". Not yet implemented.");
                                /* Give up. Not possible without an additional local */
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, name, desc, itf);
                            }
                        } else {
                            mv.visitMethodInsn(opcode, owner, name, desc, itf);
                        }
                    }

                    public void visitLineNumber(int line, Label start) {
                        mv.visitLineNumber(line, start);
                        lastLine = line;
                    }

                    public void visitCode() {
                        if (notransform) {
                            mv.visitCode();
                            return;
                        }
                        additionalLocals = newStack || checkStack ? 2 : 1;
                        replacedLocals = new Object[paramTypes.length + additionalLocals + (isStatic ? 0 : 1)];
                        if (!newStack && !checkStack) {
                            replacedLocals[replacedLocals.length - 1] = MEMORYSTACK;
                        } else {
                            replacedLocals[replacedLocals.length - 2] = MEMORYSTACK;
                            replacedLocals[replacedLocals.length - 1] = INTEGER;
                        }
                        if (!isStatic)
                            replacedLocals[0] = isConstructor ? TOP : className;
                        int var = isStatic ? 0 : 1;
                        for (int t = 0, i = var; t < paramTypes.length; t++, i++) {
                            Type type = paramTypes[t];
                            var += type.getSize();
                            switch (type.getSort()) {
                            case Type.INT:
                            case Type.BYTE:
                            case Type.BOOLEAN:
                            case Type.SHORT:
                            case Type.CHAR:
                                replacedLocals[i] = INTEGER;
                                break;
                            case Type.LONG:
                                replacedLocals[i] = LONG;
                                break;
                            case Type.FLOAT:
                                replacedLocals[i] = FLOAT;
                                break;
                            case Type.DOUBLE:
                                replacedLocals[i] = DOUBLE;
                                break;
                            case Type.OBJECT:
                            case Type.ARRAY:
                                replacedLocals[i] = type.getInternalName();
                                break;
                            default:
                                throw new AssertionError("Unhandled parameter type: " + type);
                            }
                        }
                        firstAdditionalLocal = var;
                        stackVarIndex = var;
                        stackPointerVarIndex = var + 1;
                        mv.visitCode();
                        if (newStack && !checkStack || checkStack) {
                            if (!memoryStackParam) {
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet",
                                        "()L" + MEMORYSTACK + ";", false);
                                mv.visitInsn(DUP);
                                mv.visitVarInsn(ASTORE, stackVarIndex);
                            } else {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                            mv.visitVarInsn(ISTORE, stackPointerVarIndex);
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] save stack pointer [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString",
                                        "(I)Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("] at begin of " + className.replace('/', '.') + "." + name);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            mv.visitLabel(tryLabel);
                            if (!memoryStackParam)
                                mv.visitFrame(F_APPEND, 2, new Object[] { MEMORYSTACK, INTEGER }, 0, null);
                            else
                                mv.visitFrame(F_APPEND, 1, new Object[] { INTEGER }, 0, null);
                        } else if (!newStack && !checkStack) {
                            if (!memoryStackParam) {
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet",
                                        "()L" + MEMORYSTACK + ";", false);
                                mv.visitVarInsn(ASTORE, stackVarIndex);
                            }
                            if (debugRuntime) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] current stack pointer is [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString",
                                        "(I)Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("] at begin of " + className.replace('/', '.') + "." + name);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            mv.visitLabel(tryLabel);
                            if (!memoryStackParam)
                                mv.visitFrame(F_APPEND, 1, new Object[] { MEMORYSTACK }, 0, null);
                        }
                    }

                    public void visitMaxs(int maxStack, int maxLocals) {
                        if (notransform) {
                            mv.visitMaxs(maxStack, maxLocals);
                            return;
                        }
                        if (newStack && !checkStack || checkStack) {
                            mv.visitLabel(finallyLabel);
                            mv.visitFrame(F_FULL, replacedLocals.length, replacedLocals, 1,
                                    new Object[] { "java/lang/Throwable" });
                            mv.visitTryCatchBlock(tryLabel, finallyLabel, finallyLabel, null);
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] restore stack pointer because of throw [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitInsn(DUP);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString",
                                        "()Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn(
                                        "] at " + className.replace('/', '.') + "." + name + ":" + lastLine);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            if (newStack && !checkStack) {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "setPointer", "(I)V", false);
                            }
                            if (checkStack) {
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, className, "$checkStackWithThrowable$",
                                        "(Ljava/lang/Throwable;II)Ljava/lang/Throwable;", false);
                            }
                            mv.visitInsn(ATHROW);
                        }
                        mv.visitMaxs(-1, maxLocals + additionalLocals);
                    }
                };
                return mv;
            }
        }, 0);
        byte[] arr = cw.toByteArray();
        if (trace) {
            cr = new ClassReader(arr);
            cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
        }
        return arr;
    } catch (Throwable t) {
        t.printStackTrace();
        throw new RuntimeException(t);
    }
}

From source file:org.moditect.internal.analyzer.ServiceLoaderUseScanner.java

License:Apache License

private Set<String> getUsedServices(JarFile jarFile, JarEntry je) {
    Set<String> usedServices = new HashSet<>();

    try (InputStream classFile = jarFile.getInputStream(je)) {
        new ClassReader(classFile).accept(new ClassVisitor(Opcodes.ASM6) {

            @Override//from   w  w  w.  j  a  v  a 2  s .com
            public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                    String[] exceptions) {

                return new MethodVisitor(Opcodes.ASM6) {

                    private Type lastType;

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        if (owner.equals("java/util/ServiceLoader") && name.equals("load")) {
                            if (lastType == null) {
                                // TODO Log class/method
                                log.warn(
                                        "Cannot derive uses clause from service loader invocation with non constant class literal");
                            } else {
                                usedServices.add(lastType.getClassName());
                            }
                        }
                    }

                    @Override
                    public void visitLdcInsn(Object cst) {
                        if (cst instanceof Type) {
                            lastType = (Type) cst;
                        }
                    };
                };
            }
        }, 0);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    return usedServices;
}

From source file:org.moe.gradle.natj.NatJMethod.java

License:Apache License

/**
 * Returns a MethodVisitor used to initialize this object.
 *
 * @param api ASM API version/*from www.j a  v  a 2s .co m*/
 * @param consumer Consumer to invoke post-initialization.
 * @return MethodVisitor instance
 */
public MethodVisitor getInitializingVisitor(int api, Consumer<NatJMethod> consumer) {
    return new MethodVisitor(api) {
        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            if ("Lorg/moe/natj/general/ann/ByValue;".equals(desc)) {
                // Ignore
            } else if ("Lorg/moe/natj/general/ann/Generated;".equals(desc)) {
                isGenerated = true;
                // } else if ("Lorg/moe/natj/general/ann/MappedReturn;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/general/ann/NFloat;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/general/ann/NInt;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/general/ann/NUInt;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/general/ann/Owned;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/general/ann/ReferenceInfo;".equals(desc)) {
                //     // Ignore
            } else if ("Lorg/moe/natj/c/ann/CFunction;".equals(desc)) {
                isCFunction = true;
            } else if ("Lorg/moe/natj/c/ann/CVariable;".equals(desc)) {
                isCVariable = true;
                // } else if ("Lorg/moe/natj/c/ann/FunctionPtr;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/c/ann/Inline;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/c/ann/StructureField;".equals(desc)) {
                //     // Ignore
            } else if ("Lorg/moe/natj/c/ann/Variadic;".equals(desc)) {
                isVariadic = true;
            } else if ("Lorg/moe/natj/objc/ann/IBAction;".equals(desc)) {
                isIBAction = true;
            } else if ("Lorg/moe/natj/objc/ann/IBOutlet;".equals(desc)) {
                isIBOutlet = true;
            } else if ("Lorg/moe/natj/objc/ann/IBOutletCollection;".equals(desc)) {
                isIBOutletCollection = true;
            } else if ("Lorg/moe/natj/objc/ann/IsOptional;".equals(desc)) {
                isOptional = true;
            } else if ("Lorg/moe/natj/objc/ann/Property;".equals(desc)) {
                isProperty = true;
                // } else if ("Lorg/moe/natj/objc/ann/ProtocolClassMethod;".equals(desc)) {
                //     // Ignore
                // } else if ("Lorg/moe/natj/objc/ann/ObjCBlock;".equals(desc)) {
                //     // Ignore
            } else if ("Lorg/moe/natj/objc/ann/Selector;".equals(desc)) {
                return new AnnotationVisitor(api) {
                    @Override
                    public void visit(String name, Object value) {
                        if ("value".equals(name)) {
                            sel = (String) value;
                        }
                    }
                };
            }
            return null;
        }

        @Override
        public void visitEnd() {
            if (consumer != null) {
                consumer.accept(NatJMethod.this);
            }
        }
    };
}

From source file:org.pantsbuild.jarjar.EmptyClassVisitor.java

License:Apache License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    return new MethodVisitor(Opcodes.ASM5) {
    };/*from  w  w w .j a v  a  2s  .  c  o m*/
}

From source file:org.pantsbuild.jarjar.StringReader.java

License:Apache License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    MethodVisitor mv = new MethodVisitor(Opcodes.ASM5) {
        @Override//from   w  w  w  .ja va2  s  .  co  m
        public void visitLdcInsn(Object cst) {
            handleObject(cst);
        }

        @Override
        public void visitLineNumber(int line, Label start) {
            StringReader.this.line = line;
        }

        @Override
        public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
            for (Object bsmArg : bsmArgs)
                handleObject(bsmArg);
        }

        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            return StringReader.this.visitAnnotation(desc, visible);
        }

        @Override
        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
            return StringReader.this.visitAnnotation(desc, visible);
        }
    };
    return mv;
}

From source file:org.revapi.java.compilation.ClassTreeInitializer.java

License:Apache License

private void processClassBytes(final Archive currentArchive, InputStream data, final InitTreeContext context)
        throws IOException {

    ClassReader classReader = new ClassReader(data);

    classReader.accept(new ClassVisitor(Opcodes.ASM5) {

        private String visitedClassInternalName;
        private String visitedClassBinaryName;
        private String[] visitedClassOwners;
        private boolean isInnerClass;
        private int visitedInnerClassAccess;

        private TypeTreeConstructor.ClassProcessor classProcessor;

        @Override// www  . j  a  v a2 s. c o m
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {

            visitedClassInternalName = name;
            visitedClassBinaryName = Type.getObjectType(name).getClassName();

            boolean visible = isAccessible(access);
            boolean isPublicAPI = !context.processingSupplementaryArchives && visible;

            classProcessor = context.typeTreeConstructor.createApiClassProcessor(currentArchive,
                    visitedClassBinaryName, isPublicAPI);

            //add the superclass and interface use sites
            reportUse(Type.getObjectType(superName), UseSite.Type.IS_INHERITED, RawUseSite.SiteType.CLASS, null,
                    null, -1);

            for (String iface : interfaces) {
                reportUse(Type.getObjectType(iface), UseSite.Type.IS_IMPLEMENTED, RawUseSite.SiteType.CLASS,
                        null, null, -1);
            }

            if (name.indexOf('$') >= 0) {
                visitedClassOwners = name.split("\\$");
            }

            if (LOG.isTraceEnabled()) {
                LOG.trace("visit(): name={}, signature={}, access=0x{}", name, signature,
                        Integer.toHexString(access));
            }
        }

        @Override
        public FieldVisitor visitField(int access, final String name, final String desc, String signature,
                Object value) {
            //only consider public or protected fields - only those contribute to the API
            if (isAccessible(access)) {
                reportUse(Type.getType(desc), UseSite.Type.HAS_TYPE, RawUseSite.SiteType.FIELD, name, desc, -1);

                return new FieldVisitor(Opcodes.ASM5) {
                    @Override
                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        reportUse(Type.getType(desc), UseSite.Type.ANNOTATES, RawUseSite.SiteType.FIELD, name,
                                desc, -1);
                        return null;
                    }
                };
            }

            return null;
        }

        @Override
        public void visitInnerClass(String name, String outerName, String innerName, int access) {
            LOG.trace("Visiting inner class spec {} {}", innerName, outerName);

            boolean isThisClass = visitedClassInternalName.equals(name);

            if (isThisClass) {
                visitedInnerClassAccess = access;
            }

            isInnerClass = isInnerClass || isThisClass;

            if (isThisClass || isTransitiveOwnerOfVisitedClass(name)) {
                //visiting some outer class of the currently processed class
                classProcessor.getInnerClassHierarchyConstructor().addName(outerName, innerName);
            }
        }

        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            reportUse(Type.getType(desc), UseSite.Type.ANNOTATES, RawUseSite.SiteType.CLASS, null, null, -1);

            return null;
        }

        @Override
        public MethodVisitor visitMethod(int access, final String name, final String desc, String signature,
                String[] exceptions) {

            LOG.trace("Visiting method {} {}", name, desc);

            //only consider public or protected methods - only those contribute to the API
            if (isAccessible(access)) {

                Type[] argumentTypes = Type.getArgumentTypes(desc);

                reportUse(Type.getReturnType(desc), UseSite.Type.RETURN_TYPE, RawUseSite.SiteType.METHOD, name,
                        desc, -1);

                //instance inner classes synthesize their constructors to always have the enclosing type as the
                //first parameter. Ignore that parameter for usage reporting.
                int ai = isInnerClass && "<init>".equals(name)
                        && (visitedInnerClassAccess & Opcodes.ACC_STATIC) == 0 ? 1 : 0;

                while (ai < argumentTypes.length) {
                    Type t = argumentTypes[ai];
                    reportUse(t, UseSite.Type.PARAMETER_TYPE, RawUseSite.SiteType.METHOD_PARAMETER, name, desc,
                            ai++);
                }

                if (exceptions != null && exceptions.length > 0) {
                    for (String ex : exceptions) {
                        reportUse(Type.getObjectType(ex), UseSite.Type.IS_THROWN, RawUseSite.SiteType.METHOD,
                                name, desc, -1);
                    }
                }

                return new MethodVisitor(Opcodes.ASM5) {
                    @Override
                    public AnnotationVisitor visitAnnotation(String annotationDesc, boolean visible) {
                        reportUse(Type.getType(annotationDesc), UseSite.Type.ANNOTATES,
                                RawUseSite.SiteType.METHOD, name, desc, -1);
                        return null;
                    }

                    @Override
                    public AnnotationVisitor visitParameterAnnotation(int parameter, String parameterDesc,
                            boolean visible) {
                        reportUse(Type.getType(parameterDesc), UseSite.Type.ANNOTATES,
                                RawUseSite.SiteType.METHOD_PARAMETER, name, desc, parameter);
                        return null;
                    }
                };
            }

            return null;
        }

        @Override
        public void visitEnd() {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Visited {}, isInner={}, onlyAdditional={}", visitedClassInternalName, isInnerClass,
                        context.processingSupplementaryArchives);
            }

            classProcessor.commitClass();
        }

        private void reportUse(Type t, UseSite.Type useType, RawUseSite.SiteType siteType, String siteName,
                String siteDescriptor, int sitePosition) {

            if (skipUseTracking) {
                return;
            }

            if (t.getSort() < Type.ARRAY) {
                //primitive type
                return;
            }

            if (ignoreMissingAnnotations && useType == UseSite.Type.ANNOTATES) {
                return;
            }

            String binaryName = t.getClassName();
            RawUseSite useSite = new RawUseSite(useType, siteType, visitedClassBinaryName, siteName,
                    siteDescriptor, sitePosition);

            switch (t.getSort()) {
            case Type.OBJECT:
                classProcessor.addUse(binaryName, useSite);
                break;
            case Type.ARRAY:
                String desc = t.getDescriptor();
                desc = desc.substring(desc.lastIndexOf('[') + 1);
                reportUse(Type.getType(desc), useType, siteType, siteName, siteDescriptor, sitePosition);
                break;
            case Type.METHOD:
                throw new AssertionError("A method type should not enter here.");
                //all other cases are primitive types that we don't need to consider
            }
        }

        private boolean isTransitiveOwnerOfVisitedClass(String owningClass) {
            if (visitedClassOwners == null) {
                return false;
            }

            if (owningClass.length() > visitedClassInternalName.length()) {
                return false;
            }

            int startIdx = 0;
            int dollarIdx = owningClass.indexOf('$');
            int ownerIdx = 0;

            while (dollarIdx >= 0 && ownerIdx < visitedClassOwners.length) {
                String owner = owningClass.substring(startIdx, dollarIdx);
                if (!visitedClassOwners[ownerIdx++].equals(owner)) {
                    return false;
                }

                startIdx = dollarIdx + 1;
                dollarIdx = owningClass.indexOf('$', startIdx);
            }

            if (ownerIdx < visitedClassOwners.length) {
                return visitedClassOwners[ownerIdx].equals(owningClass.substring(startIdx));
            } else {
                return dollarIdx == -1;
            }
        }
    }, ClassReader.SKIP_CODE);
}

From source file:org.tomitribe.crest.maven.CrestCommandLoaderDescriptorGeneratorMojo.java

License:Apache License

private String commandName(final File classFile) throws IOException {
    try (InputStream stream = new FileInputStream(classFile)) {
        final ClassReader reader = new ClassReader(stream);
        reader.accept(new ClassVisitor(ASM5) {
            private String className;

            @Override/*from w w w.  jav a  2 s.  c o  m*/
            public void visit(final int version, final int access, final String name, final String signature,
                    final String superName, final String[] interfaces) {
                className = name.replace('/', '.');
            }

            @Override
            public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
                checkAnnotation(desc);
                return super.visitAnnotation(desc, visible);
            }

            @Override
            public MethodVisitor visitMethod(final int access, final String name, final String desc,
                    final String signature, final String[] exceptions) {
                return new MethodVisitor(ASM5) {
                    @Override
                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        checkAnnotation(desc);
                        return super.visitAnnotation(desc, visible);
                    }
                };
            }

            private void checkAnnotation(final String desc) {
                if (COMMAND_MARKER.equals(desc) || INTERCEPTOR_MARKER.equals(desc)) {
                    throw new CommandFoundException(className);
                }
            }
        }, SKIP_CODE + SKIP_DEBUG + SKIP_FRAMES);
    } catch (final CommandFoundException cfe) {
        return cfe.getMessage(); // class name
    }
    return null;
}