use of org.objectweb.asm.tree.FieldNode in project MinecraftForge by MinecraftForge.
the class EventSubscriptionTransformer method buildEvents.
private boolean buildEvents(ClassNode classNode) throws Exception {
// Yes, this recursively loads classes until we get this base class. THIS IS NOT A ISSUE. Coremods should handle re-entry just fine.
// If they do not this a COREMOD issue NOT a Forge/LaunchWrapper issue.
Class<?> parent = this.getClass().getClassLoader().loadClass(classNode.superName.replace('/', '.'));
if (!Event.class.isAssignableFrom(parent)) {
return false;
}
//Class<?> listenerListClazz = Class.forName("net.minecraftforge.fml.common.eventhandler.ListenerList", false, getClass().getClassLoader());
Type tList = Type.getType("Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
boolean edited = false;
boolean hasSetup = false;
boolean hasGetListenerList = false;
boolean hasDefaultCtr = false;
boolean hasCancelable = false;
boolean hasResult = false;
String voidDesc = Type.getMethodDescriptor(VOID_TYPE);
String boolDesc = Type.getMethodDescriptor(BOOLEAN_TYPE);
String listDesc = tList.getDescriptor();
String listDescM = Type.getMethodDescriptor(tList);
for (MethodNode method : classNode.methods) {
if (method.name.equals("setup") && method.desc.equals(voidDesc) && (method.access & ACC_PROTECTED) == ACC_PROTECTED)
hasSetup = true;
if ((method.access & ACC_PUBLIC) == ACC_PUBLIC) {
if (method.name.equals("getListenerList") && method.desc.equals(listDescM))
hasGetListenerList = true;
if (method.name.equals("isCancelable") && method.desc.equals(boolDesc))
hasCancelable = true;
if (method.name.equals("hasResult") && method.desc.equals(boolDesc))
hasResult = true;
}
if (method.name.equals("<init>") && method.desc.equals(voidDesc))
hasDefaultCtr = true;
}
if (classNode.visibleAnnotations != null) {
for (AnnotationNode node : classNode.visibleAnnotations) {
if (!hasResult && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Event$HasResult;")) {
/* Add:
* public boolean hasResult()
* {
* return true;
* }
*/
MethodNode method = new MethodNode(ACC_PUBLIC, "hasResult", boolDesc, null, null);
method.instructions.add(new InsnNode(ICONST_1));
method.instructions.add(new InsnNode(IRETURN));
classNode.methods.add(method);
edited = true;
} else if (!hasCancelable && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Cancelable;")) {
/* Add:
* public boolean isCancelable()
* {
* return true;
* }
*/
MethodNode method = new MethodNode(ACC_PUBLIC, "isCancelable", boolDesc, null, null);
method.instructions.add(new InsnNode(ICONST_1));
method.instructions.add(new InsnNode(IRETURN));
classNode.methods.add(method);
edited = true;
}
}
}
if (hasSetup) {
if (!hasGetListenerList)
throw new RuntimeException("Event class defines setup() but does not define getListenerList! " + classNode.name);
else
return edited;
}
Type tSuper = Type.getType(classNode.superName);
//Add private static ListenerList LISTENER_LIST
classNode.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, "LISTENER_LIST", listDesc, null, null));
/*Add:
* public <init>()
* {
* super();
* }
*/
if (!hasDefaultCtr) {
MethodNode method = new MethodNode(ACC_PUBLIC, "<init>", voidDesc, null, null);
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "<init>", voidDesc, false));
method.instructions.add(new InsnNode(RETURN));
classNode.methods.add(method);
}
/*Add:
* protected void setup()
* {
* super.setup();
* if (LISTENER_LIST != NULL)
* {
* return;
* }
* LISTENER_LIST = new ListenerList(super.getListenerList());
* }
*/
MethodNode method = new MethodNode(ACC_PROTECTED, "setup", voidDesc, null, null);
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "setup", voidDesc, false));
method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
LabelNode initListener = new LabelNode();
method.instructions.add(new JumpInsnNode(IFNULL, initListener));
method.instructions.add(new InsnNode(RETURN));
method.instructions.add(initListener);
method.instructions.add(new FrameNode(F_SAME, 0, null, 0, null));
method.instructions.add(new TypeInsnNode(NEW, tList.getInternalName()));
method.instructions.add(new InsnNode(DUP));
method.instructions.add(new VarInsnNode(ALOAD, 0));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "getListenerList", listDescM, false));
method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tList.getInternalName(), "<init>", getMethodDescriptor(VOID_TYPE, tList), false));
method.instructions.add(new FieldInsnNode(PUTSTATIC, classNode.name, "LISTENER_LIST", listDesc));
method.instructions.add(new InsnNode(RETURN));
classNode.methods.add(method);
/*Add:
* public ListenerList getListenerList()
* {
* return this.LISTENER_LIST;
* }
*/
method = new MethodNode(ACC_PUBLIC, "getListenerList", listDescM, null, null);
method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
method.instructions.add(new InsnNode(ARETURN));
classNode.methods.add(method);
return true;
}
use of org.objectweb.asm.tree.FieldNode in project MinecraftForge by MinecraftForge.
the class SideTransformer method transform.
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
if (bytes == null) {
return null;
}
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
if (remove(classNode.visibleAnnotations, SIDE)) {
if (DEBUG) {
System.out.println(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
}
throw new RuntimeException(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
}
Iterator<FieldNode> fields = classNode.fields.iterator();
while (fields.hasNext()) {
FieldNode field = fields.next();
if (remove(field.visibleAnnotations, SIDE)) {
if (DEBUG) {
System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
}
fields.remove();
}
}
LambdaGatherer lambdaGatherer = new LambdaGatherer();
Iterator<MethodNode> methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = methods.next();
if (remove(method.visibleAnnotations, SIDE)) {
if (DEBUG) {
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
}
methods.remove();
lambdaGatherer.accept(method);
}
}
// remove dynamic lambda methods that are inside of removed methods
List<Handle> dynamicLambdaHandles = lambdaGatherer.getDynamicLambdaHandles();
if (!dynamicLambdaHandles.isEmpty()) {
methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = methods.next();
for (Handle dynamicLambdaHandle : dynamicLambdaHandles) {
if (method.name.equals(dynamicLambdaHandle.getName()) && method.desc.equals(dynamicLambdaHandle.getDesc())) {
if (DEBUG) {
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
}
methods.remove();
}
}
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
use of org.objectweb.asm.tree.FieldNode in project pinpoint by naver.
the class ASMClassNodeAdapter method getField.
public ASMFieldNodeAdapter getField(final String fieldName, final String fieldDesc) {
if (fieldName == null || this.classNode.fields == null) {
return null;
}
final List<FieldNode> fields = this.classNode.fields;
for (FieldNode fieldNode : fields) {
if ((fieldNode.name != null && fieldNode.name.equals(fieldName)) && (fieldDesc == null || (fieldNode.desc != null && fieldNode.desc.equals(fieldDesc)))) {
return new ASMFieldNodeAdapter(fieldNode);
}
}
// find interface.
final List<String> interfaces = this.classNode.interfaces;
if (interfaces != null && interfaces.size() > 0) {
for (String interfaceClassName : interfaces) {
if (interfaceClassName == null) {
continue;
}
final ASMClassNodeAdapter classNodeAdapter = ASMClassNodeAdapter.get(this.pluginContext, this.classLoader, interfaceClassName, true);
if (classNodeAdapter != null) {
final ASMFieldNodeAdapter fieldNode = classNodeAdapter.getField(fieldName, fieldDesc);
if (fieldNode != null) {
return fieldNode;
}
}
}
}
// find super class.
if (this.classNode.superName != null) {
final ASMClassNodeAdapter classNodeAdapter = ASMClassNodeAdapter.get(this.pluginContext, this.classLoader, this.classNode.superName, true);
if (classNodeAdapter != null) {
final ASMFieldNodeAdapter fieldNode = classNodeAdapter.getField(fieldName, fieldDesc);
if (fieldNode != null) {
return fieldNode;
}
}
}
return null;
}
use of org.objectweb.asm.tree.FieldNode in project pinpoint by naver.
the class ASMFieldNodeAdapterTest method getName.
@Test
public void getName() throws Exception {
ClassNode classNode = ASMClassNodeLoader.get("com.navercorp.pinpoint.profiler.instrument.mock.FieldClass");
List<FieldNode> fieldNodes = classNode.fields;
for (FieldNode fieldNode : fieldNodes) {
ASMFieldNodeAdapter adapter = new ASMFieldNodeAdapter(fieldNode);
assertNotNull(adapter.getName());
assertNotNull(adapter.getClassName());
assertNotNull(adapter.getDesc());
}
}
use of org.objectweb.asm.tree.FieldNode in project spring-loaded by spring-projects.
the class Utils method fieldNodeFormat.
// * The name value pairs of this annotation. Each name value pair is stored
// * as two consecutive elements in the list. The name is a {@link String},
// * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
// * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
// * {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an
// * two elements String array (for enumeration values), a
// * {@link AnnotationNode}, or a {@link List} of values of one of the
// * preceding types. The list may be <tt>null</tt> if there is no name
// * value pair.
public static String fieldNodeFormat(Collection<FieldNode> fieldNodes) {
StringBuilder s = new StringBuilder();
int n = 0;
for (FieldNode fieldNode : fieldNodes) {
if (n > 0) {
s.append(" ");
}
s.append("'").append(fieldNodeFormat(fieldNode)).append("'");
n++;
}
return s.toString();
}
Aggregations