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
This commit is contained in:
Christian 2013-11-09 14:27:15 -05:00
parent 3b42a14dba
commit 7831555a7f
2 changed files with 30 additions and 2 deletions

View file

@ -51,6 +51,13 @@ public final class Optional {
* @return the modid * @return the modid
*/ */
public String 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 * Used to remove optional methods

View file

@ -58,7 +58,9 @@ public class ModAPITransformer implements IClassTransformer {
if (optional.getAnnotationInfo().containsKey("iface")) 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 else
{ {
@ -88,12 +90,31 @@ public class ModAPITransformer implements IClassTransformer {
if (logDebugInfo) FMLRelaunchLog.finest("Optional removal - method %s NOT removed - not found", methodDescriptor); 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('.', '/'); String ifaceName = interfaceName.replace('.', '/');
boolean found = classNode.interfaces.remove(ifaceName); 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 removed", interfaceName);
if (!found && logDebugInfo) FMLRelaunchLog.finest("Optional removal - interface %s NOT removed - not found", 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<MethodNode> 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) public void initTable(ASMDataTable dataTable)