Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 6702c75

Browse files
authored
Fix annotation scanning argument object types (#76)
* Fix annotation scanning argument object wrappers * rename * Renames and minor changes * Minor rename
1 parent c9f2cdf commit 6702c75

2 files changed

Lines changed: 167 additions & 16 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.fml.loading.moddiscovery;
21+
22+
import java.lang.annotation.ElementType;
23+
import java.util.ArrayList;
24+
import java.util.Map;
25+
26+
import com.google.common.base.MoreObjects;
27+
import com.google.common.collect.Lists;
28+
import com.google.common.collect.Maps;
29+
import net.minecraftforge.forgespi.language.ModFileScanData;
30+
import org.objectweb.asm.Type;
31+
32+
public class ModAnnotation {
33+
private final ElementType type;
34+
private final Type asmType;
35+
private final String member;
36+
private final Map<String, Object> elements;
37+
private ArrayList<Object> arrayList;
38+
private String arrayName;
39+
40+
public static ModFileScanData.AnnotationData fromModAnnotation(Type clazz, ModAnnotation annotation) {
41+
return new ModFileScanData.AnnotationData(
42+
annotation.asmType, annotation.type, clazz, annotation.member, annotation.elements
43+
);
44+
}
45+
46+
public ModAnnotation(ElementType type, Type asmType, String member) {
47+
this.elements = Maps.newHashMap();
48+
this.type = type;
49+
this.asmType = asmType;
50+
this.member = member;
51+
}
52+
53+
public ModAnnotation(Type asmType, ModAnnotation parent) {
54+
this.elements = Maps.newHashMap();
55+
this.type = parent.type;
56+
this.asmType = asmType;
57+
this.member = parent.member;
58+
}
59+
60+
public String toString() {
61+
return MoreObjects.toStringHelper("Annotation")
62+
.add("type", this.type).add("name", this.asmType.getClassName())
63+
.add("member", this.member).add("values", this.elements).toString();
64+
}
65+
66+
public ElementType getType() {
67+
return this.type;
68+
}
69+
70+
public String getMember() {
71+
return this.member;
72+
}
73+
74+
public Map<String, Object> getValues() {
75+
return this.elements;
76+
}
77+
78+
public void addArray(String name) {
79+
this.arrayList = Lists.newArrayList();
80+
this.arrayName = name;
81+
}
82+
83+
public void addProperty(String key, Object value) {
84+
if (this.arrayList != null) {
85+
this.arrayList.add(value);
86+
} else {
87+
this.elements.put(key, value);
88+
}
89+
}
90+
91+
public void addEnumProperty(String key, String enumName, String value) {
92+
this.addProperty(key, new ModAnnotation.EnumHolder(enumName, value));
93+
}
94+
95+
public void endArray() {
96+
this.elements.put(this.arrayName, this.arrayList);
97+
this.arrayList = null;
98+
}
99+
100+
public ModAnnotation addChildAnnotation(String name, String desc) {
101+
ModAnnotation child = new ModAnnotation(Type.getType(desc), this);
102+
this.addProperty(name, child.getValues());
103+
return child;
104+
}
105+
106+
public static class EnumHolder {
107+
private final String desc;
108+
private final String value;
109+
110+
public EnumHolder(String desc, String value) {
111+
this.desc = desc;
112+
this.value = value;
113+
}
114+
115+
public String getDesc() {
116+
return this.desc;
117+
}
118+
119+
public String getValue() {
120+
return this.value;
121+
}
122+
}
123+
}

patchwork-fml/src/main/java/net/minecraftforge/forgespi/language/ModFileScanData.java

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.stream.Collectors;
3636

3737
import com.google.gson.Gson;
38+
import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation;
3839
import org.apache.logging.log4j.LogManager;
3940
import org.apache.logging.log4j.Logger;
4041
import org.objectweb.asm.Type;
@@ -110,8 +111,7 @@ public static class AnnotationData {
110111
private final Type clazz;
111112
private final String memberName;
112113

113-
//lazy evaluated
114-
private Map<String, Object> annotationData;
114+
private Map<String, Object> elements;
115115

116116
public AnnotationData(
117117
final Type annotationType, final ElementType targetType,
@@ -123,6 +123,17 @@ public AnnotationData(
123123
this.memberName = memberName;
124124
}
125125

126+
public AnnotationData(
127+
Type annotationType, ElementType targetType, Type clazz,
128+
String memberName, Map<String, Object> elements
129+
) {
130+
this.annotationType = annotationType;
131+
this.targetType = targetType;
132+
this.clazz = clazz;
133+
this.memberName = memberName;
134+
this.elements = elements;
135+
}
136+
126137
public Type getAnnotationType() {
127138
return annotationType;
128139
}
@@ -140,15 +151,15 @@ public String getMemberName() {
140151
}
141152

142153
public Map<String, Object> getAnnotationData() {
143-
if (annotationData == null) {
154+
if (elements == null) {
144155
initAnnotationData();
145156
}
146157

147-
return annotationData;
158+
return elements;
148159
}
149160

150161
private void initAnnotationData() {
151-
annotationData = new HashMap<>();
162+
elements = new HashMap<>();
152163

153164
try {
154165
// TODO: This *may* load classes in the wrong order, but it shouldn't be an issue
@@ -163,22 +174,21 @@ private void initAnnotationData() {
163174
return;
164175
}
165176

166-
Method[] argMethods = annotationObject.getClass().getDeclaredMethods();
177+
Method[] elementGetters = annotationObject.getClass().getDeclaredMethods();
167178

168-
for (Method argMethod : argMethods) {
169-
if (isArgumentMethod(argMethod)) {
170-
annotationData.put(
171-
argMethod.getName(),
172-
argMethod.invoke(annotationObject)
173-
);
179+
for (Method elementGetter : elementGetters) {
180+
if (isElementGetter(elementGetter)) {
181+
Object value = elementGetter.invoke(annotationObject);
182+
183+
elements.put(elementGetter.getName(), processElementObject(value));
174184
}
175185
}
176186
} catch (Throwable e) {
177187
LOGGER.catching(e);
178188
}
179189
}
180190

181-
private static boolean isArgumentMethod(Method method) {
191+
private static boolean isElementGetter(Method method) {
182192
String name = method.getName();
183193
if (name.equals("toString")) return false;
184194
if (name.equals("hashCode")) return false;
@@ -199,15 +209,14 @@ private Annotation getAnnotationObject(Class<?> clazzObj, Class annotationType)
199209
case METHOD:
200210
String methodName = memberName.substring(0, memberName.indexOf('('));
201211
Method[] methods = Arrays.stream(clazzObj.getDeclaredMethods())
202-
.filter(method -> method.getName().equals(methodName))
203-
.toArray(Method[]::new);
212+
.filter(method -> method.getName().equals(methodName))
213+
.toArray(Method[]::new);
204214
if (methods.length == 0) {
205215
throw new RuntimeException("Cannot find method " + methodName);
206216
}
207217

208218
if (methods.length > 1) {
209219
//TODO handle overloaded methods
210-
211220
throw new RuntimeException("Currently Cannot Handle Overloaded Methods");
212221
}
213222

@@ -235,4 +244,23 @@ public int hashCode() {
235244
return Objects.hash(annotationType, targetType, clazz, memberName);
236245
}
237246
}
247+
248+
private static Object processElementObject(Object object) {
249+
if (object instanceof Object[]) {
250+
return Arrays.stream((Object[]) object)
251+
.map(ModFileScanData::processElementObject)
252+
.collect(Collectors.toList());
253+
}
254+
255+
if (object instanceof Enum) {
256+
Enum enumObject = (Enum) object;
257+
String className = enumObject.getDeclaringClass().getName();
258+
return new ModAnnotation.EnumHolder(
259+
className.replace('.', '/'),
260+
enumObject.toString()
261+
);
262+
}
263+
264+
return object;
265+
}
238266
}

0 commit comments

Comments
 (0)