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.spongepowered.lantern.plugin.PluginScanner.java

License:MIT License

@Nullable
private static String findPlugin(InputStream in) throws IOException {
    ClassReader reader = new ClassReader(in);
    ClassNode classNode = new ClassNode();
    reader.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);

    if (classNode.visibleAnnotations != null) {
        for (AnnotationNode node : classNode.visibleAnnotations) {
            if (node.desc.equals(PLUGIN_DESCRIPTOR)) {
                return classNode.name.replace('/', '.');
            }/*from w w  w . j a  v  a 2 s . c  o  m*/
        }
    }

    return null;
}

From source file:org.spongepowered.lwts.transformer.AccessTransformer.java

License:MIT License

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (this.modifiers == null) {
        this.modifiers = this.processor.build();
        this.processor = null;
    }/*w  w w  .  ja va2  s .  c om*/

    if (bytes == null || !this.modifiers.containsKey(transformedName)) {
        return bytes;
    }

    ClassNode classNode = new ClassNode();
    ClassReader reader = new ClassReader(bytes);
    reader.accept(classNode, 0);

    for (Modifier m : this.modifiers.get(transformedName)) {
        if (m.isClass) { // Class
            classNode.access = m.transform(classNode.access);
        } else if (m.desc == null) { // Field
            for (FieldNode fieldNode : classNode.fields) {
                if (m.wildcard || fieldNode.name.equals(m.name)) {
                    fieldNode.access = m.transform(fieldNode.access);
                    if (!m.wildcard) {
                        break;
                    }
                }
            }
        } else {
            List<MethodNode> overridable = null;

            for (MethodNode methodNode : classNode.methods) {
                if (m.wildcard || (methodNode.name.equals(m.name) && methodNode.desc.equals(m.desc))) {
                    boolean wasPrivate = (methodNode.access & ACC_PRIVATE) != 0;
                    methodNode.access = m.transform(methodNode.access);

                    // Constructors always use INVOKESPECIAL
                    // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL
                    // so that overridden methods will be called. Only need to scan this class, because obviously the method was private.
                    if (!methodNode.name.equals("<init>") && wasPrivate
                            && (methodNode.access & ACC_PRIVATE) == 0) {
                        if (overridable == null) {
                            overridable = Lists.newArrayListWithExpectedSize(3);
                        }

                        overridable.add(methodNode);
                    }

                    if (!m.wildcard) {
                        break;
                    }
                }
            }

            if (overridable != null) {
                for (MethodNode methodNode : classNode.methods) {
                    for (Iterator<AbstractInsnNode> itr = methodNode.instructions.iterator(); itr.hasNext();) {
                        AbstractInsnNode insn = itr.next();
                        if (insn.getOpcode() == INVOKESPECIAL) {
                            MethodInsnNode mInsn = (MethodInsnNode) insn;
                            for (MethodNode replace : overridable) {
                                if (replace.name.equals(mInsn.name) && replace.desc.equals(mInsn.desc)) {
                                    mInsn.setOpcode(INVOKEVIRTUAL);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

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

From source file:org.spongepowered.mod.asm.transformers.BaseEventTransformer.java

License:MIT License

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {

    if (bytes == null || name == null) {
        return bytes;
    }/*from ww  w  . jav  a  2  s .  c o  m*/

    try {
        ClassReader cr = new ClassReader(bytes);
        ClassNode classNode = new ClassNode();
        cr.accept(classNode, 0);

        String parentName = classNode.superName.replace('/', '.');

        Class<?> parent = this.getClass().getClassLoader().loadClass(parentName);

        // Skip classes that do not implement SpongeAPI Event, or extend other classes
        // This implies that there will be issues with custom event classes that extend a superclass that does not fit these conditions itself
        // However, this is a fairly fundamental JVM limitation
        if ((!Object.class.equals(parent.getSuperclass())) || (!Event.class.isAssignableFrom(parent))) {
            return bytes;
        }

        // Add forwarding methods
        ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createGetGameMethod());
        ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createGetSimpleNameMethod());
        ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createIsCancellableMethod());
        ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createIsCancelledMethod());
        ASMHelper.addAndReplaceMethod(classNode, EventTransformer.createSetCancelledMethod());

        // Change super-class
        classNode.superName = "net/minecraftforge/fml/common/eventhandler/Event";

        // Replace super() call in constructor so that it points to the new super-class
        MethodNode method = ASMHelper.findMethod(classNode, "<init>", "()V");

        ListIterator<AbstractInsnNode> instructions = method.instructions.iterator();

        while (instructions.hasNext()) {
            AbstractInsnNode insn = instructions.next();
            if (insn.getOpcode() == Opcodes.INVOKESPECIAL) {
                MethodInsnNode methodInsn = new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.superName,
                        "<init>", "()V", false);
                instructions.remove();
                instructions.add(methodInsn);
                break;
            }
        }

        ClassWriter cw = new ClassWriter(cr, COMPUTE_MAXS | COMPUTE_FRAMES);
        classNode.accept(cw);
        return cw.toByteArray();
    } catch (Throwable t) {
        t.printStackTrace();
        return bytes;
    }
}

From source file:org.spongepowered.mod.asm.transformers.EventTransformer.java

License:MIT License

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {

    if (bytes == null || transformedName.startsWith("net.minecraft.")
            || transformedName.equals("net.minecraftforge.fml.common.event.FMLEvent")
            || transformedName.equals("net.minecraftforge.fml.common.eventhandler.Event")
            || transformedName.indexOf('.') == -1) {
        return bytes;
    }//from  w ww  . java2s  . c  o  m

    try {
        ClassReader cr = new ClassReader(bytes);
        ClassNode classNode = new ClassNode();
        cr.accept(classNode, 0);

        String parentName = classNode.superName.replace('/', '.');

        Class<?> parent = this.getClass().getClassLoader().loadClass(parentName);

        // Only process FMLEvents and Forge Events sub-classes

        if ((!Event.class.isAssignableFrom(parent)) && (!FMLEvent.class.isAssignableFrom(parent))) {
            return bytes;
        }

        Class<?> interf = events.get(transformedName);
        if (interf != null && interf.isInterface()) {
            String interfaceName = Type.getInternalName(interf);

            classNode.interfaces.add(interfaceName);
        }

        // Method forwarding for all events
        classNode.methods.add(createGetGameMethod());
        classNode.methods.add(createGetSimpleNameMethod());

        if (Event.class.isAssignableFrom(parent)) {
            // Forge Event method forwarding
            if (classNode.interfaces.contains("org/spongepowered/api/event/Cancellable")) {
                if (classNode.visibleAnnotations == null) {
                    classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
                }
                classNode.visibleAnnotations
                        .add(new AnnotationNode("Lnet/minecraftforge/fml/common/eventhandler/Cancelable;"));
                classNode.methods.add(createIsCancelledMethod());
                classNode.methods.add(createSetCancelledMethod());
            }
            classNode.methods.add(createIsCancellableMethod());
        }

        // TODO: This is a temporary thing to make PreInit work. The different things needed to make different events work should be abstracted.
        if (interf != null && PreInitializationEvent.class.isAssignableFrom(interf)) {
            ASMHelper.generateSelfForwardingMethod(classNode, "getConfigurationDirectory",
                    "getModConfigurationDirectory", Type.getType(File.class));
            ASMHelper.generateSelfForwardingMethod(classNode, "getPluginLog", "getModLog",
                    Type.getType(Logger.class));
        }

        ClassWriter cw = new ClassWriter(cr, COMPUTE_MAXS | COMPUTE_FRAMES);

        classNode.accept(cw);
        return cw.toByteArray();
    } catch (Throwable t) {
        t.printStackTrace();
        return bytes;
    }
}

From source file:org.spongepowered.mod.asm.transformers.InterfaceInfo.java

License:MIT License

/**
 * Reads an interface and its super-interfaces and gathers method names in to the local "methods" collection
 *//*from w  ww .  jav a 2s.  c o  m*/
private void readInterface(String ifaceName) {
    ClassNode ifaceNode = new ClassNode();
    try {
        ClassReader classReader = new ClassReader(this.loadInterface(ifaceName));
        classReader.accept(ifaceNode, 0);
    } catch (IOException ex) {
        throw new InvalidMixinException(
                "An error was encountered parsing the interface " + this.iface.toString());
    }

    for (MethodNode ifaceMethod : ifaceNode.methods) {
        String signature = ifaceMethod.name + ifaceMethod.desc;
        this.methods.add(signature);
    }

    for (String superIface : ifaceNode.interfaces) {
        String sif = superIface.replace('/', '.');
        this.readInterface(sif);
    }
}

From source file:org.spongepowered.mod.asm.transformers.MixinInfo.java

License:MIT License

/**
 * Get a new tree for the class bytecode
 * /*  w ww  .j a  v a2  s.com*/
 * @param flags
 * @return
 */
public ClassNode getClassNode(int flags) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(this.mixinBytes);
    classReader.accept(classNode, flags);
    return classNode;
}

From source file:org.spongepowered.mod.asm.transformers.PriorityTransformer.java

License:MIT License

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {

    if (bytes == null || !name.equals("cpw.mods.fml.common.eventhandler.EventPriority")) {
        return bytes;
    }/*from  w  w w.ja v a 2s .co m*/

    try {
        ClassReader cr = new ClassReader(bytes);
        ClassNode classNode = new ClassNode();
        cr.accept(classNode, 0);

        ClassWriter cw = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES);
        CheckClassAdapter checker = new CheckClassAdapter(cw);
        classNode.accept(checker);
        return cw.toByteArray();
    } catch (Throwable t) {
        t.printStackTrace();
        return bytes;
    }
}

From source file:org.spongepowered.server.launch.transformer.deobf.NotchDeobfuscationTransformer.java

License:MIT License

private void createSuperMaps(ClassReader reader, String name, @Nullable String superName,
        @Nullable String[] interfaces) {
    loadedClasses.add(name);/*  www  .ja v  a2 s. com*/

    Map<String, String> fields = new HashMap<>();
    Map<String, String> methods = new HashMap<>();

    if (superName != null) {
        addInheritedMembers(superName, fields, methods);
    }

    if (interfaces != null) {
        for (String parent : interfaces) {
            addInheritedMembers(parent, fields, methods);
        }
    }

    Map<String, String> raw = this.rawFields.row(name);
    if (!raw.isEmpty()) {
        // Resolve field descriptors
        ClassNode classNode = new ClassNode();
        reader.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);

        for (FieldNode fieldNode : classNode.fields) {
            String newName = raw.get(fieldNode.name);
            if (newName != null) {
                fields.put(fieldNode.name + ':' + fieldNode.desc, newName);
            }
        }
    }

    methods.putAll(this.rawMethods.row(name));

    this.fields.put(name, ImmutableMap.copyOf(fields));
    this.methods.put(name, ImmutableMap.copyOf(methods));
}

From source file:org.spongepowered.test.ast.TestHelper.java

License:Open Source License

public static StatementBlock get(Class<?> cls, String method_name) throws IOException {
    TypeEntry type = cached_types.get(cls);
    if (type == null) {
        String path = cls.getProtectionDomain().getCodeSource().getLocation().getPath();
        File file = new File(path, cls.getName().replace('.', '/') + ".class");
        ClassReader cr = new ClassReader(new FileInputStream(file));
        ClassNode cn = new ClassNode();
        cr.accept(cn, 0);/*from   w  w w  .j  a  v a2 s.  c o  m*/
        type = SingularClassLoader.instance.load(cn, null);
    }
    return type.getMethod(method_name).getInstructions();
}

From source file:org.spongepowered.test.ast.TestHelper.java

License:Open Source License

public static String getAsString(Class<?> cls, String method_name) throws IOException {
    TypeEntry type = cached_types.get(cls);
    if (type == null) {
        String path = cls.getProtectionDomain().getCodeSource().getLocation().getPath();
        File file = new File(path, cls.getName().replace('.', '/') + ".class");
        ClassReader cr = new ClassReader(new FileInputStream(file));
        ClassNode cn = new ClassNode();
        cr.accept(cn, 0);//from ww w .  ja  v a  2 s  . co m
        type = SingularClassLoader.instance.load(cn, null);
    }
    StatementBlock stmt = type.getMethod(method_name).getInstructions();
    StringWriter writer = new StringWriter();
    SourceEmitter emitter = new SourceEmitter(writer);
    emitter.emitBody(stmt);
    return writer.toString();
}