Skip to content

Commit

Permalink
Add general parameter naming
Browse files Browse the repository at this point in the history
  • Loading branch information
JoJoDeveloping committed Jan 27, 2020
1 parent 18c9023 commit 3008489
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 33 deletions.
31 changes: 24 additions & 7 deletions src/main/java/de/oceanlabs/mcp/mcinjector/MCInjector.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public class MCInjector
private Path fileIn, fileOut;
private Path excIn, excOut;
private Path accIn, accOut;
private Path ctrIn, ctrOut;
private Path ctrIn;
private Path prmIn, prmOut;
private LVTNaming lvt;

public MCInjector(Path fileIn, Path fileOut)
Expand Down Expand Up @@ -104,9 +105,15 @@ public MCInjector constructors(Path ctrs)
return this;
}

public MCInjector constructorsOut(Path out)
public MCInjector parameters(Path ctrs)
{
this.ctrOut = out;
this.prmIn = ctrs;
return this;
}

public MCInjector parametersOut(Path out)
{
this.prmOut = out;
return this;
}

Expand All @@ -121,8 +128,9 @@ public void process() throws IOException
{
MCInjectorImpl.process(fileIn, fileOut,
accIn, accOut,
ctrIn, ctrOut,
ctrIn,
excIn, excOut,
prmIn, prmOut,
lvt);
}

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

Expand All @@ -192,6 +202,11 @@ else if (o.has(ver))
System.out.println(VERSION);
return;
}
else if (o.has(ctrOut))
{
System.out.println("ctrOut is using the legacy format and is no longer supported!");
return;
}

MCInjector.LOG.setUseParentHandlers(false);
MCInjector.LOG.setLevel(o.valueOf(logLvl));
Expand All @@ -205,7 +220,8 @@ else if (o.has(ver))
LOG.info("Access: " + o.valueOf(acc));
LOG.info(" " + o.valueOf(accOut));
LOG.info("Constructors: " + o.valueOf(ctr));
LOG.info(" " + o.valueOf(ctrOut));
LOG.info("Extra Params: " + o.valueOf(prm));
LOG.info(" " + o.valueOf(prmOut));
LOG.info("LVT: " + o.valueOf(lvt));

try
Expand All @@ -219,7 +235,8 @@ else if (o.has(ver))
.access(o.valueOf(acc))
.accessOut(o.valueOf(accOut))
.constructors(o.valueOf(ctr))
.constructorsOut(o.valueOf(ctrOut))
.parameters(o.valueOf(prm))
.parametersOut(o.valueOf(prmOut))
.process();
}
catch (Exception e)
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/de/oceanlabs/mcp/mcinjector/MCInjectorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import de.oceanlabs.mcp.mcinjector.adaptors.InnerClassInitAdder;
import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
import de.oceanlabs.mcp.mcinjector.data.Access;
import de.oceanlabs.mcp.mcinjector.data.Constructors;
import de.oceanlabs.mcp.mcinjector.data.Parameters;
import de.oceanlabs.mcp.mcinjector.data.Exceptions;
import de.oceanlabs.mcp.mcinjector.lvt.LVTFernflower;
import de.oceanlabs.mcp.mcinjector.lvt.LVTLvt;
Expand All @@ -47,15 +47,18 @@ public class MCInjectorImpl
static void process(
Path in, Path out,
Path accIn, Path accOut,
Path ctrIn, Path ctrOut,
Path ctrIn,
Path excIn, Path excOut,
Path prmIn, Path prmOut,
LVTNaming naming)
throws IOException
{
if (accIn != null)
Access.INSTANCE.load(accIn);
if (prmIn != null)
Parameters.INSTANCE.load(prmIn);
if (ctrIn != null)
Constructors.INSTANCE.load(ctrIn);
Parameters.INSTANCE.loadLegacy(ctrIn);
if (excIn != null)
Exceptions.INSTANCE.load(excIn);

Expand All @@ -69,8 +72,8 @@ static void process(

if (accOut != null)
Access.INSTANCE.dump(accOut);
if (ctrOut != null)
Constructors.INSTANCE.dump(ctrOut);
if (prmOut != null)
Parameters.INSTANCE.dump(prmOut);
if (excOut != null)
Exceptions.INSTANCE.dump(excOut);

Expand Down
27 changes: 23 additions & 4 deletions src/main/java/de/oceanlabs/mcp/mcinjector/adaptors/ApplyMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Set;
import java.util.logging.Level;

import de.oceanlabs.mcp.mcinjector.data.Parameters;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
Expand All @@ -21,12 +22,12 @@

import de.oceanlabs.mcp.mcinjector.MCInjector;
import de.oceanlabs.mcp.mcinjector.MCInjectorImpl;
import de.oceanlabs.mcp.mcinjector.data.Constructors;
import de.oceanlabs.mcp.mcinjector.data.Exceptions;

public class ApplyMap extends ClassVisitor
{
String className;
boolean isEnum;
MCInjectorImpl injector;

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

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

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

MCInjector.LOG.fine(" Generating map:");
String nameFormat = "p_" + name + "_%d_";
String nameFormat = null;
if (name.matches("func_\\d+_.+")) // A srg name method params are just p_MethodID_ParamIndex_
nameFormat = "p_" + name.substring(5, name.indexOf('_', 5)) + "_%s_";
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
nameFormat = "p_i" + Constructors.INSTANCE.getID(className, desc, types.size() > 1) + "_%s_";
else if(!isSynthetic(mn))
nameFormat = "p_" + Parameters.INSTANCE.getName(className, name, desc, types.size() > params.size(), isStatic) + "_%s_"; //assign new name only if there are names remaining
else nameFormat = "p_%s_"; //don't really care about synthetics

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

Collections.sort(mn.localVariables, (o1, o2) -> o1.index < o2.index ? -1 : (o1.index == o2.index ? 0 : 1));
}

private boolean isSynthetic(MethodNode mn){
if ((mn.access & Opcodes.ACC_SYNTHETIC) != 0) return true;

//check for special case pursuant to JLS 13.1.7
//which specifies that these are the one and only proper methods that may be generated and not be marked synthetic
if (isEnum && (mn.access & Opcodes.ACC_STATIC) != 0) {
if ("valueOf".equals(mn.name) && mn.desc.equals("(Ljava/lang/String;)L" + className + ";"))
return true;
if("values".equals(mn.name) && mn.desc.equals("()[L" + className + ";"))
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.oceanlabs.mcp.mcinjector.data;

import de.oceanlabs.mcp.mcinjector.MCInjector;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Expand All @@ -10,9 +12,7 @@
import java.util.Map;
import java.util.stream.Collectors;

import de.oceanlabs.mcp.mcinjector.MCInjector;

public enum Constructors
public enum Parameters
{
INSTANCE;

Expand All @@ -26,7 +26,7 @@ public boolean load(Path file)
this.fromID.clear();
try
{
MCInjector.LOG.fine("Loading Constructors from: " + file);
MCInjector.LOG.fine("Loading Parameters from: " + file);
Files.readAllLines(file).forEach(line ->
{
line = line.trim();
Expand All @@ -35,19 +35,44 @@ public boolean load(Path file)

String[] parts = line.split(" " );
int id = Integer.parseInt(parts[0]);
MCInjector.LOG.fine(" Constructor ID loaded " + id + " " + parts[0] + " " + parts[1]);
this.setID(parts[1], parts[2], id);
MCInjector.LOG.fine(" Method parameter ID loaded " + id + " " + parts[0] + " " + parts[1] + " " + parts[3]);
this.setName(parts[1], parts[2], parts[3], id);
});
}
catch (IOException e)
{
e.printStackTrace();
MCInjector.LOG.warning("Could not load Constructors list: " + e.toString());
MCInjector.LOG.warning("Could not load Parameters list: " + e.toString());
return false;
}
return true;
}

public boolean loadLegacy(Path file)
{
try {
MCInjector.LOG.fine("Loading Constructors from: " + file);
Files.readAllLines(file).forEach(line ->
{
line = line.trim();
if (line.isEmpty() || line.startsWith("#"))
return;

String[] parts = line.split(" " );
int id = Integer.parseInt(parts[0]);
MCInjector.LOG.fine(" Legacy Constructor ID loaded " + id + " " + parts[0] + " " + parts[1]);
this.setName(parts[1], "<init>", parts[2], id);
});
return true;
}
catch (IOException e)
{
e.printStackTrace();
MCInjector.LOG.warning("Could not import Constructors list: " + e.toString());
return false;
}
}

public boolean dump(Path file)
{
try
Expand All @@ -61,31 +86,32 @@ public boolean dump(Path file)
catch (IOException e)
{
e.printStackTrace();
MCInjector.LOG.warning("Could not dump Constructors list: " + e.toString());
MCInjector.LOG.warning("Could not dump Parameters list: " + e.toString());
return false;
}
return true;
}

public void setID(String cls, String desc, int id)
public void setName(String cls, String method, String desc, int id)
{
if (id < 0)
throw new IllegalArgumentException("ID must be positive: " + id);
this.maxID = Math.max(this.maxID, id);
this.fromDesc.put(cls + " " + desc, id);
this.fromID .put(id, cls + " " + desc);
this.fromDesc.put(cls + " " + method + " " + desc, id);
this.fromID .put(id, cls + " " + method + " " + desc);
}

public int getID(String cls, String desc, boolean generate)
public String getName(String cls, String method, String desc, boolean generate, boolean isStatic)
{
Integer id = this.fromDesc.get(cls + " " + desc);
Integer id = this.fromDesc.get(cls + " " + method + " " + desc);
if (id == null)
{
if (!generate)
return -1;
id = ++maxID;
this.setID(cls, desc, id);
return method; //if we are not generating new names we will return the old parameter format, _p_funcname_x_
int newId = ++maxID;
this.setName(cls, method, desc, newId);
return Integer.toString(newId);
}
return id;
return Integer.toString(id);
}
}

0 comments on commit 3008489

Please sign in to comment.