Support, and fix up, interface lists for Optional

This commit is contained in:
Christian 2013-10-09 13:57:52 -04:00
parent 1754a5820a
commit daf454af62
4 changed files with 62 additions and 8 deletions

View File

@ -17,6 +17,21 @@ public final class Optional {
* Not constructable
*/
private Optional() {}
/**
* Mark a list of interfaces as removable
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface InterfaceList {
/**
* Mark a list of interfaces for optional removal.
* @return
*/
public Interface[] value();
}
/**
* Used to remove optional interfaces
* @author cpw

View File

@ -1,6 +1,8 @@
package cpw.mods.fml.common.asm.transformers;
import java.lang.annotation.Annotation;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
@ -14,6 +16,7 @@ import org.objectweb.asm.tree.MethodNode;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
@ -52,7 +55,7 @@ public class ModAPITransformer implements IClassTransformer {
}
if (logDebugInfo) FMLRelaunchLog.finest("Optional on %s triggered - mod missing %s", name, modId);
if ("cpw.mods.fml.common.Optional$Interface".equals(optional.getAnnotationName()))
if (optional.getAnnotationInfo().containsKey("iface"))
{
stripInterface(classNode,(String)optional.getAnnotationInfo().get("iface"));
}
@ -95,12 +98,29 @@ public class ModAPITransformer implements IClassTransformer {
public void initTable(ASMDataTable dataTable)
{
optionals = ArrayListMultimap.create();
Set<ASMData> interfaceLists = dataTable.getAll("cpw.mods.fml.common.Optional$InterfaceList");
addData(unpackInterfaces(interfaceLists));
Set<ASMData> interfaces = dataTable.getAll("cpw.mods.fml.common.Optional$Interface");
addData(interfaces);
Set<ASMData> methods = dataTable.getAll("cpw.mods.fml.common.Optional$Method");
addData(methods);
}
private Set<ASMData> unpackInterfaces(Set<ASMData> packedInterfaces)
{
Set<ASMData> result = Sets.newHashSet();
for (ASMData data : packedInterfaces)
{
List<Map<String,Object>> packedList = (List<Map<String,Object>>) data.getAnnotationInfo().get("value");
for (Map<String,Object> packed : packedList)
{
ASMData newData = data.copy(packed);
result.add(newData);
}
}
return result;
}
private void addData(Set<ASMData> interfaces)
{
for (ASMData data : interfaces)

View File

@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@ -29,7 +29,7 @@ import cpw.mods.fml.common.ModContainer;
public class ASMDataTable
{
public static class ASMData
public final static class ASMData implements Cloneable
{
private ModCandidate candidate;
private String annotationName;
@ -64,6 +64,20 @@ public class ASMDataTable
{
return annotationInfo;
}
public ASMData copy(Map<String,Object> newAnnotationInfo)
{
try
{
ASMData clone = (ASMData) this.clone();
clone.annotationInfo = newAnnotationInfo;
return clone;
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException("Unpossible", e);
}
}
}
private static class ModContainerPredicate implements Predicate<ASMData>

View File

@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@ -52,7 +52,7 @@ public class ModAnnotation
this.asmType = asmType;
this.member = member;
}
public ModAnnotation(AnnotationType type, Type asmType, ModAnnotation parent)
{
this.type = type;
@ -101,12 +101,12 @@ public class ModAnnotation
values.put(key, value);
}
}
public void addEnumProperty(String key, String enumName, String value)
{
values.put(key, new EnumHolder(enumName, value));
}
public void endArray()
{
values.put(arrayName, arrayList);
@ -114,6 +114,11 @@ public class ModAnnotation
}
public ModAnnotation addChildAnnotation(String name, String desc)
{
return new ModAnnotation(AnnotationType.SUBTYPE, Type.getType(desc), this);
ModAnnotation child = new ModAnnotation(AnnotationType.SUBTYPE, Type.getType(desc), this);
if (arrayList != null)
{
arrayList.add(child.getValues());
}
return child;
}
}