Example usage for org.objectweb.asm ClassVisitor ClassVisitor

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

Introduction

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

Prototype

public ClassVisitor(final int api) 

Source Link

Document

Constructs a new ClassVisitor .

Usage

From source file:net.fabricmc.tinyremapper.TinyRemapper.java

License:Open Source License

private RClass analyze(Path srcPath, byte[] data, boolean saveData) {
    final RClass ret = new RClass(srcPath, saveData ? data : null);

    ClassReader reader = new ClassReader(data);

    reader.accept(new ClassVisitor(Opcodes.ASM5) {
        @Override//from www.  j  av a  2s  .  co m
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            ret.name = mapClass(name);
            ret.superName = mapClass(superName);
            ret.interfaces = new String[interfaces.length];
            for (int i = 0; i < interfaces.length; i++)
                ret.interfaces[i] = mapClass(interfaces[i]);
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            ret.methods.put(name + desc, new Member(name, desc, access));

            return null;
        }

        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            ret.fields.put(name + ";;" + desc, new Member(name, desc, access));

            return null;
        }
    }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE);

    return ret;
}

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;// w w  w.j ava  2  s  . c  om
    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.orfjackal.retrolambda.ClassAnalyzer.java

License:Open Source License

private void analyzeClass(ClassInfo c, ClassReader cr) {
    cr.accept(new ClassVisitor(ASM5) {
        private String owner;

        @Override/*from   ww w.  ja  v  a 2  s . c  o m*/
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            this.owner = name;
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            int tag;
            if (isConstructor(name)) {
                tag = H_INVOKESPECIAL;
            } else if (isStaticMethod(access)) {
                tag = H_INVOKESTATIC;
            } else {
                tag = H_INVOKEVIRTUAL;
            }

            c.addMethod(access, new MethodRef(tag, owner, name, desc), new MethodKind.Implemented());
            return null;
        }

    }, ClassReader.SKIP_CODE);
}

From source file:net.orfjackal.retrolambda.ClassAnalyzer.java

License:Open Source License

private void analyzeInterface(ClassInfo c, ClassReader cr) {
    cr.accept(new ClassVisitor(ASM5) {
        private String owner;
        private String companion;

        @Override//  ww w  .  ja v a 2s. c  o  m
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            this.owner = name;
            this.companion = name + "$";
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            MethodRef method = new MethodRef(Handles.accessToTag(access, true), owner, name, desc);

            if (isAbstractMethod(access)) {
                c.addMethod(access, method, new MethodKind.Abstract());

            } else if (isDefaultMethod(access)) {
                MethodRef defaultImpl = new MethodRef(H_INVOKESTATIC, companion, name,
                        Bytecode.prependArgumentType(desc, Type.getObjectType(owner)));
                c.enableCompanionClass();
                c.addMethod(access, method, new MethodKind.Default(defaultImpl));

            } else if (isInstanceLambdaImplMethod(access)) {
                relocatedMethods.put(method, new MethodRef(H_INVOKESTATIC, companion, name,
                        Bytecode.prependArgumentType(desc, Type.getObjectType(owner))));
                c.enableCompanionClass();

            } else if (isStaticMethod(access) && !isStaticInitializer(name, desc, access)) {
                relocatedMethods.put(method, new MethodRef(H_INVOKESTATIC, companion, name, desc));
                c.enableCompanionClass();
            }
            return null;
        }
    }, ClassReader.SKIP_CODE);
}

From source file:net.orfjackal.retrolambda.ClassAnalyzer.java

License:Open Source License

private void analyzeClassOrInterface(ClassInfo c, ClassReader cr) {
    cr.accept(new ClassVisitor(ASM5) {
        private String owner;

        @Override/*from  ww w  .ja  v a 2  s  .  c om*/
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            this.owner = name;
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            MethodRef method = new MethodRef(Handles.accessToTag(access, true), owner, name, desc);

            // XXX: duplicates code in net.orfjackal.retrolambda.lambdas.BackportLambdaInvocations.visitMethod()
            if (LambdaNaming.isBodyMethod(access, name) && Flags.isPrivateMethod(access)
                    && Flags.isInstanceMethod(access)) {
                desc = Types.prependArgumentType(Type.getObjectType(owner), desc); // add 'this' as first parameter
                renamedLambdaMethods.put(method, new MethodRef(H_INVOKESTATIC, owner, name, desc));
            }

            return null;
        }
    }, ClassReader.SKIP_CODE);
}

From source file:net.orfjackal.retrolambda.interfaces.ClassHierarchyAnalyzer.java

License:Open Source License

private void analyzeClass(ClassInfo c, ClassReader cr) {
    cr.accept(new ClassVisitor(ASM5) {
        private String owner;

        @Override// w w  w.  j a  v a2s.  c  o  m
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            this.owner = name;
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            if (isConstructor(name) || isStaticMethod(access)) {
                return null;
            }
            c.addMethod(new MethodRef(H_INVOKEVIRTUAL, owner, name, desc), new MethodKind.Implemented());
            return null;
        }

    }, ClassReader.SKIP_CODE);
}

From source file:net.orfjackal.retrolambda.interfaces.ClassHierarchyAnalyzer.java

License:Open Source License

private void analyzeInterface(ClassInfo c, ClassReader cr) {
    cr.accept(new ClassVisitor(ASM5) {
        private String owner;
        private String companion;

        @Override//from   www  . ja  v a 2 s .  co  m
        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            this.owner = name;
            this.companion = name + "$";
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            MethodRef method = new MethodRef(Handles.accessToTag(access, true), owner, name, desc);

            if (isAbstractMethod(access)) {
                c.addMethod(method, new MethodKind.Abstract());

            } else if (isDefaultMethod(access)) {
                MethodRef defaultImpl = new MethodRef(H_INVOKESTATIC, companion, name,
                        Bytecode.prependArgumentType(desc, Type.getObjectType(owner)));
                c.enableCompanionClass();
                c.addMethod(method, new MethodKind.Default(defaultImpl));

            } else if (isInstanceLambdaImplMethod(access)) {
                relocatedMethods.put(method, new MethodRef(H_INVOKESTATIC, companion, name,
                        Bytecode.prependArgumentType(desc, Type.getObjectType(owner))));
                c.enableCompanionClass();

            } else if (isStaticMethod(access)) {
                relocatedMethods.put(method, new MethodRef(H_INVOKESTATIC, companion, name, desc));
                c.enableCompanionClass();
            }
            return null;
        }
    }, ClassReader.SKIP_CODE);
}

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 {//from  ww w. ja  v  a  2 s  . c  o  m
        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);
}

From source file:org.apache.batchee.tools.maven.doc.ComponentDocumentationGenerator.java

License:Apache License

private String component(final Map<String, ClassDoc> commands, final File classFile) throws IOException {
    InputStream stream = null;//from ww w . ja v  a2s .  c o  m
    try {
        stream = new FileInputStream(classFile);
        final ClassReader reader = new ClassReader(stream);
        reader.accept(new ClassVisitor(ASM5) {
            public boolean isLeaf;
            private String parentName;
            private String configName;
            private String className;
            private String doc;
            private List<FieldDoc> configs;

            @Override
            public void visit(final int version, final int access, final String name, final String signature,
                    final String superName, final String[] interfaces) {
                parentName = superName == null || OBJECT_NAME.equals(superName) ? null
                        : superName.replace('/', '.');
                className = name.replace('/', '.');
                isLeaf = !Modifier.isAbstract(access); // TODO: interfaces?
            }

            @Override
            public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
                final AnnotationVisitor annotationVisitor = super.visitAnnotation(desc, visible);
                if (NAMED_MARKER.equals(desc)) {
                    configName = className;
                    final int dollar = configName.lastIndexOf('$');
                    if (dollar > 0) {
                        configName = configName.substring(dollar + 1);
                    } else {
                        final int dot = configName.lastIndexOf('.');
                        if (dot > 0) {
                            configName = configName.substring(dot + 1);
                        }
                    }

                    configName = Introspector.decapitalize(configName);
                    return new AnnotationVisitor(ASM5, annotationVisitor) {
                        @Override
                        public void visit(final String name, final Object value) {
                            super.visit(name, value);
                            if ("value".equals(name) && String.class.isInstance(value)
                                    && !String.class.cast(value).isEmpty()) {
                                configName = value.toString();
                            }
                        }
                    };
                }
                if (CONFIGURATION_MARKER.equals(desc)) {
                    return new AnnotationVisitor(ASM5, annotationVisitor) {
                        @Override
                        public void visit(final String name, final Object value) {
                            super.visit(name, value);
                            if ("value".equals(name) && String.class.isInstance(value)
                                    && !String.class.cast(value).isEmpty()) {
                                doc = value.toString();
                            }
                        }
                    };
                }
                return annotationVisitor;
            }

            @Override
            public FieldVisitor visitField(final int access, final String name, final String desc,
                    final String signature, final Object value) {
                return new FieldVisitor(ASM5, super.visitField(access, name, desc, signature, value)) {
                    private boolean marked = false;
                    private boolean hasInject = false;
                    private String configName = name;
                    private String doc = null;

                    @Override
                    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
                        final AnnotationVisitor annotationVisitor = super.visitAnnotation(desc, visible);
                        if (PROPERTY_MARKER.equals(desc)) {
                            marked = true;
                            return new AnnotationVisitor(ASM5, annotationVisitor) {
                                @Override
                                public void visit(final String name, final Object value) {
                                    super.visit(name, value);
                                    if ("name".equals(name) && String.class.isInstance(value)
                                            && !String.class.cast(value).isEmpty()) {
                                        configName = value.toString();
                                    }
                                }
                            };
                        }
                        if (INJECT_MARKER.equals(desc)) {
                            hasInject = true;
                            return annotationVisitor;
                        }
                        if (CONFIGURATION_MARKER.equals(desc)) {
                            return new AnnotationVisitor(ASM5, annotationVisitor) {
                                @Override
                                public void visit(final String name, final Object value) {
                                    super.visit(name, value);
                                    if ("value".equals(name) && String.class.isInstance(value)
                                            && !String.class.cast(value).isEmpty()) {
                                        doc = value.toString();
                                    }
                                }
                            };
                        }
                        return annotationVisitor;
                    }

                    @Override
                    public void visitEnd() {
                        super.visitEnd();
                        if (marked && hasInject) {
                            if (configs == null) {
                                configs = new ArrayList<FieldDoc>();
                            }
                            configs.add(new FieldDoc(configName, doc));
                        }
                    }
                };
            }

            @Override
            public void visitEnd() {
                super.visitEnd();
                if (configs != null) {
                    Collections.sort(configs);
                    commands.put(className, new ClassDoc(isLeaf, parentName,
                            configName == null ? className : configName, doc, configs));
                }
            }
        }, SKIP_CODE + SKIP_DEBUG + SKIP_FRAMES);
    } finally {
        try {
            if (stream != null) {
                stream.close();
            }
        } catch (final IOException e) {
            // no-op
        }
    }
    return null;
}

From source file:org.apache.cassandra.cql3.functions.UDFByteCodeVerifier.java

License:Apache License

public Set<String> verify(byte[] bytes) {
    Set<String> errors = new TreeSet<>(); // it's a TreeSet for unit tests
    ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM5) {
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            errors.add("field declared: " + name);
            return null;
        }//from w  w  w  .j a v  a  2 s  .co  m

        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
                String[] exceptions) {
            if ("<init>".equals(name) && CTOR_SIG.equals(desc)) {
                if (Opcodes.ACC_PUBLIC != access)
                    errors.add("constructor not public");
                // allowed constructor - JavaUDF(TypeCodec returnCodec, TypeCodec[] argCodecs)
                return new ConstructorVisitor(errors);
            }
            if ("executeImpl".equals(name) && "(ILjava/util/List;)Ljava/nio/ByteBuffer;".equals(desc)) {
                if (Opcodes.ACC_PROTECTED != access)
                    errors.add("executeImpl not protected");
                // the executeImpl method - ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)
                return new ExecuteImplVisitor(errors);
            }
            if ("<clinit>".equals(name)) {
                errors.add("static initializer declared");
            } else {
                errors.add("not allowed method declared: " + name + desc);
                return new ExecuteImplVisitor(errors);
            }
            return null;
        }

        public void visit(int version, int access, String name, String signature, String superName,
                String[] interfaces) {
            if (!JAVA_UDF_NAME.equals(superName)) {
                errors.add("class does not extend " + JavaUDF.class.getName());
            }
            if (access != (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER)) {
                errors.add("class not public final");
            }
            super.visit(version, access, name, signature, superName, interfaces);
        }

        public void visitInnerClass(String name, String outerName, String innerName, int access) {
            errors.add("class declared as inner class");
            super.visitInnerClass(name, outerName, innerName, access);
        }
    };

    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classVisitor, ClassReader.SKIP_DEBUG);

    return errors;
}