Skip to content

Commit ae4e715

Browse files
committed
Dump parameter names for abstract methods to a text file that FernFlower can then read as abstract methods can not have parameter names at the bytecode level.
1 parent 8cac0b9 commit ae4e715

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33
import java.io.ByteArrayOutputStream;
44
import java.io.IOException;
55
import java.lang.reflect.Field;
6+
import java.nio.charset.StandardCharsets;
67
import java.nio.file.Files;
78
import java.nio.file.Path;
89
import java.nio.file.StandardOpenOption;
10+
import java.util.HashMap;
11+
import java.util.HashSet;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.Set;
915
import java.util.logging.Level;
16+
import java.util.stream.Collectors;
1017
import java.util.zip.ZipEntry;
1118
import java.util.zip.ZipInputStream;
1219
import java.util.zip.ZipOutputStream;
@@ -34,6 +41,7 @@
3441
public class MCInjectorImpl
3542
{
3643
public LVTNaming naming = LVTNaming.STRIP;
44+
private Map<String, List<String>> abstractParameters = new HashMap<>();
3745

3846
static void process(
3947
Path in, Path out,
@@ -72,6 +80,7 @@ private MCInjectorImpl(){}
7280

7381
private void processJar(Path inFile, Path outFile) throws IOException
7482
{
83+
Set<String> entries = new HashSet<>();
7584
try (ZipInputStream inJar = new ZipInputStream(Files.newInputStream(inFile)))
7685
{
7786
try (ZipOutputStream outJar = new ZipOutputStream(outFile == null ? new ByteArrayOutputStream() : Files.newOutputStream(outFile, StandardOpenOption.CREATE)))
@@ -117,6 +126,19 @@ private void processJar(Path inFile, Path outFile) throws IOException
117126
ZipEntry newEntry = new ZipEntry(entryName);
118127
outJar.putNextEntry(newEntry);
119128
outJar.write(entryData);
129+
entries.add(entryName);
130+
}
131+
132+
if (!abstractParameters.isEmpty() && !entries.contains("fernflower_abstract_parameter_names.txt"))
133+
{
134+
outJar.putNextEntry(new ZipEntry("fernflower_abstract_parameter_names.txt"));
135+
for (String key : abstractParameters.keySet().stream().sorted().collect(Collectors.toList()))
136+
{
137+
outJar.write(key.getBytes(StandardCharsets.UTF_8));//class method desc
138+
outJar.write(' ');
139+
outJar.write(abstractParameters.get(key).stream().collect(Collectors.joining(" ")).getBytes(StandardCharsets.UTF_8));
140+
outJar.write('\n');
141+
}
120142
}
121143
}
122144
}
@@ -133,7 +155,7 @@ public byte[] processClass(byte[] cls, boolean readOnly)
133155
}
134156
else
135157
{
136-
ca = new ApplyMap(ca);
158+
ca = new ApplyMap(this, ca);
137159

138160
switch (naming)
139161
{
@@ -220,4 +242,9 @@ public static ClassNode getClassNode(ClassVisitor cv)
220242

221243
}
222244
}
245+
246+
public void storeAbstractParameters(String className, String name, String desc, List<String> params)
247+
{
248+
abstractParameters.put(className + ' ' + name + ' ' + desc, params);
249+
}
223250
}

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
public class ApplyMap extends ClassVisitor
2828
{
2929
String className;
30+
MCInjectorImpl injector;
3031

31-
public ApplyMap(ClassVisitor cn)
32+
public ApplyMap(MCInjectorImpl injector, ClassVisitor cn)
3233
{
3334
super(Opcodes.ASM6, cn);
35+
this.injector = injector;
3436
}
3537

3638
@Override
@@ -52,10 +54,10 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
5254
exceptions = processExceptions(className, name, desc, exceptions);
5355

5456
// abstract and native methods don't have a Code attribute
55-
if ((access & Opcodes.ACC_ABSTRACT) != 0 || (access & Opcodes.ACC_NATIVE) != 0)
57+
/*if ((access & Opcodes.ACC_ABSTRACT) != 0 || (access & Opcodes.ACC_NATIVE) != 0)
5658
{
5759
return super.visitMethod(access, name, desc, signature, exceptions);
58-
}
60+
}*/
5961

6062
return new MethodVisitor(api, cv.visitMethod(access, name, desc, signature, exceptions))
6163
{
@@ -121,6 +123,15 @@ else if (name.equals("<init>")) // Every constructor is given a unique ID, try t
121123
y += types.get(x).getSize();
122124
}
123125

126+
if ((mn.access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != 0) //Abstract and native methods dont have code so we need to store the names elseware.
127+
{
128+
if ((mn.access & Opcodes.ACC_STATIC) == 0)
129+
params.remove(0); //remove 'this'
130+
if (params.size() > 0)
131+
injector.storeAbstractParameters(className, name, desc, params);
132+
return;
133+
}
134+
124135
MCInjector.LOG.fine(" Applying map:");
125136
if (params.size() != types.size())
126137
{

0 commit comments

Comments
 (0)