Example usage for org.objectweb.asm.tree ClassNode ClassNode

List of usage examples for org.objectweb.asm.tree ClassNode ClassNode

Introduction

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

Prototype

public ClassNode() 

Source Link

Document

Constructs a new ClassNode .

Usage

From source file:org.wisdom.ipojo.module.WisdomViewVisitorTest.java

License:Apache License

@Test
public void parseEmptyAnnotation() {
    Reporter reporter = new SystemReporter();
    ComponentWorkbench workbench = mock(ComponentWorkbench.class);
    when(workbench.getType()).thenReturn(Type.getType(MyComponent.class));
    when(workbench.getClassNode()).thenReturn(new ClassNode());
    when(workbench.getElements()).thenReturn(elements);

    FieldNode node = new FieldNode(Opcodes.ACC_PROTECTED, "template", Type.getDescriptor(Template.class), null,
            null);/*  w  w  w. j a  v a  2  s.c o m*/

    WisdomViewVisitor visitor = new WisdomViewVisitor(workbench, reporter, node);
    visitor.visitEnd();

    assertThat(elements).hasSize(0);
}

From source file:org.wisdom.ipojo.module.WisdomViewVisitorTest.java

License:Apache License

@Test
public void parseViewOnNotTemplateField() {
    Reporter reporter = new SystemReporter();
    ComponentWorkbench workbench = mock(ComponentWorkbench.class);
    when(workbench.getType()).thenReturn(Type.getType(MyComponent.class));
    when(workbench.getClassNode()).thenReturn(new ClassNode());
    when(workbench.getElements()).thenReturn(elements);

    FieldNode node = new FieldNode(Opcodes.ACC_PROTECTED, "template", Type.getDescriptor(String.class), null,
            null);//from w w w.j  av a  2 s  .  c  om

    WisdomViewVisitor visitor = new WisdomViewVisitor(workbench, reporter, node);
    visitor.visit("value", "index");
    visitor.visitEnd();

    assertThat(elements).hasSize(1);
    Element element = elements.keySet().iterator().next();
    assertThat(element.getName()).isEqualTo("requires");
    assertThat(element.getAttribute("field")).isEqualTo("template");
    assertThat(element.getAttribute("filter")).contains("=index)");
}

From source file:pku.sei.checkedcoverage.tracer.instrumentation.Transformer.java

License:Creative Commons License

private byte[] transform0(final String className, final String javaClassName, final byte[] classfileBuffer) {
    final ClassReader reader = new ClassReader(classfileBuffer);

    final ClassNode classNode = new ClassNode();
    reader.accept(classNode, 0);//from  w w w .  jav  a 2 s.c om
    final ClassWriter writer;

    // we have to synchronize on System.out first.
    // otherwise it may lead to a deadlock if a thread calls removeStale() on ConcurrentReferenceHashMap
    // while he holds the lock for System.out, but another thread is inside the transformation step and
    // waits for the lock of System.out
    synchronized (System.out) {
        synchronized (this.transformationLock) {

            // register that class for later reconstruction of the trace
            List<Field> fields;
            if (classNode.fields.isEmpty())
                fields = Collections.emptyList();
            else
                fields = new ArrayList<Field>(classNode.fields.size());

            final String javaSuperName = Type.getObjectType(classNode.superName).getClassName();
            final ReadClass readClass = new ReadClass(className, AbstractInstruction.getNextIndex(),
                    classNode.access, classNode.sourceFile, fields, javaSuperName);
            for (final Object fieldObj : classNode.fields) {
                final FieldNode f = (FieldNode) fieldObj;
                fields.add(new Field(f.name, f.desc, f.access, readClass));
            }

            writer = new FixedClassWriter(
                    COMPUTE_FRAMES ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS);

            final ClassVisitor output = this.tracer.check ? new CheckClassAdapter(writer) : writer;

            if (Arrays.asList(this.pauseTracingClasses).contains(javaClassName)
                    || className.startsWith("java/security/")) {
                new PauseTracingInstrumenter(readClass, this.tracer).transform(classNode);
            } else {
                if ("java/lang/Thread".equals(className))
                    new ThreadInstrumenter(readClass, this.tracer).transform(classNode);
                else
                    new TracingClassInstrumenter(readClass, this.tracer).transform(classNode);
            }

            new IdentifiableInstrumenter(readClass, this.tracer).transform(classNode);

            classNode.accept(COMPUTE_FRAMES ? new JSRInliner(output) : output);

            readClass.setInstructionNumberEnd(AbstractInstruction.getNextIndex());

            // now we can write the class out
            // NOTE: we do not write it out immediately, because this sometimes leads
            // to circular dependencies!
            //readClass.writeOut(this.readClassesOutputStream, this.readClassesStringCache);
            this.readClasses.add(readClass);

        }
    }

    final byte[] newClassfileBuffer = writer.toByteArray();

    if (this.tracer.check) {
        checkClass(newClassfileBuffer, className);
    }

    //printClass(newClassfileBuffer, Type.getObjectType(className).getClassName());
    /*
    if (className.endsWith("line/Main"))
    printClass(newClassfileBuffer, Type.getObjectType(className).getClassName());
    */

    return newClassfileBuffer;
}

From source file:pku.sei.checkedcoverage.tracer.instrumentation.Transformer.java

License:Creative Commons License

private boolean checkClass(final byte[] newClassfileBuffer, final String classname) {
    final ClassNode cn = new ClassNode();
    final ClassReader cr = new ClassReader(newClassfileBuffer);
    //cr.accept(new CheckClassAdapter(cn), ClassReader.SKIP_DEBUG);
    cr.accept(new CheckClassAdapter(cn), 0);

    for (final Object methodObj : cn.methods) {
        final MethodNode method = (MethodNode) methodObj;
        final Analyzer a = new Analyzer(new BasicVerifier());
        // SimpleVerifier has problems with sub-classes, e.g. you cannot use PrintStream for Appendable and so on...
        //final Analyzer a = new Analyzer(new SimpleVerifier(
        //    Type.getObjectType(cn.name), Type.getObjectType(cn.superName),
        //    (cn.access & Opcodes.ACC_INTERFACE) != 0));
        try {/* ww  w. jav  a 2s  . c  o  m*/
            a.analyze(cn.name, method);
        } catch (final AnalyzerException e) {
            System.err.println("Error in method " + classname + "." + method.name + method.desc + ":");
            e.printStackTrace(System.err);
            printMethod(a, System.err, method);
            return false;
        }
    }
    return true;
}

From source file:pl.asie.foamfix.coremod.BlockPosPatch.java

License:Open Source License

public static byte[] patchVec3i(byte[] data) {
    final ClassReader reader = new ClassReader(data);
    final ClassNode node = new ClassNode();
    reader.accept(node, 8);/*from  w w  w.jav a  2  s.  c  o m*/
    for (FieldNode fn : node.fields) {
        if ("I".equals(fn.desc) && fn.access == (Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL)) {
            fn.access = Opcodes.ACC_PROTECTED;
        }
    }
    final ClassWriter writer = new ClassWriter(8);
    node.accept(writer);
    return writer.toByteArray();
}

From source file:pl.asie.foamfix.coremod.FoamFixTransformer.java

License:Open Source License

public byte[] spliceMethods(final byte[] data, final String className, final String targetClassName,
        final String... methods) {
    final Set<String> methodSet = Sets.newHashSet(methods);
    try {//from www  . j av  a  2  s .  c  om
        final byte[] dataSplice = ByteStreams.toByteArray(
                this.getClass().getClassLoader().getResourceAsStream(className.replace('.', '/') + ".class"));
        final ClassReader readerData = new ClassReader(data);
        final ClassReader readerSplice = new ClassReader(dataSplice);
        final ClassWriter writer = new ClassWriter(8);
        final String className2 = className.replace('.', '/');
        final String targetClassName2 = targetClassName.replace('.', '/');
        final Remapper remapper = new Remapper() {
            public String map(final String name) {
                return className2.equals(name) ? targetClassName2 : name;
            }
        };
        ClassNode nodeData = new ClassNode();
        ClassNode nodeSplice = new ClassNode();
        readerData.accept(nodeData, 8);
        readerSplice.accept(new RemappingClassAdapter(nodeSplice, remapper), 8);
        for (int i = 0; i < nodeSplice.methods.size(); i++) {
            if (methodSet.contains(nodeSplice.methods.get(i).name)) {
                MethodNode mn = nodeSplice.methods.get(i);
                boolean added = false;

                for (int j = 0; j < nodeData.methods.size(); j++) {
                    if (nodeData.methods.get(j).name.equals(mn.name)
                            && nodeData.methods.get(j).desc.equals(mn.desc)) {
                        System.out.println("Spliced in: " + targetClassName + "." + mn.name);
                        nodeData.methods.set(j, mn);
                        added = true;
                        break;
                    }
                }

                if (!added) {
                    System.out.println("Added: " + targetClassName + "." + mn.name);
                    nodeData.methods.add(mn);
                    added = true;
                }
            }
        }
        nodeData.accept(writer);
        return writer.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

From source file:pl.clareo.coroutines.core.ClassTransformer.java

License:Apache License

@SuppressWarnings("unchecked")
void transform() {
    for (MethodNode coroutine : coroutines) {
        if (log.isLoggable(Level.FINEST)) {
            log.finest("Generating method for coroutine " + coroutine.name + coroutine.desc);
        }//w w w  .java2  s.  co m
        String coroutineName = getCoroutineName(coroutine);
        MethodTransformer methodTransformer = new MethodTransformer(coroutine, thisType);
        MethodNode coroutineImpl = methodTransformer.transform(coroutineName, generateDebugCode);
        thisNode.methods.add(coroutineImpl);
        /*
         * generate co iterators and method stubs
         */
        log.finest("Generating CoIterator implementation and method stubs");
        String baseCoIteratorName;
        Map<String, Object> annotation = getCoroutineAnnotationValues(coroutine);
        if (getBoolean(annotation, "threadLocal")) {
            baseCoIteratorName = Type.getInternalName(ThreadLocalCoIterator.class);
        } else {
            baseCoIteratorName = Type.getInternalName(SingleThreadedCoIterator.class);
        }
        String coIteratorClassName = "pl/clareo/coroutines/core/CoIterator" + num;
        ClassNode coIteratorClass = new ClassNode();
        coIteratorClass.version = Opcodes.V1_6;
        coIteratorClass.access = Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER;
        coIteratorClass.name = coIteratorClassName;
        coIteratorClass.superName = baseCoIteratorName;
        if (generateDebugCode) {
            /*
             * If debugging code is emitted create field keeping JDK logger
             */
            FieldNode loggerField = new FieldNode(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC,
                    "logger", "Ljava/util/logging/Logger;", null, null);
            coIteratorClass.fields.add(loggerField);
            MethodNode clinit = new MethodNode();
            clinit.access = Opcodes.ACC_STATIC;
            clinit.name = "<clinit>";
            clinit.desc = "()V";
            clinit.exceptions = Collections.EMPTY_LIST;
            String loggerName = thisType.getClassName();
            InsnList clinitCode = clinit.instructions;
            clinitCode.add(new LdcInsnNode(loggerName));
            clinitCode.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/logging/Logger", "getLogger",
                    "(Ljava/lang/String;)Ljava/util/logging/Logger;"));
            clinitCode.add(new FieldInsnNode(Opcodes.PUTSTATIC, coIteratorClassName, "logger",
                    "Ljava/util/logging/Logger;"));
            clinitCode.add(new InsnNode(Opcodes.RETURN));
            clinit.maxStack = 1;
            clinit.maxLocals = 0;
            coIteratorClass.methods.add(clinit);
        }
        /*
         * Generate constructor
         */
        MethodNode init = new MethodNode();
        init.access = Opcodes.ACC_PUBLIC;
        init.name = "<init>";
        init.desc = CO_ITERATOR_CONSTRUCTOR_DESCRIPTOR;
        init.exceptions = Collections.EMPTY_LIST;
        InsnList initCode = init.instructions;
        initCode.add(new VarInsnNode(Opcodes.ALOAD, 0));
        initCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
        initCode.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, baseCoIteratorName, "<init>",
                CO_ITERATOR_CONSTRUCTOR_DESCRIPTOR));
        initCode.add(new InsnNode(Opcodes.RETURN));
        init.maxStack = 2;
        init.maxLocals = 2;
        coIteratorClass.methods.add(init);
        /*
         * Generate overriden call to coroutine
         */
        MethodNode call = new MethodNode();
        call.access = Opcodes.ACC_PROTECTED;
        call.name = "call";
        call.desc = CALL_METHOD_DESCRIPTOR;
        call.exceptions = Collections.EMPTY_LIST;
        InsnList callCode = call.instructions;
        /*
         * if debug needed generate call details
         */
        if (generateDebugCode) {
            String coroutineId = "Coroutine " + coroutine.name;
            callCode.add(loggingInstructions(coIteratorClassName, "logger", Level.FINER,
                    coroutineId + " call. Caller sent: ", 2));
            callCode.add(new FrameNode(Opcodes.F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
            callCode.add(loggingInstructions(coIteratorClassName, "logger", Level.FINEST,
                    coroutineId + " state ", 1));
            callCode.add(new FrameNode(Opcodes.F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
        }
        /*
         * push call arguments: this (if not static), frame, input, output
         */
        boolean isStatic = (coroutine.access & Opcodes.ACC_STATIC) != 0;
        if (!isStatic) {
            callCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
            callCode.add(
                    new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FRAME_NAME, "getThis", "()Ljava/lang/Object;"));
            callCode.add(new TypeInsnNode(Opcodes.CHECKCAST, thisType.getInternalName()));
        }
        callCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
        callCode.add(new InsnNode(Opcodes.ACONST_NULL));
        callCode.add(new VarInsnNode(Opcodes.ALOAD, 2));
        callCode.add(new MethodInsnNode(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL,
                thisType.getInternalName(), coroutineName, COROUTINE_METHOD_DESCRIPTOR));
        // stack: *
        if (!generateDebugCode) {
            callCode.add(new InsnNode(Opcodes.ARETURN));
        } else {
            // save result display suspension point (two more locals
            // needed)
            callCode.add(new VarInsnNode(Opcodes.ASTORE, 3));
            callCode.add(new VarInsnNode(Opcodes.ALOAD, 1));
            callCode.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FRAME_NAME, "getLineOfCode", "()I"));
            callCode.add(box_int(Type.INT));
            callCode.add(new VarInsnNode(Opcodes.ASTORE, 4));
            callCode.add(loggingInstructions(coIteratorClassName, "logger", Level.FINER,
                    "Coroutine suspended at line ", 4, ". Yielded:", 3));
            callCode.add(new FrameNode(Opcodes.F_APPEND, 2,
                    new Object[] { "java/lang/Object", "java/lang/Integer" }, 0, EMPTY_STACK));
            callCode.add(new VarInsnNode(Opcodes.ALOAD, 3));
            callCode.add(new InsnNode(Opcodes.ARETURN));
        }
        coIteratorClass.methods.add(call);
        // if debugging code is emitted it needs space for two
        // additional locals and 5 stack operand
        if (generateDebugCode) {
            call.maxStack = 5;
            call.maxLocals = 5;
        } else {
            if (isStatic) {
                call.maxStack = 3;
            } else {
                call.maxStack = 4;
            }
            call.maxLocals = 3;
        }
        /*
         * CoIterator created - define it in the runtime and verify if
         * needed
         */
        if (log.isLoggable(Level.FINEST)) {
            log.finest("Generated class " + coIteratorClassName);
        }
        ClassWriter cw = new ClassWriter(0);
        coIteratorClass.accept(cw);
        byte[] classBytes = cw.toByteArray();
        try {
            CoroutineInstrumentator.dumpClass(coIteratorClassName, classBytes);
        } catch (IOException e) {
            throw new CoroutineGenerationException("Unable to write class " + coIteratorClassName, e);
        }
        /*
         * start generating method - new method is named as the method in
         * user code, it: returns instance of appropriate CoIterator (see
         * above), saves arguments of call
         */
        if (log.isLoggable(Level.FINEST)) {
            log.finest("Instrumenting method " + coroutine.name);
        }
        InsnList code = coroutine.instructions;
        code.clear();
        /*
         * create new Frame
         */
        boolean isDebugFramePossible = generateDebugCode && coroutine.localVariables != null;
        if (isDebugFramePossible) {
            code.add(createDebugFrame(coroutine));
        } else {
            code.add(createFrame(coroutine));
        }
        /*
         * save frame in the first, and locals array in the second local
         * variable
         */
        int argsSize = Type.getArgumentsAndReturnSizes(coroutine.desc) >> 2;
        if (isStatic) {
            argsSize -= 1;
        }
        code.add(new VarInsnNode(Opcodes.ASTORE, argsSize));
        code.add(new VarInsnNode(Opcodes.ALOAD, argsSize));
        code.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FRAME_NAME, "getLocals", "()[Ljava/lang/Object;"));
        int localsArrayIndex = argsSize + 1;
        code.add(new VarInsnNode(Opcodes.ASTORE, localsArrayIndex));
        /*
         * save all call arguments (along with this if this method is not
         * static) into locals array
         */
        Type[] argsTypes = Type.getArgumentTypes(coroutine.desc);
        if (!isStatic) {
            code.add(saveloc(localsArrayIndex, 0, 0, JAVA_LANG_OBJECT));
            code.add(savelocs(localsArrayIndex, 1, 1, argsTypes));
        } else {
            code.add(savelocs(localsArrayIndex, 0, 0, argsTypes));
        }
        /*
         * create CoIterator instance with saved frame, make initial call to
         * next if needed and return to caller
         */
        code.add(new TypeInsnNode(Opcodes.NEW, coIteratorClassName));
        code.add(new InsnNode(Opcodes.DUP));
        code.add(new VarInsnNode(Opcodes.ALOAD, argsSize));
        code.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, coIteratorClassName, "<init>",
                CO_ITERATOR_CONSTRUCTOR_DESCRIPTOR));
        if (!getBoolean(annotation, "generator", true)) {
            code.add(new InsnNode(Opcodes.DUP));
            code.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, coIteratorClassName, "next",
                    "()Ljava/lang/Object;"));
            code.add(new InsnNode(Opcodes.POP));
        }
        code.add(new InsnNode(Opcodes.ARETURN));
        /*
         * end method generation; maxs can be statically determined 3
         * operands on stack (call to frame setLocals and CoIterator
         * constructor) + 1 if any argument is long or double (debug frame
         * needs 7 operands for variable names creation); locals = argsSize
         * + 1 reference to frame + 1 array of locals
         */
        if (isDebugFramePossible) {
            coroutine.maxStack = 7;
        } else {
            boolean isCategory2ArgumentPresent = false;
            for (Type argType : argsTypes) {
                int sort = argType.getSort();
                if (sort == Type.LONG || sort == Type.DOUBLE) {
                    isCategory2ArgumentPresent = true;
                    break;
                }
            }
            coroutine.maxStack = isCategory2ArgumentPresent ? 4 : 3;
        }
        coroutine.maxLocals = localsArrayIndex + 1;
        coroutine.localVariables.clear();
        coroutine.tryCatchBlocks.clear();
        num++;
    }
}

From source file:pl.clareo.coroutines.core.CoroutineInstrumentator.java

License:Apache License

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (classBeingRedefined != null) {
        return null;
    }//from  ww w .  j  a va  2s.c  o  m
    if (className.startsWith("java/") || className.startsWith("javax/") || className.startsWith("sun/")) {
        return null;
    }
    List<MethodNode> coroutineMethodsInCurrentClass;
    boolean debug = generateDebugCode;
    boolean print = printCode;
    boolean verify = runVerification;
    boolean outputBin = generateBinaryOutput;
    boolean asmComputeFrames = overrideFrames;
    if (!detectCoroutineClasses) {
        int classnameIndex = Arrays.binarySearch(coroutineEnabledClassnames, className);
        if (classnameIndex < 0) {
            // search package
            String packageName = className;
            int indexOfSlash;
            while ((indexOfSlash = packageName.lastIndexOf('/')) != -1) {
                packageName = packageName.substring(0, indexOfSlash);
                classnameIndex = Arrays.binarySearch(coroutineEnabledClassnames, packageName);
                if (classnameIndex >= 0) {
                    break;
                }
            }
            if (classnameIndex < 0)
                return null;
        }
        debug = debugMode[classnameIndex];
        print = printMode[classnameIndex];
        verify = verifyMode[classnameIndex];
        outputBin = outputBinMode[classnameIndex];
        asmComputeFrames = overrideFramesMode[classnameIndex];
    }
    boolean log = logger.isLoggable(Level.FINEST);
    if (log) {
        logger.finest(className + ": Analyzing");
    }
    ClassReader asmClassReader = new ClassReader(classfileBuffer);
    ClassNode cn = new ClassNode();
    asmClassReader.accept(cn, debug ? 0 : ClassReader.SKIP_DEBUG);
    ClassAnalyzer analyzer = new ClassAnalyzer(cn);
    analyzer.analyze();
    coroutineMethodsInCurrentClass = analyzer.getCoroutineMethods();
    if (coroutineMethodsInCurrentClass.isEmpty()) {
        return null;
    }
    if (log) {
        logger.finest(className + ": Instrumenting coroutines "
                + methodNodeListToString(coroutineMethodsInCurrentClass));
    }
    ClassWriter asmClassWriter = new ClassWriter(
            (asmComputeFrames ? ClassWriter.COMPUTE_FRAMES : 0) | ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = asmClassWriter;
    byte[] instrumentedClassContents;
    try {
        if (print) {
            try {
                cv = createTracer(className, cv);
            } catch (FileNotFoundException e) {
                throw new CoroutineGenerationException("Unable to write trace file ", e);
            }
        }
        new ClassTransformer(cn, coroutineMethodsInCurrentClass, debug).transform();
        cn.accept(cv);
        instrumentedClassContents = asmClassWriter.toByteArray();
        if (verify) {
            verifyClass(className, new ClassReader(instrumentedClassContents), print);
        }
        if (outputBin) {
            dumpClass(className + "Instrumented", instrumentedClassContents);
        }
    } catch (IllegalStateException e) {
        logger.log(Level.WARNING, "Verification failed", e);
        return null;
    } catch (IllegalArgumentException e) {
        logger.log(Level.WARNING, "Verification failed", e);
        return null;
    } catch (CoroutineGenerationException e) {
        logger.warning(e.getMessage());
        return null;
    } catch (Throwable t) {
        logger.log(Level.SEVERE,
                "Coroutine generation ended abruptly. This may be a bug in the package itself. Details below:",
                t);
        return null;
    }
    return instrumentedClassContents;
}

From source file:portablejim.veinminer.asm.ItemInWorldManagerTransformer.java

License:Open Source License

public byte[] transformItemInWorldManager(String obfuscatedClassName, byte[] bytes) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);/*from  www  .  ja va2s .  c  o  m*/

    // Setup type map
    for (FieldNode variable : classNode.fields) {
        String srgVariableName = FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(obfuscatedClassName,
                variable.name, variable.desc);
        if (getCorrectName("theWorld").equals(srgVariableName)
                || getCorrectName("thisPlayerMP").equals(srgVariableName)) {
            typemap.put(srgVariableName, variable.desc);
        }
    }

    try {
        for (MethodNode curMethod : classNode.methods) {
            String srgFunctionName = FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(obfuscatedClassName,
                    curMethod.name, curMethod.desc);

            if (getCorrectName("uncheckedTryHarvestBlock").equals(srgFunctionName)) {
                Logger.debug("Inserting call to uncheckedTryHarvestBlock (%s)", srgFunctionName);
                insertCallAfterTryHarvestBlockFunction(curMethod, obfuscatedClassName);
            } else if (getCorrectName("onBlockClicked").equals(srgFunctionName)) {
                Logger.debug("Inserting call to onBlockClicked (%s)", srgFunctionName);
                int afterFirst = insertCallAfterTryHarvestBlockFunction(curMethod, obfuscatedClassName);
                insertCallAfterTryHarvestBlockFunction(curMethod, obfuscatedClassName, afterFirst);

            }
        }
    } catch (IndexOutOfBoundsException e) {
        FMLLog.getLogger().log(Level.WARNING,
                "[%s] Problem inserting all required code. This mod may not function correctly. Please report a bug.",
                ModInfo.MOD_NAME);
    }

    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:pt.ist.esw.advice.GenerateAnnotationInstance.java

License:Open Source License

public void start() throws IOException {
    InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(annotation + ".class");
    ClassReader cr = new ClassReader(is);
    ClassNode cNode = new ClassNode();
    cr.accept(cNode, 0);/*from  w  w  w  .  j ava  2s.c  o  m*/

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(V1_6, ACC_PUBLIC | ACC_FINAL, annotationInstance, null, "java/lang/Object",
            new String[] { annotation });
    cw.visitSource("Annotation Instance Class", null);

    // Generate fields
    for (MethodNode annotationElems : cNode.methods) {
        cw.visitField(ACC_PRIVATE | ACC_FINAL, annotationElems.name, getReturnTypeDescriptor(annotationElems),
                null, null);
    }

    // Generate constructor
    {
        StringBuffer ctorDescriptor = new StringBuffer("(");
        for (MethodNode annotationElems : cNode.methods) {
            ctorDescriptor.append(getReturnTypeDescriptor(annotationElems));
        }
        ctorDescriptor.append(")V");

        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", ctorDescriptor.toString(), null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        int localsPos = 0;
        for (MethodNode annotationElems : cNode.methods) {
            Type t = Type.getReturnType(annotationElems.desc);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(t.getOpcode(ILOAD), localsPos + 1);
            mv.visitFieldInsn(PUTFIELD, annotationInstance, annotationElems.name, t.getDescriptor());
            localsPos += t.getSize();
        }
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    // Generate getters
    for (MethodNode annotationElems : cNode.methods) {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, annotationElems.name, annotationElems.desc, null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, annotationInstance, annotationElems.name,
                getReturnTypeDescriptor(annotationElems));
        mv.visitInsn(Type.getReturnType(annotationElems.desc).getOpcode(IRETURN));
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    // Generate annotationType() method
    {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "annotationType", "()Ljava/lang/Class;",
                "()Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;", null);
        mv.visitCode();
        mv.visitLdcInsn(Type.getType(annotationClass));
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }

    // Write Class
    FileOutputStream fos = null;
    try {
        File parentDir = new File(buildDir, ANNOTATION_INSTANCE_PACKAGE.replace('/', separatorChar));
        if (!parentDir.exists() && !parentDir.mkdirs()) {
            throw new IOException("Could not create required directory: " + parentDir);
        }

        File f = new File(parentDir, annotationClass.getSimpleName() + "Instance.class");
        fos = new FileOutputStream(f);
        fos.write(cw.toByteArray());
    } finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}