Add mixins that target the class as a comment. (#168)

* Add mixins that target the class as a comment.

* some final fixes and tweaks

* Remove debug log

* Fix inner class mixins
This commit is contained in:
modmuss50
2020-01-01 19:12:31 +00:00
committed by GitHub
parent 705754de80
commit fb3c2c86cb
4 changed files with 274 additions and 3 deletions

View File

@@ -26,6 +26,8 @@ package net.fabricmc.loom.task.fernflower;
import static java.text.MessageFormat.format;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -33,6 +35,7 @@ import java.util.Map;
import java.util.Stack;
import java.util.function.Supplier;
import org.apache.commons.io.FileUtils;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.api.logging.LogLevel;
@@ -47,6 +50,9 @@ import net.fabricmc.loom.task.AbstractDecompileTask;
import net.fabricmc.loom.task.ForkingJavaExecTask;
import net.fabricmc.loom.util.ConsumingOutputStream;
import net.fabricmc.loom.util.OperatingSystem;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.MixinTargetScanner;
import net.fabricmc.loom.util.RemappedConfigurationEntry;
/**
* Created by covers1624 on 9/02/19.
@@ -61,6 +67,16 @@ public class FernFlowerTask extends AbstractDecompileTask implements ForkingJava
throw new UnsupportedOperationException("FernFlowerTask requires a 64bit JVM to run due to the memory requirements");
}
MixinTargetScanner mixinTargetScanner = new MixinTargetScanner(getProject());
for (RemappedConfigurationEntry modCompileEntry : Constants.MOD_COMPILE_ENTRIES) {
mixinTargetScanner.scan(getProject().getConfigurations().getByName(modCompileEntry.getRemappedConfiguration()));
}
String mixinTargetJson = mixinTargetScanner.getClassMixinsJson();
File mixinTargetFile = new File(getExtension().getProjectBuildCache(), "mixin_targets.json");
FileUtils.writeStringToFile(mixinTargetFile, mixinTargetJson, StandardCharsets.UTF_8);
Map<String, Object> options = new HashMap<>();
options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1");
options.put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1");
@@ -80,6 +96,7 @@ public class FernFlowerTask extends AbstractDecompileTask implements ForkingJava
args.add("-t=" + getNumThreads());
args.add("-m=" + getExtension().getMappingsProvider().tinyMappings.getAbsolutePath());
args.add("-j=" + mixinTargetFile.getAbsolutePath());
//TODO, Decompiler breaks on jemalloc, J9 module-info.class?
getLibraries().forEach(f -> args.add("-e=" + f.getAbsolutePath()));

View File

@@ -52,6 +52,7 @@ public class ForkedFFExecutor {
File output = null;
File lineMap = null;
File mappings = null;
File mixins = null;
List<File> libraries = new ArrayList<>();
int numThreads = 0;
@@ -91,6 +92,12 @@ public class ForkedFFExecutor {
}
mappings = new File(arg.substring(3));
} else if (arg.startsWith("-j=")) {
if (mixins != null) {
throw new RuntimeException("Unable to use more than one mixin file.");
}
mixins = new File(arg.substring(3));
} else if (arg.startsWith("-t=")) {
numThreads = Integer.parseInt(arg.substring(3));
} else {
@@ -107,7 +114,7 @@ public class ForkedFFExecutor {
Objects.requireNonNull(output, "Output not set.");
Objects.requireNonNull(mappings, "Mappings not set.");
options.put(IFabricJavadocProvider.PROPERTY_NAME, new TinyJavadocProvider(mappings));
options.put(IFabricJavadocProvider.PROPERTY_NAME, new TinyJavadocProvider(mappings, mixins));
runFF(options, libraries, input, output, lineMap);
}

View File

@@ -27,12 +27,14 @@ package net.fabricmc.loom.task.fernflower;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructField;
import org.jetbrains.java.decompiler.struct.StructMethod;
@@ -45,15 +47,18 @@ import net.fabricmc.mapping.tree.ParameterDef;
import net.fabricmc.mapping.tree.TinyMappingFactory;
import net.fabricmc.mapping.tree.TinyTree;
import net.fabricmc.mappings.EntryTriple;
import net.fabricmc.loom.util.MixinTargetScanner;
public class TinyJavadocProvider implements IFabricJavadocProvider {
private final Map<String, ClassDef> classes = new HashMap<>();
private final Map<EntryTriple, FieldDef> fields = new HashMap<>();
private final Map<EntryTriple, MethodDef> methods = new HashMap<>();
private final Map<String, List<MixinTargetScanner.MixinTargetInfo>> mixins;
private final String namespace = "named";
public TinyJavadocProvider(File tinyFile) {
public TinyJavadocProvider(File tinyFile, File mixinTargetFile) {
final TinyTree mappings = readMappings(tinyFile);
for (ClassDef classDef : mappings.getClasses()) {
@@ -68,12 +73,38 @@ public class TinyJavadocProvider implements IFabricJavadocProvider {
methods.put(new EntryTriple(className, methodDef.getName(namespace), methodDef.getDescriptor(namespace)), methodDef);
}
}
try {
mixins = MixinTargetScanner.fromJson(FileUtils.readFileToString(mixinTargetFile, StandardCharsets.UTF_8));
} catch (IOException e) {
throw new RuntimeException("Failed to read mixin target file", e);
}
}
@Override
public String getClassDoc(StructClass structClass) {
StringBuilder comment = new StringBuilder();
ClassDef classDef = classes.get(structClass.qualifiedName);
return classDef != null ? classDef.getComment() : null;
if (classDef != null && classDef.getComment() != null) {
comment.append(classDef.getComment());
}
if (mixins.containsKey(structClass.qualifiedName)) {
List<MixinTargetScanner.MixinTargetInfo> mixinList = mixins.get(structClass.qualifiedName);
if (classDef != null && classDef.getComment() != null) {
comment.append("\n");
}
comment.append("Mixins:");
for (MixinTargetScanner.MixinTargetInfo info : mixinList) {
comment.append(String.format("\n\t%s - {@link %s}", info.getModid(), info.getMixinClass().replaceAll("\\$", ".")));
}
}
return comment.length() == 0 ? null : comment.toString();
}
@Override