Skip to content

Commit

Permalink
Mapping writers done, but untested
Browse files Browse the repository at this point in the history
Add some ignores to avoid triggering unnecessary CI
Non-static methods' params in tsrgv2 can now be correctly applied when renaming lvt
Delegate SysOut to Log4J when FernFlower is running
Update Spigot FernFlower. It can read all libs successfully now
Add a few useful methods in namespaced mappings
Now tsrgv1's version is correctly represented in the version field
  • Loading branch information
XiaoPangxie732 committed Jul 16, 2021
1 parent 906ea05 commit 283a19c
Show file tree
Hide file tree
Showing 19 changed files with 542 additions and 30 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ name: Java CI with Maven
on:
push:
branches: [ master ]
paths-ignore:
- README.md
- LICENSE
- .gitignore
- CODE_OF_CONDUCT.md
- src/main/resources
- src/test/resources
- decompiler

jobs:
build:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import cn.maxpixel.mcdecompiler.mapping.namespaced.NamespacedClassMapping;
import cn.maxpixel.mcdecompiler.mapping.namespaced.NamespacedMethodMapping;
import cn.maxpixel.mcdecompiler.mapping.tsrg.TsrgMethodMapping;
import cn.maxpixel.mcdecompiler.reader.AbstractMappingReader;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.*;
Expand Down Expand Up @@ -98,7 +99,12 @@ private void renameLVT() {
.filter(m -> m.getName(fromNamespace).equals(methodNode.name) &&
m.getUnmappedDescriptor().equals(methodNode.desc)).findAny();
IntArrayList regen = new IntArrayList();
methodNode.localVariables.forEach(lvn -> methodMapping.map(mm -> mm.getLocalVariableName(lvn.index, targetNamespace))
methodNode.localVariables.forEach(lvn ->
methodMapping.map(mm -> {
int index = lvn.index;
if(mm instanceof TsrgMethodMapping tmm && !tmm.isStatic) index++;
return mm.getLocalVariableName(index, targetNamespace);
})
.filter(name -> !name.isEmpty() && !name.equals("o"/* tsrg2 empty lvn placeholder */))
.ifPresentOrElse(name -> lvn.name = name, () -> regen.add(lvn.index)));
if(rvn) regenerateVariableNames(methodNode, regen);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public void decompile(Path source, Path target) {
PrintStream sysErr = System.err;
System.setErr(new PrintStream(new OutputStream() {
private static final Logger LOGGER = LogManager.getLogger("CFR");

@Override
public void write(int b) {
throw new UnsupportedOperationException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@

package cn.maxpixel.mcdecompiler.decompiler;

import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler;
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Path;
import java.util.Map;

Expand All @@ -41,18 +44,32 @@ public SourceType getSourceType() {
@Override
public void decompile(Path source, Path target) throws IOException {
checkArgs(source, target);
Map<String, Object> options = new Object2ObjectOpenHashMap<>();
options.put("log", "TRACE");
options.put("dgs", "1");
options.put("hdc", "0");
options.put("asc", "1");
options.put("udv", "0");
options.put("rsy", "1");
Map<String, Object> options = Map.of(
"log", "TRACE",
"dgs", "1",
"asc", "1",
"rsy", "1"
);
ConsoleDecompiler decompiler = new AccessibleConsoleDecompiler(target.toFile(), options, new PrintStreamLogger(System.out));
decompiler.addSource(source.toFile());
// List<String> libs = listLibs();
// ObjectList<String> libs = listLibs();
// for(int index = 0; index < libs.size(); index++) decompiler.addLibrary(new File(libs.get(index)));
PrintStream sysOut = System.out;
System.setOut(new PrintStream(new OutputStream() {
private static final Logger LOGGER = LogManager.getLogger("FernFlower");

@Override
public void write(int b) {
throw new UnsupportedOperationException();
}

@Override
public void write(byte[] b, int off, int len) {
LOGGER.debug(new String(b, off, len).stripTrailing());
}
}));
decompiler.decompileContext();
System.setOut(sysOut);
}

private static class AccessibleConsoleDecompiler extends ConsoleDecompiler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@

import cn.maxpixel.mcdecompiler.util.Utils;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectList;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;

// Do not extend AbstractLibRecommendedDecompiler because this decompiler cannot read some of the libraries successfully
// TODO: Make SpigotFernFlowerDecompiler read all libraries successfully
public class SpigotFernFlowerDecompiler/* extends AbstractLibRecommendedDecompiler */implements IExternalResourcesDecompiler {
public class SpigotFernFlowerDecompiler extends AbstractLibRecommendedDecompiler implements IExternalResourcesDecompiler {
private Path decompilerJarPath;
SpigotFernFlowerDecompiler() {}

Expand All @@ -42,9 +41,9 @@ public SourceType getSourceType() {
public void decompile(Path source, Path target) throws IOException {
checkArgs(source, target);
ObjectArrayList<String> args = new ObjectArrayList<>();
args.addAll(Arrays.asList("java", "-jar", decompilerJarPath.toString(), "-log=TRACE", "-dgs=1", "-hdc=0", "-asc=1", "-udv=0", "-rsy=1", "-aoa=1"));
// List<String> libs = listLibs();
// for(int i = 0; i < 26; i++) args.add("-e=\"" + libs.get(i) + "\"");
args.addAll(Arrays.asList("java", "-jar", decompilerJarPath.toString(), "-log=TRACE", "-dgs=1", "-asc=1", "-udv=0", "-ump=0", "-rsy=1", "-aoa=1"));
ObjectList<String> libs = listLibs();
for(int i = 0; i < 26; i++) args.add("-e=\"" + libs.get(i) + "\"");
args.add(source.toString());
args.add(target.toString());
Process process = Runtime.getRuntime().exec(args.toArray(new String[0]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import cn.maxpixel.mcdecompiler.mapping.AbstractMapping;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import it.unimi.dsi.fastutil.objects.ObjectSets;

import java.util.Map;

Expand Down Expand Up @@ -58,6 +60,10 @@ public NamespacedMapping(String[] namespaces, String[] names, int nameStart) {
}
public NamespacedMapping() {}

public ObjectSet<String> getNamespaces() {
return ObjectSets.unmodifiable(names.keySet());
}

public void setName(String namespace, String name) {
names.put(namespace, name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import cn.maxpixel.mcdecompiler.mapping.components.Descriptor;
import cn.maxpixel.mcdecompiler.mapping.components.Owned;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.ints.IntSets;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
Expand Down Expand Up @@ -95,6 +97,14 @@ public void setLocalVariableName(int index, String[] namespaces, String[] names,
}
}

public IntSet getLocalVariableIndexes() {
return IntSets.unmodifiable(lvt.keySet());
}

public Object2ObjectMap<String, String> getLocalVariableNames(int index) {
return Object2ObjectMaps.unmodifiable(lvt.get(index));
}

@Override
public String getUnmappedDescriptor() {
return unmappedDescriptor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public CsrgMappingReader(String path) throws FileNotFoundException {
}

private final CsrgMappingProcessor PROCESSOR = new CsrgMappingProcessor();

@Override
public CsrgMappingProcessor getProcessor() {
return PROCESSOR;
Expand Down Expand Up @@ -136,7 +137,7 @@ public PairedMapping processPackage(String line) {
}

private PairedMapping processPackage(String[] line) {
return new PairedMapping(line[0].substring(0, line[0].length() - 1), line[1]);
return new PairedMapping(line[0].substring(0, line[0].length() - 1), line[1].substring(0, line[1].length() - 1));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ private static BufferedReader downloadMapping(String version, Info.SideType type
}

private final ProguardMappingProcessor PROCESSOR = new ProguardMappingProcessor();

@Override
public ProguardMappingProcessor getProcessor() {
return PROCESSOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public SrgMappingReader(String path) throws FileNotFoundException {
}

private final SrgMappingProcessor PROCESSOR = new SrgMappingProcessor();

@Override
public SrgMappingProcessor getProcessor() {
return PROCESSOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,14 @@ public TinyMappingReader(String path) throws FileNotFoundException, NullPointerE

private final TinyV1MappingProcessor V1_PROCESSOR = new TinyV1MappingProcessor();
private final TinyV2MappingProcessor V2_PROCESSOR = new TinyV2MappingProcessor();

@Override
public NamespacedMappingProcessor getProcessor() {
if(version == 2) return V2_PROCESSOR;
else if(version == 1) return V1_PROCESSOR;
else throw new IllegalArgumentException("Unknown tiny mapping version");
return switch(version) {
case 1 -> V1_PROCESSOR;
case 2 -> V2_PROCESSOR;
default -> throw new UnsupportedOperationException("Unknown tiny mapping version");
};
}

private class TinyV1MappingProcessor implements NamespacedMappingProcessor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import java.util.concurrent.atomic.AtomicReference;

public class TsrgMappingReader extends AbstractMappingReader {
public final int version = lines.get(0).startsWith("tsrg2") ? 2 : -1;
public final int version = lines.get(0).startsWith("tsrg2") ? 2 : 1;

public TsrgMappingReader(BufferedReader reader) {
super(reader);
Expand All @@ -57,14 +57,19 @@ public TsrgMappingReader(String path) throws FileNotFoundException, NullPointerE
super(path);
}

private final TsrgMappingProcessor PROCESSOR = new TsrgMappingProcessor();
private final TsrgV1MappingProcessor V1_PROCESSOR = new TsrgV1MappingProcessor();
private final TsrgV2MappingProcessor V2_PROCESSOR = new TsrgV2MappingProcessor();

@Override
public MappingProcessor getProcessor() {
return version == 2 ? V2_PROCESSOR : PROCESSOR;
return switch(version) {
case 1 -> V1_PROCESSOR;
case 2 -> V2_PROCESSOR;
default -> throw new UnsupportedOperationException("Unknown tsrg mapping version");
};
}

private class TsrgMappingProcessor implements PairedMappingProcessor, PackageMappingProcessor {
private class TsrgV1MappingProcessor implements PairedMappingProcessor, PackageMappingProcessor {
private final ObjectArrayList<PairedMapping> packages = new ObjectArrayList<>();
private final ObjectArrayList<PairedClassMapping> mappings = new ObjectArrayList<>(5000);
@Override
Expand Down Expand Up @@ -121,7 +126,7 @@ public ObjectList<PairedMapping> getPackages() {
@Override
public PairedMapping processPackage(String line) {
String[] strings = line.split(" ");
return new PairedMapping(strings[0].substring(0, strings[0].length() - 1), strings[1]);
return new PairedMapping(strings[0].substring(0, strings[0].length() - 1), strings[1].substring(0, strings[1].length() - 1));
}
}

Expand Down Expand Up @@ -215,7 +220,9 @@ public ObjectList<NamespacedMapping> getPackages() {
@Override
public NamespacedMapping processPackage(String line) {
String[] split = line.split(" ");
split[0] = split[0].substring(0, split[0].length() - 1);
for(int i = 0; i < split.length; i++) {
split[i] = split[i].substring(0, split[i].length() - 1);
}
return new NamespacedMapping(namespaces, split);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public final void writeNamespacedPackage(NamespacedMapping pkg) {
synchronized(buf) {
buf.add(((PackageMappingGenerator) getGenerator()).generatePackage(pkg));
}
} else throw new IllegalArgumentException("Use writePairedPackage(s)");
} else throw new UnsupportedOperationException("Use writePairedPackage(s)");
}

/**
Expand Down Expand Up @@ -182,7 +182,7 @@ public final void writePairedMapping(PairedClassMapping pcm) {
} finally {
if(needLock) lock.unlock();
}
} else throw new IllegalArgumentException("Use writeNamespacedMapping(s)");
} else throw new UnsupportedOperationException("Use writeNamespacedMapping(s)");
}

public final void writePairedMapping(NamespacedClassMapping ncm, String unmapped, String mapped) {
Expand Down Expand Up @@ -233,7 +233,7 @@ public final void writeNamespacedMapping(NamespacedClassMapping ncm) {
} finally {
if(needLock) lock.unlock();
}
} else throw new IllegalArgumentException("Use writePairedMapping(s)");
} else throw new UnsupportedOperationException("Use writePairedMapping(s)");
}

public final void writeNamespacedMapping(PairedClassMapping pcm, String unmapped, String mapped) {
Expand Down Expand Up @@ -274,20 +274,26 @@ public final void writeNamespacedMappings(Collection<PairedClassMapping> mapping

public final void writeTo(OutputStream os) throws IOException {
synchronized(buf) {
String header = getHeader();
if(!header.isEmpty()) os.write(header.getBytes(StandardCharsets.UTF_8));
os.write(String.join("\n", buf).getBytes(StandardCharsets.UTF_8));
buf.clear();
}
}

public final void writeTo(Writer writer) throws IOException {
synchronized(buf) {
String header = getHeader();
if(!header.isEmpty()) writer.write(header);
writer.write(String.join("\n", buf));
buf.clear();
}
}

public final void writeTo(WritableByteChannel os) throws IOException {
synchronized(buf) {
String header = getHeader();
if(!header.isEmpty()) os.write(ByteBuffer.wrap(header.concat("\n").getBytes(StandardCharsets.UTF_8)));
os.write(ByteBuffer.wrap(String.join("\n", buf).getBytes(StandardCharsets.UTF_8)));
buf.clear();
}
Expand All @@ -297,6 +303,10 @@ public final void writeTo(WritableByteChannel os) throws IOException {

protected abstract boolean needLock();

protected String getHeader() {
return "";
}

public interface MappingGenerator {
default boolean isPaired() {
return this instanceof PairedMappingGenerator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public CsrgMappingWriter(MappingRemapper remapper) {
}

private final CsrgMappingGenerator GENERATOR = new CsrgMappingGenerator();

@Override
protected CsrgMappingGenerator getGenerator() {
return GENERATOR;
Expand Down Expand Up @@ -71,7 +72,7 @@ public String generateField(PairedFieldMapping mapping) {
@Override
public String generatePackage(AbstractMapping mapping) {
if(mapping instanceof PairedMapping paired && paired.getClass() == PairedMapping.class) {
return paired.getUnmappedName() + '/' + ' ' + paired.getMappedName();
return paired.getUnmappedName() + '/' + ' ' + paired.getMappedName() + '/';
} else throw new UnsupportedOperationException();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public ProguardMappingWriter(MappingRemapper remapper) {
}

private final ProguardMappingGenerator GENERATOR = new ProguardMappingGenerator();

@Override
protected ProguardMappingGenerator getGenerator() {
return GENERATOR;
Expand Down
Loading

0 comments on commit 283a19c

Please sign in to comment.