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:com.google.devtools.kythe.analyzers.jvm.KytheClassVisitor.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature,
        String[] exceptions) {//w w  w .j a  v a  2s.co m
    JvmGraph.Type.MethodType methodType = JvmGraph.Type.rawMethodType(desc);
    VName methodVName = jvmGraph.emitMethodNode(classType, methodName, methodType);
    entrySets.emitEdge(methodVName, EdgeKind.CHILDOF, classVName);

    return new MethodVisitor(ASM_API_LEVEL) {
        private int parameterIndex = 0;

        @Override
        public void visitParameter(String parameterName, int access) {
            VName parameterVName = jvmGraph.emitParameterNode(classType, methodName, methodType,
                    parameterIndex);
            entrySets.emitEdge(parameterVName, EdgeKind.CHILDOF, methodVName);
            entrySets.emitEdge(methodVName, EdgeKind.PARAM, parameterVName, parameterIndex);

            parameterIndex++;
            super.visitParameter(parameterName, access);
        }
    };
}

From source file:com.igormaznitsa.jute.TestClassProcessor.java

License:Apache License

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
        final String[] exceptions) {
    if (this.inappropriateClass) {
        return null;
    }//from   w  ww.ja v  a2s.  com

    if (((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE | Opcodes.ACC_STATIC)) != 0)
            || !desc.equals("()V") || name.startsWith("<")) {
        return null;
    }
    final boolean foundInExcludedList = isTestIncluded(desc);
    final boolean testExcluded = isTestExcluded(desc);

    final String logTestName = this.className + '#' + name;

    if (!foundInExcludedList) {
        this.logger.info("Test method " + logTestName + " is ignored because not presented in include list");
        return null;
    }

    if (testExcluded) {
        this.logger.info("Test " + logTestName + " is ignored because presented in exclude list");
        return null;
    }

    return new MethodVisitor(Opcodes.ASM5) {
        private boolean junitTest;
        private boolean juteTest;
        private boolean junitIgnore;
        private TestContainer detectedMethod;

        @Override
        public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
            if (detectedMethod == null) {
                detectedMethod = new TestContainer(classFilePath, className, name,
                        clazzJuteTestParameters == null ? baseParameters : clazzJuteTestParameters, null);
            }

            AnnotationVisitor result = null;
            if (desc.equals(JuteMojo.ANNO_TEST)) {
                this.junitTest = true;
            } else if (desc.equals(JuteMojo.ANNO_IGNORE)) {
                this.junitIgnore = true;
            } else if (desc.equals(JuteMojo.ANNO_JUTE)) {
                this.juteTest = true;
                result = detectedMethod;
            }
            return result;
        }

        @Override
        public void visitEnd() {
            if (this.detectedMethod == null) {
                this.detectedMethod = new TestContainer(classFilePath, className, name,
                        clazzJuteTestParameters == null ? baseParameters : clazzJuteTestParameters, null);
            }
            this.juteTest = this.juteTest || clazzJuteTestParameters != null;

            this.detectedMethod.setJUnitIgnore(this.junitIgnore);
            this.detectedMethod.setJUnitTest(this.junitTest);
            this.detectedMethod.setJuteTest(this.juteTest);

            if ((this.junitTest || this.juteTest)
                    && Utils.checkClassAndMethodForPattern(juteTestParameter,
                            this.detectedMethod.getClassName(), this.detectedMethod.getMethodName(), false)
                    && isTestCanBeListed(this.detectedMethod)) {
                detectedTestMethodList.add(detectedMethod);
            }
        }
    };
}

From source file:com.tonicsystems.jarjar.EmptyClassVisitor.java

License:Apache License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    return new MethodVisitor(Opcodes.ASM4) {
    };//from w  w  w .  j  av a2s  .c o  m
}

From source file:com.tonicsystems.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.ASM4) {
        @Override//  w  w  w  . j  a  va 2  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:com.tonicsystems.jarjar.strings.StringReader.java

License:Apache License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    return new MethodVisitor(Opcodes.ASM5) {
        @Override/* w ww.j  a v  a  2 s. c o  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);
        }
    };
}

From source file:de.thetaphi.forbiddenapis.ClassScanner.java

License:Apache License

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature,
        String[] exceptions) {/*from www  .j  a  v a 2s .  c o  m*/
    currentGroupId++;
    if (classSuppressed) {
        return null;
    }
    return new MethodVisitor(Opcodes.ASM5) {
        private final Method myself = new Method(name, desc);
        private final boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0;
        private int lineNo = -1;

        {
            // only check signature, if method is not synthetic
            if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
                reportMethodViolation(checkDescriptor(desc), "method declaration");
            }
            if (this.isDeprecated) {
                maybeSuppressCurrentGroup(DEPRECATED_TYPE);
                reportMethodViolation(checkType(DEPRECATED_TYPE), "deprecation on method declaration");
            }
        }

        private String checkMethodAccess(String owner, Method method) {
            String violation = checkClassUse(owner, "class/interface");
            if (violation != null) {
                return violation;
            }
            final String printout = forbiddenMethods.get(owner + '\000' + method);
            if (printout != null) {
                return "Forbidden method invocation: " + printout;
            }
            final ClassSignature c = lookup.lookupRelatedClass(owner);
            if (c != null && !c.methods.contains(method)) {
                if (c.superName != null && (violation = checkMethodAccess(c.superName, method)) != null) {
                    return violation;
                }
                // JVM spec says: interfaces after superclasses
                if (c.interfaces != null) {
                    for (String intf : c.interfaces) {
                        if (intf != null && (violation = checkMethodAccess(intf, method)) != null) {
                            return violation;
                        }
                    }
                }
            }
            return null;
        }

        private String checkFieldAccess(String owner, String field) {
            String violation = checkClassUse(owner, "class/interface");
            if (violation != null) {
                return violation;
            }
            final String printout = forbiddenFields.get(owner + '\000' + field);
            if (printout != null) {
                return "Forbidden field access: " + printout;
            }
            final ClassSignature c = lookup.lookupRelatedClass(owner);
            if (c != null && !c.fields.contains(field)) {
                if (c.interfaces != null) {
                    for (String intf : c.interfaces) {
                        if (intf != null && (violation = checkFieldAccess(intf, field)) != null) {
                            return violation;
                        }
                    }
                }
                // JVM spec says: superclasses after interfaces
                if (c.superName != null && (violation = checkFieldAccess(c.superName, field)) != null) {
                    return violation;
                }
            }
            return null;
        }

        private String checkHandle(Handle handle, boolean checkLambdaHandle) {
            switch (handle.getTag()) {
            case Opcodes.H_GETFIELD:
            case Opcodes.H_PUTFIELD:
            case Opcodes.H_GETSTATIC:
            case Opcodes.H_PUTSTATIC:
                return checkFieldAccess(handle.getOwner(), handle.getName());
            case Opcodes.H_INVOKEVIRTUAL:
            case Opcodes.H_INVOKESTATIC:
            case Opcodes.H_INVOKESPECIAL:
            case Opcodes.H_NEWINVOKESPECIAL:
            case Opcodes.H_INVOKEINTERFACE:
                final Method m = new Method(handle.getName(), handle.getDesc());
                if (checkLambdaHandle && handle.getOwner().equals(internalMainClassName)
                        && handle.getName().startsWith(LAMBDA_METHOD_NAME_PREFIX)) {
                    // as described in <http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html>,
                    // we will record this metafactory call as "lambda" invokedynamic,
                    // so we can assign the called lambda with the same groupId like *this* method:
                    lambdas.put(m, currentGroupId);
                }
                return checkMethodAccess(handle.getOwner(), m);
            }
            return null;
        }

        private String checkConstant(Object cst, boolean checkLambdaHandle) {
            if (cst instanceof Type) {
                return checkType((Type) cst);
            } else if (cst instanceof Handle) {
                return checkHandle((Handle) cst, checkLambdaHandle);
            }
            return null;
        }

        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            if (this.isDeprecated && DEPRECATED_DESCRIPTOR.equals(desc)) {
                // don't report 2 times!
                return null;
            }
            final Type type = Type.getType(desc);
            maybeSuppressCurrentGroup(type);
            reportMethodViolation(checkAnnotationDescriptor(type, visible), "annotation on method declaration");
            return null;
        }

        @Override
        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "parameter annotation on method declaration");
            return null;
        }

        @Override
        public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc,
                boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "type annotation on method declaration");
            return null;
        }

        @Override
        public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc,
                boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "annotation in method body");
            return null;
        }

        @Override
        public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start,
                Label[] end, int[] index, String desc, boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "annotation in method body");
            return null;
        }

        @Override
        public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc,
                boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "annotation in method body");
            return null;
        }

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
            reportMethodViolation(checkMethodAccess(owner, new Method(name, desc)), "method body");
        }

        @Override
        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
            reportMethodViolation(checkFieldAccess(owner, name), "method body");
        }

        @Override
        public void visitTypeInsn(int opcode, String type) {
            if (opcode == Opcodes.ANEWARRAY) {
                reportMethodViolation(checkType(Type.getObjectType(type)), "method body");
            }
        }

        @Override
        public void visitMultiANewArrayInsn(String desc, int dims) {
            reportMethodViolation(checkDescriptor(desc), "method body");
        }

        @Override
        public void visitLdcInsn(Object cst) {
            reportMethodViolation(checkConstant(cst, false), "method body");
        }

        @Override
        public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
            final boolean isLambdaMetaFactory = LAMBDA_META_FACTORY_INTERNALNAME.equals(bsm.getOwner());
            reportMethodViolation(checkHandle(bsm, false), "method body");
            for (final Object cst : bsmArgs) {
                reportMethodViolation(checkConstant(cst, isLambdaMetaFactory), "method body");
            }
        }

        private String getHumanReadableMethodSignature() {
            final Type[] args = Type.getType(myself.getDescriptor()).getArgumentTypes();
            final StringBuilder sb = new StringBuilder(myself.getName()).append('(');
            boolean comma = false;
            for (final Type t : args) {
                if (comma)
                    sb.append(',');
                sb.append(t.getClassName());
                comma = true;
            }
            sb.append(')');
            return sb.toString();
        }

        private void reportMethodViolation(String violation, String where) {
            if (violation != null) {
                violations.add(new ForbiddenViolation(currentGroupId, myself, violation,
                        String.format(Locale.ENGLISH, "%s of '%s'", where, getHumanReadableMethodSignature()),
                        lineNo));
            }
        }

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

From source file:edu.umd.cs.findbugs.classfile.engine.SelfMethodCalls.java

License:Open Source License

public static <T> MultiMap<T, T> getSelfCalls(final ClassDescriptor classDescriptor,
        final Map<String, T> methods) {
    final MultiMap<T, T> map = new MultiMap<T, T>(HashSet.class);

    FBClassReader reader;/*  ww w.  j a v  a 2  s  .  c o  m*/
    try {
        reader = Global.getAnalysisCache().getClassAnalysis(FBClassReader.class, classDescriptor);
    } catch (CheckedAnalysisException e) {
        AnalysisContext.logError("Error finding self method calls for " + classDescriptor, e);
        return map;
    }
    reader.accept(new ClassVisitor(FindBugsASM.ASM_VERSION) {

        @Override
        public MethodVisitor visitMethod(final int access, final String name, final String desc,
                String signature, String[] exceptions) {
            return new MethodVisitor(FindBugsASM.ASM_VERSION) {
                @Override
                public void visitMethodInsn(int opcode, String owner, String name2, String desc2, boolean itf) {
                    if (owner.equals(classDescriptor.getClassName()) && interestingSignature(desc2)) {
                        T from = methods.get(name + desc + ((access & Opcodes.ACC_STATIC) != 0));
                        T to = methods.get(name2 + desc2 + (opcode == Opcodes.INVOKESTATIC));
                        map.add(from, to);
                    }

                }

            };
        }

    }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
    return map;
}

From source file:javadepchecker.Main.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    for (Type param : Type.getArgumentTypes(desc)) {
        addDep(param);/*w ww.  java 2s .c  o  m*/
    }

    if (exceptions != null) {
        for (String exception : exceptions) {
            addDep(exception);
        }
    }
    addDep(Type.getReturnType(desc));
    return new MethodVisitor(Opcodes.ASM5) {
        @Override
        public void visitLocalVariable(String name, String desc, String signature, Label start, Label end,
                int index) {
            addDep(Type.getType(desc));
        }

        @Override
        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
            addDep(Type.getObjectType(owner));
            addDep(Type.getType(desc));
        }

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
            addDep(Type.getObjectType(owner));
        }

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

From source file:net.nexustools.jvm.compiler.Compiler.java

License:Open Source License

public void compile(String rawClassname) throws IOException {
    if (processed.contains(rawClassname))
        return;//  www .j  a va2 s  . c o m
    processed.add(rawClassname);

    System.out.println("Resolving class " + rawClassname);

    final String classname, runtimeClassname = convertRuntime(rawClassname);

    for (String builtin : BUILT_IN)
        if (builtin.equals(runtimeClassname)) {
            usedbuiltins.add(builtin);
            return; // Skip
        }

    if (javaClass.matcher(rawClassname).find())
        classname = "net/nexustools/jvm/runtime/" + rawClassname;
    else
        classname = rawClassname;

    File findFile = resolve(classname + ".class");
    ClassReader reader;

    try {
        if (findFile.exists()) {
            if (!classname.equals(rawClassname)) {
                if (processed.contains(classname))
                    return;

                processed.add(classname);
            }

            reader = new ClassReader(new FileInputStream(findFile));
        } else {
            throw new CompileError("No implementation found: " + classname);
            //reader = new ClassReader(rawClassname);
            //System.err.println("\tUsing system provided class impl");
        }
    } catch (IOException ex) {
        throw new CompileError(ex);
    }

    int offset = outputFolder.getPath().length() + 1;
    File output = resolveOutput(findFile, runtimeClassname + ".js");
    File parentFile = output.getParentFile();
    if (!parentFile.isDirectory() && !parentFile.mkdirs())
        throw new RuntimeException("Cannot create directory: " + parentFile);

    File nativeFile = resolve(classname + ".native.js");
    if (nativeFile.exists()) {
        File outputResolvedPath = new File(parentFile, nativeFile.getName());
        copy(new FileInputStream(nativeFile), new FileOutputStream(outputResolvedPath));
        natives.add(outputResolvedPath.getPath().substring(offset));
    }
    compiled.add(output.getPath().substring(offset));

    final List<String> references = new ArrayList();
    final Referencer referencer = new Referencer() {
        @Override
        public boolean add(String reference) {
            reference = convertRuntime(reference);

            if (references.contains(reference))
                return false;
            references.add(reference);

            return true;
        }
    };
    final SignatureConverter converter = new SignatureConverter() {
        @Override
        public String convert(String input) {
            String ref = input;
            while (ref.startsWith("["))
                ref = ref.substring(1);

            if (ref.startsWith("L") && ref.endsWith(";"))
                referencer.add(ref.substring(1, ref.length() - 1));
            else if (ref.length() > 1)
                referencer.add(ref);

            return convertSignature(input);
        }
    };

    final OutputStreamWriter oSw = new OutputStreamWriter(new FileOutputStream(output));

    final BufferedWriter bw = new BufferedWriter(oSw);

    try {
        bw.append("(function JVM_");
        bw.append(runtimeClassname.replaceAll("\\W", "_"));
        bw.append("($JVM, JVM){\n\t$JVM.ClassLoader.defineClass(\"");
        bw.append(runtimeClassname);
        bw.append("\", [");

        String[] interfaces = reader.getInterfaces();
        references.addAll(Arrays.asList(interfaces));
        for (int i = 0; i < interfaces.length; i++) {
            if (i > 0)
                bw.append(',');
            bw.append('\"');
            bw.append(convertRuntime(interfaces[i]));
            bw.append('\"');
        }

        bw.append("], ");
        String parent = reader.getSuperName();
        if (parent != null && !references.contains(parent)) {
            bw.append('\"');
            bw.append(convertRuntime(parent));
            bw.append('\"');
            references.add(parent);
        } else
            bw.append("null");
        bw.append(", [\n");

        final List<String> fields = new ArrayList();
        final List<String> methods = new ArrayList();
        System.out.println("\tVisiting class " + classname);

        final int[] methodAccess = new int[1];
        final MethodVisitor methodVisitor = new MethodVisitor(Opcodes.ASM4) {

            @Override
            public void visitEnd() {
                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"end\"\n");
                    bw.append("\t\t\t\t}\n");

                    bw.append("\t\t\t],\n");

                    writeAccess(methodAccess[0], bw);

                    bw.append("\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
                System.out.println(
                        "\t\t\tvisitTryCatchBlock: " + start + ", " + end + ", " + handler + ", " + type);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"try\",\n");

                    bw.append("\t\t\t\t\t\"start\": \"");
                    bw.append(start.toString());
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"end\": \"");
                    bw.append(end.toString());
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"handler\": \"");
                    bw.append(handler.toString());
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"catch\": \"");
                    bw.append(type);
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                System.out.println("\t\t\tvisitMethodInsn: " + nameForOpcode(opcode) + ", " + owner + ", "
                        + name + ", " + desc + ", " + itf);

                /*if(name.equals("<init>") && desc.equals("()V") && runtimeClassname.equals("java/lang/Object")) {
                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"initobject\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
                        
                return;
                }*/

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"method\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"owner\": ");
                    bw.append(converter.convert(owner));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"name\": \"");
                    bw.append(name);
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"signature\": {\n");
                    bw.append("\t\t\t\t\t\t\"raw\": \"");
                    bw.append(convertRuntime(desc));
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\t\"return\": ");

                    Matcher matcher = methodSignature.matcher(desc);
                    if (!matcher.matches())
                        throw new IllegalArgumentException("Corrupt or invalid method signature: " + desc);

                    bw.append(converter.convert(matcher.group(2)));
                    bw.append(",\n");

                    String args = matcher.group(1);
                    if (args != null) {
                        bw.append("\t\t\t\t\t\t\"args\": [\n");

                        String[] argsl = splitArguments(args);
                        /*matcher = classSignature.matcher(args);
                        while(matcher.find())
                        argsl.add(converter.convert(matcher.group(1)));*/

                        for (int i = 0; i < argsl.length; i++) {
                            bw.append("\t\t\t\t\t\t\t");
                            bw.append(converter.convert(argsl[i]));
                            if (i < argsl.length - 1)
                                bw.append(',');
                            bw.append('\n');
                        }

                        bw.append("\t\t\t\t\t\t]\n");
                    } else
                        bw.append("\t\t\t\t\t\t\"args\": []\n");
                    bw.append("\t\t\t\t\t},\n");

                    bw.append("\t\t\t\t\t\"interface\": ");
                    bw.append(itf ? "true" : "false");
                    bw.append("\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
                System.out.println("\t\t\tvisitTableSwitchInsn: " + min + ", " + max + ", " + dflt + ", "
                        + Arrays.toString(labels));

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"tableSwitch\",\n");

                    bw.append("\t\t\t\t\t\"min\": \"");
                    bw.append(String.valueOf(min));
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"max\": \"");
                    bw.append(String.valueOf(max));
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"default\": \"");
                    bw.append(dflt.toString());
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"jumps\": [\n");
                    for (int i = 0; i < labels.length; i++) {
                        bw.append("\t\t\t\t\t\t\"");
                        bw.append(labels[i].toString());
                        bw.append('"');
                        if (i < labels.length - 1)
                            bw.append(',');
                        bw.append('\n');
                    }
                    bw.append("\t\t\t\t\t]\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitMultiANewArrayInsn(String desc, int dims) {
                System.out.println("\t\t\tvisitMultiANewArrayInsn: " + desc + ", " + dims);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"array\",\n");

                    bw.append("\t\t\t\t\t\"desc\": \"");
                    bw.append(desc);
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"size\": \"");
                    bw.append(String.valueOf(dims));
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitIincInsn(int var, int increment) {
                System.out.println("\t\t\tvisitIincInsn: " + var + ", " + increment);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"iinc\",\n");

                    bw.append("\t\t\t\t\t\"index\": \"");
                    bw.append(String.valueOf(var));
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"by\": \"");
                    bw.append(String.valueOf(increment));
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
                System.out.println("\t\t\tvisitLookupSwitchInsn: " + dflt + ", " + Arrays.toString(keys) + ", "
                        + Arrays.toString(labels));

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"switch\",\n");

                    if (dflt != null) {
                        bw.append("\t\t\t\t\t\"default\": \"");
                        bw.append(dflt.toString());
                        bw.append("\",\n");
                    }

                    bw.append("\t\t\t\t\t\"keys\": [\n");
                    for (int i = 0; i < keys.length; i++) {
                        bw.append("\t\t\t\t\t\t");
                        bw.append(String.valueOf(keys[i]));
                        if (i < keys.length - 1)
                            bw.append(',');
                        bw.append('\n');
                    }
                    bw.append("\t\t\t\t\t],\n");

                    bw.append("\t\t\t\t\t\"jumps\": [\n");
                    for (int i = 0; i < labels.length; i++) {
                        bw.append("\t\t\t\t\t\t\"");
                        bw.append(labels[i].toString());
                        bw.append('"');
                        if (i < labels.length - 1)
                            bw.append(',');
                        bw.append('\n');
                    }
                    bw.append("\t\t\t\t\t]\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitLocalVariable(String name, String desc, String signature, Label start, Label end,
                    int index) {
                System.out.println("\t\t\tvisitLocalVariable: " + name + ", " + desc + ", " + start + ", " + end
                        + ", " + index);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"declare\",\n");

                    bw.append("\t\t\t\t\t\"name\": \"");
                    bw.append(String.valueOf(name));
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"signature\": ");
                    bw.append(converter.convert(desc));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"index\": \"");
                    bw.append(String.valueOf(index));
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"start\": \"");
                    bw.append(start.toString());
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"end\": \"");
                    bw.append(end.toString());
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitParameter(String name, int access) {
                System.out.println("\t\t\tvisitParameter: " + name + ", " + access);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"arg\",\n");

                    bw.append("\t\t\t\t\t\"name\": \"");
                    bw.append(name);
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"access\": \"");
                    bw.append(String.valueOf(access));
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitVarInsn(int opcode, int var) {
                System.out.println("\t\t\tvisitVarInsn: " + nameForOpcode(opcode) + ", " + var);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"var\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"index\": \"");
                    bw.append(String.valueOf(var));
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitTypeInsn(int opcode, String type) {
                System.out.println("\t\t\tvisitTypeInsn: " + nameForOpcode(opcode) + ", " + type);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"type\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"signature\": ");
                    bw.append(converter.convert(type));
                    bw.append('\n');
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitLdcInsn(Object cst) {
                System.out.println("\t\t\tvisitLdcInsn: " + cst);
                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"ldc\",\n");

                    if (cst instanceof String) {
                        bw.append("\t\t\t\t\t\"stringValue\": ");
                        bw.append(new Gson().toJson((String) cst));
                        bw.append("\n");
                    } else if (cst instanceof Number) {
                        bw.append("\t\t\t\t\t\"numericValue\": ");
                        bw.append(String.valueOf((Number) cst));
                        bw.append("\n");
                    } else if (cst instanceof org.objectweb.asm.Type) {
                        org.objectweb.asm.Type type = (org.objectweb.asm.Type) cst;
                        switch (type.getSort()) {
                        case Type.OBJECT:
                            System.out.println("OBJECT REFERENCE");
                            String ref = type.getInternalName();
                            bw.append("\t\t\t\t\t\"objectRef\": ");
                            bw.append(converter.convert(ref));
                            bw.append("\n");
                            break;

                        default:
                            throw new UnsupportedOperationException("Cannot handle type: " + type.getSort());
                        }

                        /*System.out.println("asm type: " + type.getInternalName());
                        System.out.println(type.getReturnType());
                        System.out.println(type.getDescriptor());
                        System.out.println(type.getElementType());
                        System.out.println(type.getDimensions());
                        System.out.println(type.getClassName());
                                
                        throw new UnsupportedOperationException("Cannot handle types yet...");*/
                    } else
                        throw new UnsupportedOperationException(
                                "Unsupported type for LDC: " + cst.getClass().getName());

                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
                throw new UnsupportedOperationException();

                /*System.out.println("\t\t\tvisitInvokeDynamicInsn: " + name + ", " + desc + ", " + bsm + ", " + Arrays.toString(bsmArgs));
                        
                try {
                bw.append("\t\t\t\t{\n");
                bw.append("\t\t\t\t\t\"type\": \"invokeDynamic\",\n");
                        
                bw.append("\t\t\t\t\t\"name\": \"");
                bw.append(name);
                bw.append("\",\n");
                        
                bw.append("\t\t\t\t\t\"signature\": \"");
                bw.append(desc);
                bw.append("\"\n");
                bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                throw new RuntimeException(ex);
                }*/
            }

            @Override
            public void visitLabel(Label label) {
                System.out.println("\t\t\tvisitLabel: " + label.toString());

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"label\",\n");

                    bw.append("\t\t\t\t\t\"name\": \"");
                    bw.append(label.toString());
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitJumpInsn(int opcode, Label label) {
                System.out.println("\t\t\tvisitJumpInsn: " + nameForOpcode(opcode) + ", " + label.toString());

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"jump\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"name\": \"");
                    bw.append(label.toString());
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitInsn(int opcode) {
                System.out.println("\t\t\tvisitInsn: " + nameForOpcode(opcode));

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"insn\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append("\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitIntInsn(int opcode, int operand) {
                System.out.println("\t\t\tvisitIntInsn: " + nameForOpcode(opcode) + ", " + operand);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"int\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"operand\": \"");
                    bw.append(String.valueOf(operand));
                    bw.append("\"\n");
                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }

            @Override
            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                System.out.println("\t\t\tvisitFieldInsn: " + nameForOpcode(opcode) + ", " + owner + ", " + name
                        + ", " + desc);

                try {
                    bw.append("\t\t\t\t{\n");
                    bw.append("\t\t\t\t\t\"type\": \"field\",\n");

                    bw.append("\t\t\t\t\t\"opcode\": JVM.Opcodes.");
                    bw.append(nameForOpcode(opcode));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"class\": ");
                    bw.append(converter.convert(owner));
                    bw.append(",\n");

                    bw.append("\t\t\t\t\t\"name\": \"");
                    bw.append(name);
                    bw.append("\",\n");

                    bw.append("\t\t\t\t\t\"signature\": ");
                    bw.append(converter.convert(desc));
                    bw.append('\n');

                    bw.append("\t\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        };

        final ClassOptimizer[] classOptimizer = new ClassOptimizer[1];
        ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM4) {

            @Override
            public FieldVisitor visitField(int access, String name, String desc, String signature,
                    Object value) {
                System.out.println("\t\tField: " + name + ", " + desc + ", " + value + ", " + access);
                if (!fields.contains(name)) {
                    fields.add(name);
                }

                try {
                    bw.append("\t\t{\n");

                    bw.append("\t\t\t\"type\": \"field\",\n");

                    bw.append("\t\t\t\"name\": \"");
                    bw.append(name);
                    bw.append("\",\n");

                    bw.append("\t\t\t\"signature\": ");
                    bw.append(converter.convert(desc));
                    bw.append(",\n");

                    if (value instanceof String) {
                        bw.append("\t\t\t\"stringValue\": \"");
                        bw.append(((String) value).replace("\n", "\\n").replace("\"", "\\\""));
                        bw.append("\",\n");
                    } else if (value instanceof Number) {
                        bw.append("\t\t\t\"numericValue\": ");
                        bw.append(String.valueOf((Number) value));
                        bw.append(",\n");
                    } else if (value != null)
                        throw new RuntimeException("Unhandled initial value: " + value);

                    writeAccess(access, bw);
                    bw.append("\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }

                //if(signature != null) {
                Matcher matcher = classSignature.matcher(desc);
                if (matcher.matches() && !references.contains(matcher.group(1)))
                    references.add(matcher.group(1));
                //}

                return super.visitField(access, name, desc, signature, value);
            }

            @Override
            public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                    String[] exceptions) {
                System.out.println("\t\tMethod: " + name + ", " + desc + ", " + signature + ", " + access + ", "
                        + Arrays.toString(exceptions));
                if (!methods.contains(name))
                    methods.add(name);

                try {
                    bw.append("\t\t{\n");

                    bw.append("\t\t\t\"type\": \"method\",\n");

                    bw.append("\t\t\t\"name\": \"");
                    bw.append(name);
                    bw.append("\",\n");

                    bw.append("\t\t\t\"signature\": \"");
                    bw.append(convertRuntime(desc));
                    bw.append("\",\n");

                    bw.append("\t\t\t\"sigparts\": {\n");
                    bw.append("\t\t\t\t\"return\": ");

                    Matcher matcher = methodSignature.matcher(desc);
                    if (!matcher.matches())
                        throw new IllegalArgumentException("Corrupt or invalid method signature: " + desc);

                    bw.append(converter.convert(matcher.group(2)));
                    bw.append(",\n");

                    String args = matcher.group(1);
                    if (args != null) {
                        bw.append("\t\t\t\t\"args\": [\n");

                        String[] argsl = splitArguments(args);
                        /*matcher = classSignature.matcher(args);
                        while(matcher.find())
                        argsl.add(converter.convert(matcher.group(1)));*/

                        for (int i = 0; i < argsl.length; i++) {
                            bw.append("\t\t\t\t\t");
                            bw.append(converter.convert(argsl[i]));
                            if (i < argsl.length - 1)
                                bw.append(',');
                            bw.append('\n');
                        }

                        bw.append("\t\t\t\t]\n");
                    } else
                        bw.append("\t\t\t\t\"args\": []\n");
                    bw.append("\t\t\t},\n");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }

                if (exceptions != null) {
                    try {
                        bw.append("\t\t\t\"exceptions\": [\n");
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }

                    for (int i = 0; i < exceptions.length; i++) {
                        String exception = exceptions[i];
                        if (!references.contains(exception))
                            references.add(exception);

                        try {
                            bw.append("\t\t\t\t\"");
                            bw.append(convertRuntime(exception));
                            bw.append('"');
                            if (i < exceptions.length - 1)
                                bw.append(',');
                            bw.append('\n');
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                    }

                    try {
                        bw.append("\t\t\t],\n");
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                }

                Matcher matcher = methodSignature.matcher(desc);
                matcher.matches();
                String args = matcher.group(1);
                String ret = matcher.group(2);

                matcher = classSignature.matcher(ret);
                if (matcher.matches() && !references.contains(matcher.group(1)))
                    references.add(matcher.group(1));

                if (args != null) {
                    matcher = classSignature.matcher(args);
                    while (matcher.find())
                        if (!references.contains(matcher.group(1)))
                            references.add(matcher.group(1));
                }

                if ((access & Opcodes.ACC_NATIVE) != 0) {
                    try {
                        bw.append("\t\t\t\"implementation\": \"");
                        bw.append(runtimeClassname + ".native.js");
                        bw.append("\",\n");

                        writeAccess(access, bw);
                        bw.append("\t\t},\n");
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }

                    return super.visitMethod(access, name, desc, signature, exceptions);
                }

                try {
                    bw.append("\t\t\t\"implementation\": [\n");
                    bw.flush();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }

                methodAccess[0] = access;
                //return new MethodOptimizer(classOptimizer[0], access, desc, methodVisitor, new Remapper() {});
                return methodVisitor;
            }
        };

        //classOptimizer[0] = new ClassOptimizer(classVisitor, new Remapper() {});
        //reader.accept(classOptimizer[0], 0);
        reader.accept(classVisitor, 0);

        bw.append("\t\t{\n");
        bw.append("\t\t\t\"type\": \"references\",\n");
        bw.append("\t\t\t\"value\": [\n");

        List<String> written = new ArrayList();
        for (int i = 0; i < references.size(); i++) {
            String ref = convertRuntime(references.get(i));
            if (written.contains(ref))
                continue;
            written.add(ref);

            bw.append("\t\t\t\t\"");
            bw.append(ref);
            bw.append('"');
            if (i < references.size() - 1)
                bw.append(',');
            bw.append('\n');
        }
        bw.append("\t\t\t]\n");
        bw.append("\t\t}\n");
        bw.append("\t]);\n");
        bw.append("})($currentJVM, JVM);");
    } finally {
        bw.close();
    }

    System.out.println("\tProcessing references: " + references);
    for (String ref : references)
        compile(ref);

    referenceMap.put(runtimeClassname, references);
}

From source file:net.yrom.tools.RSymbols.java

License:Apache License

private void drainSymbols(Path file) {
    final String filename = file.getFileName().toString();
    String typeName = filename.substring(0, filename.length() - ".class".length());
    byte[] bytes;
    try {/*ww  w  .j  av a 2  s.com*/
        bytes = Files.readAllBytes(file);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    ClassVisitor visitor = new ClassVisitor(Opcodes.ASM5) {
        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            // read constant value
            if (value instanceof Integer) {
                String key = typeName + '.' + name;
                Integer old = symbols.get(key);
                if (old != null && !old.equals(value)) {
                    throw new IllegalStateException("Value of " + key + " mismatched! " + "Excepted 0x"
                            + Integer.toHexString(old) + " but was 0x" + Integer.toHexString((Integer) value));
                } else {
                    symbols.put(key, (Integer) value);
                }
            }
            return null;
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            if (access == Opcodes.ACC_STATIC && "<clinit>".equals(name)) {

                return new MethodVisitor(Opcodes.ASM5) {
                    int[] current = null;
                    LinkedList<Integer> intStack = new LinkedList<>();

                    @Override
                    public void visitIntInsn(int opcode, int operand) {
                        if (opcode == Opcodes.NEWARRAY && operand == Opcodes.T_INT) {
                            current = new int[intStack.pop()];
                        } else if (opcode == Opcodes.BIPUSH) {
                            intStack.push(operand);
                        }
                    }

                    @Override
                    public void visitLdcInsn(Object cst) {
                        if (cst instanceof Integer) {
                            intStack.push((Integer) cst);
                        }
                    }

                    @Override
                    public void visitInsn(int opcode) {
                        if (opcode >= Opcodes.ICONST_0 && opcode <= Opcodes.ICONST_5) {
                            intStack.push(opcode - Opcodes.ICONST_0);
                        } else if (opcode == Opcodes.IASTORE) {
                            int value = intStack.pop();
                            int index = intStack.pop();
                            current[index] = value;
                        }
                    }

                    @Override
                    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                        if (opcode == Opcodes.PUTSTATIC) {
                            int[] old = styleables.get(name);
                            if (old != null && old.length != current.length && !Arrays.equals(old, current)) {
                                throw new IllegalStateException("Value of styleable." + name + " mismatched! "
                                        + "Excepted " + Arrays.toString(old) + " but was "
                                        + Arrays.toString(current));
                            } else {
                                styleables.put(name, current);
                            }
                            current = null;
                            intStack.clear();
                        }
                    }
                };
            }
            return null;
        }
    };

    new ClassReader(bytes).accept(visitor, SKIP_DEBUG | SKIP_FRAMES);
}