Merge pull request #609 from Zot201/1.8

Add transformer to allow protected/private classes to use the event bus.
This commit is contained in:
LexManos 2015-03-04 09:49:25 -08:00
commit 7223e1a7d9
3 changed files with 76 additions and 1 deletions

View File

@ -0,0 +1,74 @@
package net.minecraftforge.fml.common.asm.transformers;
import java.lang.reflect.Modifier;
import java.util.List;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
public class EventSubscriberTransformer implements IClassTransformer
{
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass)
{
if (basicClass == null) return null;
ClassNode classNode = new ClassNode();
new ClassReader(basicClass).accept(classNode, 0);
boolean isSubscriber = false;
for (MethodNode methodNode : classNode.methods)
{
List<AnnotationNode> anns = methodNode.visibleAnnotations;
if (anns != null && Iterables.any(anns, SubscribeEventPredicate.INSTANCE))
{
if (Modifier.isPrivate(methodNode.access))
{
String msg = "Cannot apply @SubsribeEvent to private method %s/%s%s";
throw new RuntimeException(String.format(msg, classNode.name, methodNode.name, methodNode.desc));
}
methodNode.access = toPublic(methodNode.access);
isSubscriber = true;
}
}
if (isSubscriber)
{
classNode.access = toPublic(classNode.access);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
return basicClass;
}
private static int toPublic(int access)
{
return access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED) | Opcodes.ACC_PUBLIC;
}
private static class SubscribeEventPredicate implements Predicate<AnnotationNode>
{
static final SubscribeEventPredicate INSTANCE = new SubscribeEventPredicate();
@Override
public boolean apply(AnnotationNode input)
{
return input.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/SubscribeEvent;");
}
}
}

View File

@ -82,7 +82,7 @@ public class EventBus implements IEventExceptionHandler
throw new IllegalArgumentException("Method " + method + " has @SubscribeEvent annotation, but takes a argument that is not an Event " + eventType);
}
register(eventType, target, method, activeModContainer);
register(eventType, target, real, activeModContainer);
break;
}
}

View File

@ -24,6 +24,7 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
"net.minecraftforge.fml.common.asm.transformers.MarkerTransformer",
"net.minecraftforge.fml.common.asm.transformers.SideTransformer",
"net.minecraftforge.fml.common.asm.transformers.EventSubscriptionTransformer",
"net.minecraftforge.fml.common.asm.transformers.EventSubscriberTransformer",
};
}