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)