From daf454af628e37f54297b3dc2e2e2a930a2cea84 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 9 Oct 2013 13:57:52 -0400 Subject: [PATCH] Support, and fix up, interface lists for Optional --- fml/common/cpw/mods/fml/common/Optional.java | 15 +++++++++++++ .../asm/transformers/ModAPITransformer.java | 22 ++++++++++++++++++- .../fml/common/discovery/ASMDataTable.java | 18 +++++++++++++-- .../common/discovery/asm/ModAnnotation.java | 15 ++++++++----- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/fml/common/cpw/mods/fml/common/Optional.java b/fml/common/cpw/mods/fml/common/Optional.java index 09b49b9454..2a2a9de225 100644 --- a/fml/common/cpw/mods/fml/common/Optional.java +++ b/fml/common/cpw/mods/fml/common/Optional.java @@ -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 diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java b/fml/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java index ed583111d6..62f5730c15 100644 --- a/fml/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java +++ b/fml/common/cpw/mods/fml/common/asm/transformers/ModAPITransformer.java @@ -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 interfaceLists = dataTable.getAll("cpw.mods.fml.common.Optional$InterfaceList"); + addData(unpackInterfaces(interfaceLists)); Set interfaces = dataTable.getAll("cpw.mods.fml.common.Optional$Interface"); addData(interfaces); Set methods = dataTable.getAll("cpw.mods.fml.common.Optional$Method"); addData(methods); } + private Set unpackInterfaces(Set packedInterfaces) + { + Set result = Sets.newHashSet(); + for (ASMData data : packedInterfaces) + { + List> packedList = (List>) data.getAnnotationInfo().get("value"); + for (Map packed : packedList) + { + ASMData newData = data.copy(packed); + result.add(newData); + } + } + + return result; + } private void addData(Set interfaces) { for (ASMData data : interfaces) diff --git a/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java b/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java index fca7363dd3..308e6a76fb 100644 --- a/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java +++ b/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java @@ -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 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 diff --git a/fml/common/cpw/mods/fml/common/discovery/asm/ModAnnotation.java b/fml/common/cpw/mods/fml/common/discovery/asm/ModAnnotation.java index 753275e3e0..8888e897fe 100644 --- a/fml/common/cpw/mods/fml/common/discovery/asm/ModAnnotation.java +++ b/fml/common/cpw/mods/fml/common/discovery/asm/ModAnnotation.java @@ -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; } }