List of usage examples for org.objectweb.asm.tree ClassNode ClassNode
public ClassNode()
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(); }