Skip to content

Commit 3008489

Browse files
Add general parameter naming
1 parent 18c9023 commit 3008489

File tree

4 files changed

+98
-33
lines changed

4 files changed

+98
-33
lines changed

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

+24-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public class MCInjector
3030
private Path fileIn, fileOut;
3131
private Path excIn, excOut;
3232
private Path accIn, accOut;
33-
private Path ctrIn, ctrOut;
33+
private Path ctrIn;
34+
private Path prmIn, prmOut;
3435
private LVTNaming lvt;
3536

3637
public MCInjector(Path fileIn, Path fileOut)
@@ -104,9 +105,15 @@ public MCInjector constructors(Path ctrs)
104105
return this;
105106
}
106107

107-
public MCInjector constructorsOut(Path out)
108+
public MCInjector parameters(Path ctrs)
108109
{
109-
this.ctrOut = out;
110+
this.prmIn = ctrs;
111+
return this;
112+
}
113+
114+
public MCInjector parametersOut(Path out)
115+
{
116+
this.prmOut = out;
110117
return this;
111118
}
112119

@@ -121,8 +128,9 @@ public void process() throws IOException
121128
{
122129
MCInjectorImpl.process(fileIn, fileOut,
123130
accIn, accOut,
124-
ctrIn, ctrOut,
131+
ctrIn,
125132
excIn, excOut,
133+
prmIn, prmOut,
126134
lvt);
127135
}
128136

@@ -174,7 +182,9 @@ public static void main(String[] args) throws Exception
174182
OptionSpec<Path> acc = parser.accepts("acc") .withRequiredArg().withValuesConvertedBy(PATH_ARG);
175183
OptionSpec<Path> accOut = parser.accepts("accOut").withRequiredArg().withValuesConvertedBy(PATH_ARG);
176184
OptionSpec<Path> ctr = parser.accepts("ctr") .withRequiredArg().withValuesConvertedBy(PATH_ARG);
177-
OptionSpec<Path> ctrOut = parser.accepts("ctrOut").withRequiredArg().withValuesConvertedBy(PATH_ARG);
185+
OptionSpec<Path> ctrOut = parser.accepts("ctrOut").withRequiredArg().withValuesConvertedBy(PATH_ARG).describedAs("legacy, can't be used anymore");
186+
OptionSpec<Path> prm = parser.accepts("prm") .withRequiredArg().withValuesConvertedBy(PATH_ARG);
187+
OptionSpec<Path> prmOut = parser.accepts("prmOut").withRequiredArg().withValuesConvertedBy(PATH_ARG);
178188
OptionSpec<Level> logLvl = parser.accepts("level") .withRequiredArg().withValuesConvertedBy(LEVEL_ARG).defaultsTo(Level.INFO);
179189
OptionSpec<LVTNaming> lvt = parser.accepts("lvt").withRequiredArg().ofType(LVTNaming.class).defaultsTo(LVTNaming.STRIP);
180190

@@ -192,6 +202,11 @@ else if (o.has(ver))
192202
System.out.println(VERSION);
193203
return;
194204
}
205+
else if (o.has(ctrOut))
206+
{
207+
System.out.println("ctrOut is using the legacy format and is no longer supported!");
208+
return;
209+
}
195210

196211
MCInjector.LOG.setUseParentHandlers(false);
197212
MCInjector.LOG.setLevel(o.valueOf(logLvl));
@@ -205,7 +220,8 @@ else if (o.has(ver))
205220
LOG.info("Access: " + o.valueOf(acc));
206221
LOG.info(" " + o.valueOf(accOut));
207222
LOG.info("Constructors: " + o.valueOf(ctr));
208-
LOG.info(" " + o.valueOf(ctrOut));
223+
LOG.info("Extra Params: " + o.valueOf(prm));
224+
LOG.info(" " + o.valueOf(prmOut));
209225
LOG.info("LVT: " + o.valueOf(lvt));
210226

211227
try
@@ -219,7 +235,8 @@ else if (o.has(ver))
219235
.access(o.valueOf(acc))
220236
.accessOut(o.valueOf(accOut))
221237
.constructors(o.valueOf(ctr))
222-
.constructorsOut(o.valueOf(ctrOut))
238+
.parameters(o.valueOf(prm))
239+
.parametersOut(o.valueOf(prmOut))
223240
.process();
224241
}
225242
catch (Exception e)

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import de.oceanlabs.mcp.mcinjector.adaptors.InnerClassInitAdder;
3333
import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
3434
import de.oceanlabs.mcp.mcinjector.data.Access;
35-
import de.oceanlabs.mcp.mcinjector.data.Constructors;
35+
import de.oceanlabs.mcp.mcinjector.data.Parameters;
3636
import de.oceanlabs.mcp.mcinjector.data.Exceptions;
3737
import de.oceanlabs.mcp.mcinjector.lvt.LVTFernflower;
3838
import de.oceanlabs.mcp.mcinjector.lvt.LVTLvt;
@@ -47,15 +47,18 @@ public class MCInjectorImpl
4747
static void process(
4848
Path in, Path out,
4949
Path accIn, Path accOut,
50-
Path ctrIn, Path ctrOut,
50+
Path ctrIn,
5151
Path excIn, Path excOut,
52+
Path prmIn, Path prmOut,
5253
LVTNaming naming)
5354
throws IOException
5455
{
5556
if (accIn != null)
5657
Access.INSTANCE.load(accIn);
58+
if (prmIn != null)
59+
Parameters.INSTANCE.load(prmIn);
5760
if (ctrIn != null)
58-
Constructors.INSTANCE.load(ctrIn);
61+
Parameters.INSTANCE.loadLegacy(ctrIn);
5962
if (excIn != null)
6063
Exceptions.INSTANCE.load(excIn);
6164

@@ -69,8 +72,8 @@ static void process(
6972

7073
if (accOut != null)
7174
Access.INSTANCE.dump(accOut);
72-
if (ctrOut != null)
73-
Constructors.INSTANCE.dump(ctrOut);
75+
if (prmOut != null)
76+
Parameters.INSTANCE.dump(prmOut);
7477
if (excOut != null)
7578
Exceptions.INSTANCE.dump(excOut);
7679

src/main/java/de/oceanlabs/mcp/mcinjector/adaptors/ApplyMap.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Set;
1111
import java.util.logging.Level;
1212

13+
import de.oceanlabs.mcp.mcinjector.data.Parameters;
1314
import org.objectweb.asm.ClassVisitor;
1415
import org.objectweb.asm.MethodVisitor;
1516
import org.objectweb.asm.Opcodes;
@@ -21,12 +22,12 @@
2122

2223
import de.oceanlabs.mcp.mcinjector.MCInjector;
2324
import de.oceanlabs.mcp.mcinjector.MCInjectorImpl;
24-
import de.oceanlabs.mcp.mcinjector.data.Constructors;
2525
import de.oceanlabs.mcp.mcinjector.data.Exceptions;
2626

2727
public class ApplyMap extends ClassVisitor
2828
{
2929
String className;
30+
boolean isEnum;
3031
MCInjectorImpl injector;
3132

3233
public ApplyMap(MCInjectorImpl injector, ClassVisitor cn)
@@ -39,6 +40,7 @@ public ApplyMap(MCInjectorImpl injector, ClassVisitor cn)
3940
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
4041
{
4142
this.className = name;
43+
isEnum = (access & Opcodes.ACC_ENUM) != 0;
4244
super.visit(version, access, name, signature, superName, interfaces);
4345
}
4446

@@ -95,9 +97,11 @@ private void processLVT(String cls, String name, String desc, MethodNode mn)
9597
{
9698
List<String> params = new ArrayList<>();
9799
List<Type> types = new ArrayList<>();
100+
boolean isStatic = true;
98101

99102
if ((mn.access & Opcodes.ACC_STATIC) == 0)
100103
{
104+
isStatic = false;
101105
types.add(Type.getType("L" + cls + ";"));
102106
params.add(0, "this");
103107
}
@@ -109,11 +113,12 @@ private void processLVT(String cls, String name, String desc, MethodNode mn)
109113
return;
110114

111115
MCInjector.LOG.fine(" Generating map:");
112-
String nameFormat = "p_" + name + "_%d_";
116+
String nameFormat = null;
113117
if (name.matches("func_\\d+_.+")) // A srg name method params are just p_MethodID_ParamIndex_
114118
nameFormat = "p_" + name.substring(5, name.indexOf('_', 5)) + "_%s_";
115-
else if (name.equals("<init>")) // Every constructor is given a unique ID, try to load the ID from the map, if none is found assign a new one
116-
nameFormat = "p_i" + Constructors.INSTANCE.getID(className, desc, types.size() > 1) + "_%s_";
119+
else if(!isSynthetic(mn))
120+
nameFormat = "p_" + Parameters.INSTANCE.getName(className, name, desc, types.size() > params.size(), isStatic) + "_%s_"; //assign new name only if there are names remaining
121+
else nameFormat = "p_%s_"; //don't really care about synthetics
117122

118123
for (int x = params.size(), y = x; x < types.size(); x++)
119124
{
@@ -190,4 +195,18 @@ else if (tmp.getType() != AbstractInsnNode.LABEL)
190195

191196
Collections.sort(mn.localVariables, (o1, o2) -> o1.index < o2.index ? -1 : (o1.index == o2.index ? 0 : 1));
192197
}
198+
199+
private boolean isSynthetic(MethodNode mn){
200+
if ((mn.access & Opcodes.ACC_SYNTHETIC) != 0) return true;
201+
202+
//check for special case pursuant to JLS 13.1.7
203+
//which specifies that these are the one and only proper methods that may be generated and not be marked synthetic
204+
if (isEnum && (mn.access & Opcodes.ACC_STATIC) != 0) {
205+
if ("valueOf".equals(mn.name) && mn.desc.equals("(Ljava/lang/String;)L" + className + ";"))
206+
return true;
207+
if("values".equals(mn.name) && mn.desc.equals("()[L" + className + ";"))
208+
return true;
209+
}
210+
return false;
211+
}
193212
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package de.oceanlabs.mcp.mcinjector.data;
22

3+
import de.oceanlabs.mcp.mcinjector.MCInjector;
4+
35
import java.io.IOException;
46
import java.nio.charset.StandardCharsets;
57
import java.nio.file.Files;
@@ -10,9 +12,7 @@
1012
import java.util.Map;
1113
import java.util.stream.Collectors;
1214

13-
import de.oceanlabs.mcp.mcinjector.MCInjector;
14-
15-
public enum Constructors
15+
public enum Parameters
1616
{
1717
INSTANCE;
1818

@@ -26,7 +26,7 @@ public boolean load(Path file)
2626
this.fromID.clear();
2727
try
2828
{
29-
MCInjector.LOG.fine("Loading Constructors from: " + file);
29+
MCInjector.LOG.fine("Loading Parameters from: " + file);
3030
Files.readAllLines(file).forEach(line ->
3131
{
3232
line = line.trim();
@@ -35,19 +35,44 @@ public boolean load(Path file)
3535

3636
String[] parts = line.split(" " );
3737
int id = Integer.parseInt(parts[0]);
38-
MCInjector.LOG.fine(" Constructor ID loaded " + id + " " + parts[0] + " " + parts[1]);
39-
this.setID(parts[1], parts[2], id);
38+
MCInjector.LOG.fine(" Method parameter ID loaded " + id + " " + parts[0] + " " + parts[1] + " " + parts[3]);
39+
this.setName(parts[1], parts[2], parts[3], id);
4040
});
4141
}
4242
catch (IOException e)
4343
{
4444
e.printStackTrace();
45-
MCInjector.LOG.warning("Could not load Constructors list: " + e.toString());
45+
MCInjector.LOG.warning("Could not load Parameters list: " + e.toString());
4646
return false;
4747
}
4848
return true;
4949
}
5050

51+
public boolean loadLegacy(Path file)
52+
{
53+
try {
54+
MCInjector.LOG.fine("Loading Constructors from: " + file);
55+
Files.readAllLines(file).forEach(line ->
56+
{
57+
line = line.trim();
58+
if (line.isEmpty() || line.startsWith("#"))
59+
return;
60+
61+
String[] parts = line.split(" " );
62+
int id = Integer.parseInt(parts[0]);
63+
MCInjector.LOG.fine(" Legacy Constructor ID loaded " + id + " " + parts[0] + " " + parts[1]);
64+
this.setName(parts[1], "<init>", parts[2], id);
65+
});
66+
return true;
67+
}
68+
catch (IOException e)
69+
{
70+
e.printStackTrace();
71+
MCInjector.LOG.warning("Could not import Constructors list: " + e.toString());
72+
return false;
73+
}
74+
}
75+
5176
public boolean dump(Path file)
5277
{
5378
try
@@ -61,31 +86,32 @@ public boolean dump(Path file)
6186
catch (IOException e)
6287
{
6388
e.printStackTrace();
64-
MCInjector.LOG.warning("Could not dump Constructors list: " + e.toString());
89+
MCInjector.LOG.warning("Could not dump Parameters list: " + e.toString());
6590
return false;
6691
}
6792
return true;
6893
}
6994

70-
public void setID(String cls, String desc, int id)
95+
public void setName(String cls, String method, String desc, int id)
7196
{
7297
if (id < 0)
7398
throw new IllegalArgumentException("ID must be positive: " + id);
7499
this.maxID = Math.max(this.maxID, id);
75-
this.fromDesc.put(cls + " " + desc, id);
76-
this.fromID .put(id, cls + " " + desc);
100+
this.fromDesc.put(cls + " " + method + " " + desc, id);
101+
this.fromID .put(id, cls + " " + method + " " + desc);
77102
}
78103

79-
public int getID(String cls, String desc, boolean generate)
104+
public String getName(String cls, String method, String desc, boolean generate, boolean isStatic)
80105
{
81-
Integer id = this.fromDesc.get(cls + " " + desc);
106+
Integer id = this.fromDesc.get(cls + " " + method + " " + desc);
82107
if (id == null)
83108
{
84109
if (!generate)
85-
return -1;
86-
id = ++maxID;
87-
this.setID(cls, desc, id);
110+
return method; //if we are not generating new names we will return the old parameter format, _p_funcname_x_
111+
int newId = ++maxID;
112+
this.setName(cls, method, desc, newId);
113+
return Integer.toString(newId);
88114
}
89-
return id;
115+
return Integer.toString(id);
90116
}
91117
}

0 commit comments

Comments
 (0)