From 3d25b4e793c59a9131a441d6c7a2d80cac9cd701 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 9 Nov 2013 14:27:15 -0500 Subject: [PATCH] Add in the ability to strip interface references for specific interfaces - this is probably mostly useful for scala scenarios where sythetic methods are generated and is not a substitute for using Optional.Method where appropriate. Closes #300 --- common/cpw/mods/fml/common/Optional.java | 7 ++++++ .../asm/transformers/ModAPITransformer.java | 25 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/common/cpw/mods/fml/common/Optional.java b/common/cpw/mods/fml/common/Optional.java index 2a2a9de225..53860fed87 100644 --- a/common/cpw/mods/fml/common/Optional.java +++ b/common/cpw/mods/fml/common/Optional.java @@ -51,6 +51,13 @@ public final class Optional { * @return the modid */ public String modid(); + + /** + * Strip references to this interface in method declarations? (Useful to kill synthetic methods from scala f.e.) + * + * @return if references should be stripped + */ + public boolean striprefs() default false; } /** * Used to remove optional methods diff --git a/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java b/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java index 5a0330d8a7..e9a7770e91 100644 --- a/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java @@ -58,7 +58,9 @@ public class ModAPITransformer implements IClassTransformer { if (optional.getAnnotationInfo().containsKey("iface")) { - stripInterface(classNode,(String)optional.getAnnotationInfo().get("iface")); + Boolean stripRefs = (Boolean)optional.getAnnotationInfo().get("striprefs"); + if (stripRefs == null) stripRefs = Boolean.FALSE; + stripInterface(classNode,(String)optional.getAnnotationInfo().get("iface"), stripRefs); } else { @@ -88,12 +90,31 @@ public class ModAPITransformer implements IClassTransformer { if (logDebugInfo) FMLRelaunchLog.finest("Optional removal - method %s NOT removed - not found", methodDescriptor); } - private void stripInterface(ClassNode classNode, String interfaceName) + private void stripInterface(ClassNode classNode, String interfaceName, boolean stripRefs) { String ifaceName = interfaceName.replace('.', '/'); boolean found = classNode.interfaces.remove(ifaceName); if (found && logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s removed", interfaceName); if (!found && logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s NOT removed - not found", interfaceName); + + if (found && stripRefs) + { + if (logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s - stripping method signature references", interfaceName); + for (Iterator iterator = classNode.methods.iterator(); iterator.hasNext();) + { + MethodNode node = iterator.next(); + if (node.desc.contains(ifaceName)) + { + if (logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s - stripping method containing reference %s", interfaceName, node.name); + iterator.remove(); + } + } + if (logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s - all method signature references stripped", interfaceName); + } + else if (found) + { + if (logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s - NOT stripping method signature references", interfaceName); + } } public void initTable(ASMDataTable dataTable)