Skip to content

Commit 73d0c29

Browse files
committed
Inject inner class atributes for any references in fields or methods. Should fix scala linking issues. TODO if needed: Scan all libraries not just Minecraft.
1 parent 6015659 commit 73d0c29

2 files changed

Lines changed: 111 additions & 4 deletions

File tree

src/main/java/de/oceanlabs/mcp/mcinjector/JsonAttributeClassAdaptor.java

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
import java.util.logging.Logger;
66

77
import org.objectweb.asm.ClassVisitor;
8+
import org.objectweb.asm.FieldVisitor;
9+
import org.objectweb.asm.MethodVisitor;
810
import org.objectweb.asm.Opcodes;
11+
import org.objectweb.asm.Type;
912

1013
public class JsonAttributeClassAdaptor extends ClassVisitor
1114
{
@@ -15,23 +18,84 @@ public class JsonAttributeClassAdaptor extends ClassVisitor
1518
private JsonStruct json;
1619
private boolean visitedOuter = false;
1720
private Set<String> visitedInners = new HashSet<String>();
21+
private Set<String> refedInners = new HashSet<String>();
22+
1823

1924
public JsonAttributeClassAdaptor(ClassVisitor cv, MCInjectorImpl mci)
2025
{
2126
super(Opcodes.ASM4, cv);
2227
this.mci = mci;
2328
}
2429

30+
private String getAccess(int access)
31+
{
32+
StringBuilder buf = new StringBuilder();
33+
if ((access & Opcodes.ACC_PUBLIC) != 0) buf.append("PUBLIC ");
34+
else if ((access & Opcodes.ACC_PRIVATE) != 0) buf.append("PRIVATE ");
35+
else if ((access & Opcodes.ACC_PROTECTED) != 0) buf.append("PROTECTED ");
36+
else buf.append("DEFAULT ");
37+
if ((access & Opcodes.ACC_FINAL) != 0) buf.append("FINAL ");
38+
if ((access & Opcodes.ACC_SUPER) != 0) buf.append("SUPER ");
39+
if ((access & Opcodes.ACC_INTERFACE) != 0) buf.append("INTERFACE ");
40+
if ((access & Opcodes.ACC_ABSTRACT) != 0) buf.append("ABSTRACT ");
41+
if ((access & Opcodes.ACC_SYNTHETIC) != 0) buf.append("SYNTHETIC ");
42+
if ((access & Opcodes.ACC_ANNOTATION) != 0) buf.append("ANNOTATION ");
43+
if ((access & Opcodes.ACC_ENUM) != 0) buf.append("ENUM ");
44+
return buf.toString().trim();
45+
}
46+
47+
private boolean isInnerClass(String name)
48+
{
49+
return name.contains("$");
50+
}
51+
52+
private void referenced(Type type)
53+
{
54+
if (type.getSort() == Type.ARRAY)
55+
type = type.getElementType();
56+
if (type.getSort() == Type.OBJECT)
57+
{
58+
String internal = type.getInternalName();
59+
if (isInnerClass(internal))
60+
refedInners.add(internal);
61+
}
62+
}
63+
2564
@Override
2665
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
2766
{
2867
this.className = name;
2968
json = mci.json.get(className);
3069
visitedOuter = false;
3170
visitedInners.clear();
71+
for (String i : interfaces)
72+
if (isInnerClass(i))
73+
refedInners.add(i);
3274
super.visit(version, access, name, signature, superName, interfaces);
3375
}
34-
76+
77+
@Override
78+
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
79+
{
80+
referenced(Type.getType(desc));
81+
return super.visitField(access, name, desc, signature, value);
82+
}
83+
84+
@Override
85+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
86+
{
87+
if (exceptions != null)
88+
for (String s : exceptions)
89+
if (isInnerClass(s))
90+
refedInners.add(s);
91+
92+
referenced(Type.getReturnType(desc));
93+
for (Type t : Type.getArgumentTypes(desc))
94+
referenced(t);
95+
96+
return super.visitMethod(access, name, desc, signature, exceptions);
97+
}
98+
3599
@Override
36100
public void visitInnerClass(String name, String outerName, String innerName, int access)
37101
{
@@ -58,7 +122,9 @@ public void visitEnd()
58122
JsonStruct.EnclosingMethod enc = json.enclosingMethod;
59123
if (enc != null && !visitedOuter && enc.name != null && enc.desc != null)
60124
{
61-
log.fine("Adding Outer Class: " + enc.owner + " " + enc.name + " " + enc.desc);
125+
log.fine(" Adding Outer Class:");
126+
log.fine(" Owner: " + enc.owner);
127+
log.fine(" Method: " + enc.name + enc.desc);
62128
super.visitOuterClass(enc.owner, enc.name, enc.desc);
63129
}
64130

@@ -68,10 +134,37 @@ public void visitEnd()
68134
{
69135
if (!visitedInners.contains(inner.inner_class))
70136
{
71-
log.fine("Adding Inner Class: " + inner.inner_class + " " + inner.getAccess() + " " + inner.outer_class + " " + inner.inner_name);
137+
visitedInners.add(inner.inner_class);
138+
log.fine(" Adding Inner Class:");
139+
log.fine(" Inner: " + inner.inner_class);
140+
log.fine(" Access: " + getAccess(inner.getAccess()));
141+
if (inner.outer_class != null)
142+
log.fine(" Outer: "+ inner.outer_class);
143+
if (inner.inner_name != null)
144+
log.fine(" Name: " + inner.inner_name);
72145
super.visitInnerClass(inner.inner_class, inner.outer_class, inner.inner_name, inner.getAccess());
73146
}
74147
}
75148
}
149+
150+
refedInners.removeAll(visitedInners);
151+
for (String inner : refedInners)
152+
{
153+
JsonStruct.InnerClass ic = mci.inners.get(inner);
154+
if (ic == null)
155+
{
156+
log.fine(" Referenced Inner Class: " + inner + " (missing)");
157+
}
158+
else
159+
{
160+
log.fine(" Referenced Inner Class:");
161+
log.fine(" Inner: " + ic.inner_class);
162+
log.fine(" Access: " + getAccess(ic.getAccess()));
163+
if (ic.outer_class != null)
164+
log.fine(" Outer: "+ ic.outer_class);
165+
if (ic.inner_name != null)
166+
log.fine(" Name: " + ic.inner_name);
167+
}
168+
}
76169
}
77170
}

src/main/java/de/oceanlabs/mcp/mcinjector/MCInjectorImpl.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class MCInjectorImpl
3939
{
4040
private final static Logger log = Logger.getLogger("MCInjector");
4141
public final Map<String, JsonStruct> json = new HashMap<String, JsonStruct>();
42+
public final Map<String, JsonStruct.InnerClass> inners = new HashMap<String, JsonStruct.InnerClass>();
4243
public final Properties mappings = new Properties();
4344
public final Properties outMappings = new Properties()
4445
{
@@ -187,7 +188,20 @@ public void loadJson(String classJson) throws IOException
187188
JsonObject object = (JsonObject)new JsonParser().parse(reader);
188189
for (Entry<String, JsonElement> entry : object.entrySet())
189190
{
190-
json.put(entry.getKey(), GSON.fromJson(entry.getValue(), JsonStruct.class));
191+
String name = entry.getKey();
192+
JsonStruct struct = GSON.fromJson(entry.getValue(), JsonStruct.class);
193+
json.put(name, struct);
194+
if (name.contains("$") && struct.innerClasses != null)
195+
{
196+
for (JsonStruct.InnerClass ic : struct.innerClasses)
197+
{
198+
if (name.equals(ic.inner_class))
199+
{
200+
inners.put(name, ic);
201+
break;
202+
}
203+
}
204+
}
191205
}
192206
}
193207
catch (IOException e)

0 commit comments

Comments
 (0)