Reformat to use Fabric API's checkstyle (#137)

* Reformat to use Fabric API's checkstyle

* Fix

* Fix

* Update

* Travis and fixes

* possible fix for checkstyle?

* Helps if i push the checkstyle.xml file...

* Log checkstyle issues to console - used by travis

* Fix some more issues

* opps
This commit is contained in:
modmuss50
2019-11-02 20:23:27 +00:00
committed by GitHub
parent 2bd339241f
commit f85daec559
59 changed files with 2129 additions and 1655 deletions

View File

@@ -24,29 +24,52 @@
package net.fabricmc.loom.task;
import java.io.File;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import java.io.File;
public abstract class AbstractDecompileTask extends AbstractLoomTask {
private Object input;
private Object output;
private Object lineMapFile;
private Object libraries;
private Object input;
private Object output;
private Object lineMapFile;
private Object libraries;
//@formatter:off
@InputFile
public File getInput() { return getProject().file(input); }
@OutputFile public File getOutput() { return getProject().file(output); }
@OutputFile public File getLineMapFile() { return getProject().file(lineMapFile); }
@InputFiles public FileCollection getLibraries() { return getProject().files(libraries); }
public void setInput(Object input) { this.input = input; }
public void setOutput(Object output) { this.output = output; }
public void setLineMapFile(Object lineMapFile) { this.lineMapFile = lineMapFile; }
public void setLibraries(Object libraries) { this.libraries = libraries; }
//@formatter:on
@InputFile
public File getInput() {
return getProject().file(input);
}
@OutputFile
public File getOutput() {
return getProject().file(output);
}
@OutputFile
public File getLineMapFile() {
return getProject().file(lineMapFile);
}
@InputFiles
public FileCollection getLibraries() {
return getProject().files(libraries);
}
public void setInput(Object input) {
this.input = input;
}
public void setOutput(Object output) {
this.output = output;
}
public void setLineMapFile(Object lineMapFile) {
this.lineMapFile = lineMapFile;
}
public void setLibraries(Object libraries) {
this.libraries = libraries;
}
}

View File

@@ -27,9 +27,7 @@ package net.fabricmc.loom.task;
import org.gradle.api.DefaultTask;
public abstract class AbstractLoomTask extends DefaultTask {
public AbstractLoomTask() {
setGroup("fabric");
}
}

View File

@@ -24,14 +24,6 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MappingsProvider;
import net.fabricmc.loom.util.MinecraftVersionInfo;
import net.fabricmc.loom.util.OperatingSystem;
import net.fabricmc.loom.util.RunConfig;
import org.gradle.api.Project;
import org.gradle.api.tasks.JavaExec;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -41,99 +33,113 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import org.gradle.api.Project;
import org.gradle.api.tasks.JavaExec;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MappingsProvider;
import net.fabricmc.loom.util.MinecraftVersionInfo;
import net.fabricmc.loom.util.RunConfig;
public abstract class AbstractRunTask extends JavaExec {
private final Function<Project, RunConfig> configProvider;
private RunConfig config;
private final Function<Project, RunConfig> configProvider;
private RunConfig config;
public AbstractRunTask(Function<Project, RunConfig> config) {
super();
setGroup("fabric");
this.configProvider = config;
}
public AbstractRunTask(Function<Project, RunConfig> config) {
super();
setGroup("fabric");
this.configProvider = config;
}
@Override
public void exec() {
if (config == null) {
config = configProvider.apply(getProject());
}
@Override
public void exec() {
if (config == null) {
config = configProvider.apply(getProject());
}
LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class);
MinecraftVersionInfo minecraftVersionInfo = extension.getMinecraftProvider().versionInfo;
MappingsProvider mappingsProvider = extension.getMappingsProvider();
LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class);
MinecraftVersionInfo minecraftVersionInfo = extension.getMinecraftProvider().versionInfo;
MappingsProvider mappingsProvider = extension.getMappingsProvider();
List<String> libs = new ArrayList<>();
for (File file : getProject().getConfigurations().getByName("runtimeClasspath").getFiles()) {
libs.add(file.getAbsolutePath());
}
for (Path file : extension.getUnmappedMods()) {
if (Files.isRegularFile(file)) {
libs.add(file.toFile().getAbsolutePath());
}
}
List<String> libs = new ArrayList<>();
classpath(libs);
List<String> argsSplit = new ArrayList<>();
String[] args = config.programArgs.split(" ");
int partPos = -1;
for (int i = 0; i < args.length; i++) {
if (partPos < 0) {
if (args[i].startsWith("\"")) {
if (args[i].endsWith("\"")) {
argsSplit.add(args[i].substring(1, args[i].length() - 1));
} else {
partPos = i;
}
} else {
argsSplit.add(args[i]);
}
} else if (args[i].endsWith("\"")) {
StringBuilder builder = new StringBuilder(args[partPos].substring(1));
for (int j = partPos + 1; j < i; j++) {
builder.append(" ").append(args[j]);
}
builder.append(" ").append(args[i], 0, args[i].length() - 1);
argsSplit.add(builder.toString());
partPos = -1;
}
}
for (File file : getProject().getConfigurations().getByName("runtimeClasspath").getFiles()) {
libs.add(file.getAbsolutePath());
}
args(argsSplit);
setWorkingDir(new File(getProject().getRootDir(), extension.runDir));
for (Path file : extension.getUnmappedMods()) {
if (Files.isRegularFile(file)) {
libs.add(file.toFile().getAbsolutePath());
}
}
super.exec();
}
classpath(libs);
List<String> argsSplit = new ArrayList<>();
String[] args = config.programArgs.split(" ");
int partPos = -1;
@Override
public void setWorkingDir(File dir) {
if (config == null) {
config = configProvider.apply(getProject());
}
for (int i = 0; i < args.length; i++) {
if (partPos < 0) {
if (args[i].startsWith("\"")) {
if (args[i].endsWith("\"")) {
argsSplit.add(args[i].substring(1, args[i].length() - 1));
} else {
partPos = i;
}
} else {
argsSplit.add(args[i]);
}
} else if (args[i].endsWith("\"")) {
StringBuilder builder = new StringBuilder(args[partPos].substring(1));
if(!dir.exists()){
dir.mkdirs();
}
super.setWorkingDir(dir);
}
for (int j = partPos + 1; j < i; j++) {
builder.append(" ").append(args[j]);
}
@Override
public String getMain() {
if (config == null) {
config = configProvider.apply(getProject());
}
builder.append(" ").append(args[i], 0, args[i].length() - 1);
argsSplit.add(builder.toString());
partPos = -1;
}
}
return config.mainClass;
}
args(argsSplit);
setWorkingDir(new File(getProject().getRootDir(), extension.runDir));
@Override
public List<String> getJvmArgs() {
if (config == null) {
config = configProvider.apply(getProject());
}
LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class);
List<String> superArgs = super.getJvmArgs();
List<String> args = new ArrayList<>(superArgs != null ? superArgs : Collections.emptyList());
args.addAll(Arrays.asList(config.vmArgs.split(" ")));
return args;
}
super.exec();
}
@Override
public void setWorkingDir(File dir) {
if (config == null) {
config = configProvider.apply(getProject());
}
if (!dir.exists()) {
dir.mkdirs();
}
super.setWorkingDir(dir);
}
@Override
public String getMain() {
if (config == null) {
config = configProvider.apply(getProject());
}
return config.mainClass;
}
@Override
public List<String> getJvmArgs() {
if (config == null) {
config = configProvider.apply(getProject());
}
LoomGradleExtension extension = this.getProject().getExtensions().getByType(LoomGradleExtension.class);
List<String> superArgs = super.getJvmArgs();
List<String> args = new ArrayList<>(superArgs != null ? superArgs : Collections.emptyList());
args.addAll(Arrays.asList(config.vmArgs.split(" ")));
return args;
}
}

View File

@@ -24,26 +24,28 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.LoomGradleExtension;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import java.io.IOException;
import net.fabricmc.loom.LoomGradleExtension;
public class CleanLoomBinaries extends AbstractLoomTask {
@TaskAction
public void run() {
Project project = this.getProject();
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
extension.getMinecraftProvider().getMergedJar().delete();
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
extension.getMinecraftMappedProvider().getMappedJar().delete();
try {
FileUtils.deleteDirectory(extension.getNativesDirectory());
FileUtils.deleteDirectory(extension.getNativesJarStore());
} catch (IOException e) {
e.printStackTrace();
}
}
@TaskAction
public void run() {
Project project = this.getProject();
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
extension.getMinecraftProvider().getMergedJar().delete();
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
extension.getMinecraftMappedProvider().getMappedJar().delete();
try {
FileUtils.deleteDirectory(extension.getNativesDirectory());
FileUtils.deleteDirectory(extension.getNativesJarStore());
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -24,27 +24,29 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.DeletingFileVisitor;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import java.io.IOException;
import java.nio.file.Files;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.DeletingFileVisitor;
public class CleanLoomMappings extends AbstractLoomTask {
@TaskAction
public void run() {
Project project = this.getProject();
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
extension.getMappingsProvider().MAPPINGS_TINY.delete();
extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete();
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
extension.getMinecraftMappedProvider().getMappedJar().delete();
try {
Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@TaskAction
public void run() {
Project project = this.getProject();
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
extension.getMappingsProvider().MAPPINGS_TINY.delete();
extension.getMappingsProvider().MAPPINGS_TINY_BASE.delete();
extension.getMinecraftMappedProvider().getIntermediaryJar().delete();
extension.getMinecraftMappedProvider().getMappedJar().delete();
try {
Files.walkFileTree(extension.getRootProjectBuildCache().toPath(), new DeletingFileVisitor());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -24,13 +24,14 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MinecraftAssetsProvider;
import net.fabricmc.loom.providers.MinecraftNativesProvider;
import java.io.IOException;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import java.io.IOException;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MinecraftAssetsProvider;
import net.fabricmc.loom.providers.MinecraftNativesProvider;
public class DownloadAssetsTask extends AbstractLoomTask {
@TaskAction

View File

@@ -36,18 +36,18 @@ import org.gradle.process.JavaExecSpec;
* Simple trait like interface for a Task that wishes to execute a java process
* with the classpath of the gradle plugin plus groovy.
*
* Created by covers1624 on 11/02/19.
* <p>Created by covers1624 on 11/02/19.
*/
public interface ForkingJavaExecTask extends Task {
default ExecResult javaexec(Action<? super JavaExecSpec> action) {
ConfigurationContainer configurations = getProject().getBuildscript().getConfigurations();
DependencyHandler handler = getProject().getDependencies();
FileCollection classpath = configurations.getByName("classpath")//
.plus(configurations.detachedConfiguration(handler.localGroovy()));
default ExecResult javaexec(Action<? super JavaExecSpec> action) {
ConfigurationContainer configurations = getProject().getBuildscript().getConfigurations();
DependencyHandler handler = getProject().getDependencies();
FileCollection classpath = configurations.getByName("classpath")//
.plus(configurations.detachedConfiguration(handler.localGroovy()));
return getProject().javaexec(spec -> {
spec.classpath(classpath);
action.execute(spec);
});
}
return getProject().javaexec(spec -> {
spec.classpath(classpath);
action.execute(spec);
});
}
}

View File

@@ -24,33 +24,37 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.RunConfig;
import org.apache.commons.io.FileUtils;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.RunConfig;
public class GenEclipseRunsTask extends AbstractLoomTask {
@TaskAction
public void genRuns() throws IOException {
File clientRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_client.launch");
File serverRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_server.launch");
@TaskAction
public void genRuns() throws IOException {
File clientRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_client.launch");
File serverRunConfigs = new File(getProject().getRootDir(), getProject().getName() + "_server.launch");
String clientRunConfig = RunConfig.clientRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml");
String serverRunConfig = RunConfig.serverRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml");
String clientRunConfig = RunConfig.clientRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml");
String serverRunConfig = RunConfig.serverRunConfig(getProject()).fromDummy("eclipse_run_config_template.xml");
if (!clientRunConfigs.exists()) {
FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8);
}
if(!clientRunConfigs.exists())
FileUtils.writeStringToFile(clientRunConfigs, clientRunConfig, StandardCharsets.UTF_8);
if(!serverRunConfigs.exists())
FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8);
if (!serverRunConfigs.exists()) {
FileUtils.writeStringToFile(serverRunConfigs, serverRunConfig, StandardCharsets.UTF_8);
}
File runDir = new File(getProject().getRootDir(), this.getProject().getExtensions().getByType(LoomGradleExtension.class).runDir);
if(!runDir.exists())
runDir.mkdirs();
}
File runDir = new File(getProject().getRootDir(), this.getProject().getExtensions().getByType(LoomGradleExtension.class).runDir);
if (!runDir.exists()) {
runDir.mkdirs();
}
}
}

View File

@@ -24,15 +24,8 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.AbstractPlugin;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.RunConfig;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -43,18 +36,28 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.AbstractPlugin;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.RunConfig;
public class GenIdeaProjectTask extends AbstractLoomTask {
@TaskAction
public void genIdeaRuns() throws IOException, ParserConfigurationException, SAXException, TransformerException {
Project project = this.getProject();
//Only generate the idea runs on the root project
if(!AbstractPlugin.isRootProject(project)){
if (!AbstractPlugin.isRootProject(project)) {
return;
}
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
project.getLogger().lifecycle(":Building idea workspace");
@@ -65,8 +68,10 @@ public class GenIdeaProjectTask extends AbstractLoomTask {
NodeList list = doc.getElementsByTagName("component");
Element runManager = null;
for (int i = 0; i < list.getLength(); i++) {
Element element = (Element) list.item(i);
if (element.getAttribute("name").equals("RunManager")) {
runManager = element;
break;
@@ -89,6 +94,7 @@ public class GenIdeaProjectTask extends AbstractLoomTask {
transformer.transform(source, result);
File runDir = new File(getProject().getRootDir(), extension.runDir);
if (!runDir.exists()) {
runDir.mkdirs();
}

View File

@@ -24,81 +24,85 @@
package net.fabricmc.loom.task;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.RunConfig;
import org.apache.commons.io.FileUtils;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.io.FileUtils;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.RunConfig;
//Recommended vscode plugins:
// https://marketplace.visualstudio.com/items?itemName=redhat.java
// https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-debug
// https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack
public class GenVsCodeProjectTask extends AbstractLoomTask {
@TaskAction
public void genRuns() {
LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class);
File projectDir = getProject().file(".vscode");
@TaskAction
public void genRuns() {
LoomGradleExtension extension = getProject().getExtensions().getByType(LoomGradleExtension.class);
File projectDir = getProject().file(".vscode");
if (!projectDir.exists()) {
projectDir.mkdir();
}
File launchJson = new File(projectDir, "launch.json");
if (launchJson.exists()) {
launchJson.delete();
}
if (!projectDir.exists()) {
projectDir.mkdir();
}
VsCodeLaunch launch = new VsCodeLaunch();
launch.add(RunConfig.clientRunConfig(getProject()));
launch.add(RunConfig.serverRunConfig(getProject()));
File launchJson = new File(projectDir, "launch.json");
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(launch);
if (launchJson.exists()) {
launchJson.delete();
}
try {
FileUtils.writeStringToFile(launchJson, json, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException("Failed to write launch.json", e);
}
VsCodeLaunch launch = new VsCodeLaunch();
launch.add(RunConfig.clientRunConfig(getProject()));
launch.add(RunConfig.serverRunConfig(getProject()));
File runDir = new File(getProject().getRootDir(), extension.runDir);
if (!runDir.exists()) {
runDir.mkdirs();
}
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(launch);
private static class VsCodeLaunch {
public String version = "0.2.0";
public List<VsCodeConfiguration> configurations = new ArrayList<>();
try {
FileUtils.writeStringToFile(launchJson, json, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException("Failed to write launch.json", e);
}
public void add(RunConfig runConfig) {
configurations.add(new VsCodeConfiguration(runConfig));
}
}
File runDir = new File(getProject().getRootDir(), extension.runDir);
private static class VsCodeConfiguration {
public String type = "java";
public String name;
public String request = "launch";
public String cwd = "${workspaceFolder}/run";
public String console = "internalConsole";
public boolean stopOnEntry = false;
public String mainClass;
public String vmArgs;
public String args;
if (!runDir.exists()) {
runDir.mkdirs();
}
}
public VsCodeConfiguration(RunConfig runConfig) {
this.name = runConfig.configName;
this.mainClass = runConfig.mainClass;
this.vmArgs = runConfig.vmArgs;
this.args = runConfig.programArgs;
}
}
private static class VsCodeLaunch {
public String version = "0.2.0";
public List<VsCodeConfiguration> configurations = new ArrayList<>();
public void add(RunConfig runConfig) {
configurations.add(new VsCodeConfiguration(runConfig));
}
}
private static class VsCodeConfiguration {
public String type = "java";
public String name;
public String request = "launch";
public String cwd = "${workspaceFolder}/run";
public String console = "internalConsole";
public boolean stopOnEntry = false;
public String mainClass;
public String vmArgs;
public String args;
VsCodeConfiguration(RunConfig runConfig) {
this.name = runConfig.configName;
this.mainClass = runConfig.mainClass;
this.vmArgs = runConfig.vmArgs;
this.args = runConfig.programArgs;
}
}
}

View File

@@ -24,10 +24,12 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.Version;
import net.fabricmc.mappings.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.MappingsReader;
import org.cadixdev.mercury.Mercury;
@@ -35,149 +37,147 @@ import org.cadixdev.mercury.remapper.MercuryRemapper;
import org.gradle.api.Project;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.util.Constants;
import net.fabricmc.loom.util.Version;
import net.fabricmc.mappings.ClassEntry;
import net.fabricmc.mappings.EntryTriple;
import net.fabricmc.mappings.FieldEntry;
import net.fabricmc.mappings.Mappings;
import net.fabricmc.mappings.MethodEntry;
public class MigrateMappingsTask extends AbstractLoomTask {
@TaskAction
public void doTask() throws Throwable {
Project project = getProject();
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
Map<String, ?> properties = project.getProperties();
@TaskAction
public void doTask() throws Throwable {
Project project = getProject();
LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class);
Map<String, ?> properties = project.getProperties();
project.getLogger().lifecycle(":loading mappings");
project.getLogger().lifecycle(":loading mappings");
File mappingsFile = null;
File mappingsFile = null;
if (properties.containsKey("targetMappingsFile")) {
mappingsFile = new File((String) properties.get("targetMappingsFile"));
} else if (properties.containsKey("targetMappingsArtifact")) {
String[] artifactName = ((String) properties.get("targetMappingsArtifact")).split(":");
if (artifactName.length != 3) {
throw new RuntimeException("Invalid artifact name: " + properties.get("targetMappingsArtifact"));
}
if (properties.containsKey("targetMappingsFile")) {
mappingsFile = new File((String) properties.get("targetMappingsFile"));
} else if (properties.containsKey("targetMappingsArtifact")) {
String[] artifactName = ((String) properties.get("targetMappingsArtifact")).split(":");
String mappingsName = artifactName[0] + "." + artifactName[1];
if (artifactName.length != 3) {
throw new RuntimeException("Invalid artifact name: " + properties.get("targetMappingsArtifact"));
}
Version v = new Version(artifactName[2]);
String minecraftVersion = v.getMinecraftVersion();
String mappingsVersion = v.getMappingsVersion();
String mappingsName = artifactName[0] + "." + artifactName[1];
mappingsFile = new File(extension.getMappingsProvider().MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
}
Version v = new Version(artifactName[2]);
String minecraftVersion = v.getMinecraftVersion();
String mappingsVersion = v.getMappingsVersion();
if (mappingsFile == null || !mappingsFile.exists()) {
throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null"));
}
mappingsFile = new File(extension.getMappingsProvider().MAPPINGS_DIR, mappingsName + "-tiny-" + minecraftVersion + "-" + mappingsVersion);
}
if (!properties.containsKey("inputDir") || !properties.containsKey("outputDir")) {
throw new RuntimeException("Must specify input and output dir!");
}
if (mappingsFile == null || !mappingsFile.exists()) {
throw new RuntimeException("Could not find mappings file: " + (mappingsFile != null ? mappingsFile : "null"));
}
File inputDir = new File((String) properties.get("inputDir"));
File outputDir = new File((String) properties.get("outputDir"));
if (!properties.containsKey("inputDir") || !properties.containsKey("outputDir")) {
throw new RuntimeException("Must specify input and output dir!");
}
if (!inputDir.exists() || !inputDir.isDirectory()) {
throw new RuntimeException("Could not find input directory: " + inputDir);
}
File inputDir = new File((String) properties.get("inputDir"));
File outputDir = new File((String) properties.get("outputDir"));
if (!outputDir.exists()) {
if (!outputDir.mkdirs()) {
throw new RuntimeException("Could not create output directory:" + outputDir);
}
}
if (!inputDir.exists() || !inputDir.isDirectory()) {
throw new RuntimeException("Could not find input directory: " + inputDir);
}
Mappings sourceMappings = extension.getMappingsProvider().getMappings();
Mappings targetMappings;
if (!outputDir.exists()) {
if (!outputDir.mkdirs()) {
throw new RuntimeException("Could not create output directory:" + outputDir);
}
}
try (FileInputStream stream = new FileInputStream(mappingsFile)) {
targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
}
Mappings sourceMappings = extension.getMappingsProvider().getMappings();
Mappings targetMappings;
project.getLogger().lifecycle(":joining mappings");
MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read();
try (FileInputStream stream = new FileInputStream(mappingsFile)) {
targetMappings = net.fabricmc.mappings.MappingsProvider.readTinyMappings(stream, false);
}
project.getLogger().lifecycle(":remapping");
Mercury mercury = new Mercury();
project.getLogger().lifecycle(":joining mappings");
MappingSet mappingSet = new MappingsJoiner(sourceMappings, targetMappings, "intermediary", "named").read();
for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
mercury.getClassPath().add(file.toPath());
}
project.getLogger().lifecycle(":remapping");
Mercury mercury = new Mercury();
for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
mercury.getClassPath().add(file.toPath());
}
for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) {
mercury.getClassPath().add(file.toPath());
}
mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath());
mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath());
for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) {
mercury.getClassPath().add(file.toPath());
}
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath());
mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath());
try {
mercury.rewrite(inputDir.toPath(), outputDir.toPath());
} catch (Exception e) {
project.getLogger().warn("Could not remap fully!", e);
}
mercury.getProcessors().add(MercuryRemapper.create(mappingSet));
project.getLogger().lifecycle(":cleaning file descriptors");
System.gc();
}
try {
mercury.rewrite(inputDir.toPath(), outputDir.toPath());
} catch (Exception e) {
project.getLogger().warn("Could not remap fully!", e);
}
public static class MappingsJoiner extends MappingsReader {
private final Mappings sourceMappings, targetMappings;
private final String fromNamespace, toNamespace;
project.getLogger().lifecycle(":cleaning file descriptors");
System.gc();
}
public MappingsJoiner(Mappings sourceMappings, Mappings targetMappings, String fromNamespace, String toNamespace) {
this.sourceMappings = sourceMappings;
this.targetMappings = targetMappings;
this.fromNamespace = fromNamespace;
this.toNamespace = toNamespace;
}
public static class MappingsJoiner extends MappingsReader {
private final Mappings sourceMappings, targetMappings;
private final String fromNamespace, toNamespace;
@Override
public MappingSet read(MappingSet mappings) throws IOException {
Map<String, ClassEntry> targetClasses = new HashMap<>();
Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
Map<EntryTriple, MethodEntry> targetMethods = new HashMap<>();
public MappingsJoiner(Mappings sourceMappings, Mappings targetMappings, String fromNamespace, String toNamespace) {
this.sourceMappings = sourceMappings;
this.targetMappings = targetMappings;
this.fromNamespace = fromNamespace;
this.toNamespace = toNamespace;
}
targetMappings.getClassEntries().forEach((c) -> targetClasses.put(c.get(fromNamespace), c));
targetMappings.getFieldEntries().forEach((c) -> targetFields.put(c.get(fromNamespace), c));
targetMappings.getMethodEntries().forEach((c) -> targetMethods.put(c.get(fromNamespace), c));
@Override
public MappingSet read(MappingSet mappings) throws IOException {
Map<String, ClassEntry> targetClasses = new HashMap<>();
Map<EntryTriple, FieldEntry> targetFields = new HashMap<>();
Map<EntryTriple, MethodEntry> targetMethods = new HashMap<>();
for (ClassEntry entry : sourceMappings.getClassEntries()) {
String from = entry.get(toNamespace);
String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
targetMappings.getClassEntries().forEach((c) -> targetClasses.put(c.get(fromNamespace), c));
targetMappings.getFieldEntries().forEach((c) -> targetFields.put(c.get(fromNamespace), c));
targetMappings.getMethodEntries().forEach((c) -> targetMethods.put(c.get(fromNamespace), c));
mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to);
}
for (ClassEntry entry : sourceMappings.getClassEntries()) {
String from = entry.get(toNamespace);
String to = targetClasses.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
for (FieldEntry entry : sourceMappings.getFieldEntries()) {
EntryTriple fromEntry = entry.get(toNamespace);
EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
mappings.getOrCreateClassMapping(from).setDeobfuscatedName(to);
}
mappings.getOrCreateClassMapping(fromEntry.getOwner())
.getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc())
.setDeobfuscatedName(toEntry.getName());
}
for (FieldEntry entry : sourceMappings.getFieldEntries()) {
EntryTriple fromEntry = entry.get(toNamespace);
EntryTriple toEntry = targetFields.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
for (MethodEntry entry : sourceMappings.getMethodEntries()) {
EntryTriple fromEntry = entry.get(toNamespace);
EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateFieldMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
}
mappings.getOrCreateClassMapping(fromEntry.getOwner())
.getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc())
.setDeobfuscatedName(toEntry.getName());
}
for (MethodEntry entry : sourceMappings.getMethodEntries()) {
EntryTriple fromEntry = entry.get(toNamespace);
EntryTriple toEntry = targetMethods.getOrDefault(entry.get(fromNamespace), entry).get(toNamespace);
return mappings;
}
mappings.getOrCreateClassMapping(fromEntry.getOwner()).getOrCreateMethodMapping(fromEntry.getName(), fromEntry.getDesc()).setDeobfuscatedName(toEntry.getName());
}
@Override
public void close() throws IOException {
return mappings;
}
}
}
@Override
public void close() throws IOException { }
}
}

View File

@@ -24,6 +24,21 @@
package net.fabricmc.loom.task;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.Set;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.jvm.tasks.Jar;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.providers.MappingsProvider;
import net.fabricmc.loom.util.GradleSupport;
@@ -33,21 +48,6 @@ import net.fabricmc.loom.util.TinyRemapperMappingsHelper;
import net.fabricmc.tinyremapper.OutputConsumerPath;
import net.fabricmc.tinyremapper.TinyRemapper;
import net.fabricmc.tinyremapper.TinyUtils;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFile;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.jvm.tasks.Jar;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.Set;
public class RemapJarTask extends Jar {
private RegularFileProperty input;
@@ -86,6 +86,7 @@ public class RemapJarTask extends Jar {
TinyRemapper.Builder remapperBuilder = TinyRemapper.newRemapper();
remapperBuilder = remapperBuilder.withMappings(TinyRemapperMappingsHelper.create(mappingsProvider.getMappings(), fromM, toM));
if (mixinMapFile.exists()) {
remapperBuilder = remapperBuilder.withMappings(TinyUtils.createTinyMappingProvider(mixinMapPath, fromM, toM));
}
@@ -93,9 +94,11 @@ public class RemapJarTask extends Jar {
project.getLogger().lifecycle(":remapping " + input.getFileName());
StringBuilder rc = new StringBuilder("Remap classpath: ");
for (Path p : classpath) {
rc.append("\n - ").append(p.toString());
}
project.getLogger().debug(rc.toString());
TinyRemapper remapper = remapperBuilder.build();

View File

@@ -24,51 +24,68 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.task.fernflower.FernFlowerTask;
import net.fabricmc.loom.util.LineNumberRemapper;
import net.fabricmc.loom.util.progress.ProgressLogger;
import net.fabricmc.stitch.util.StitchUtil;
import java.io.File;
import java.io.IOException;
import org.gradle.api.Project;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.IOException;
import net.fabricmc.loom.task.fernflower.FernFlowerTask;
import net.fabricmc.loom.util.LineNumberRemapper;
import net.fabricmc.loom.util.progress.ProgressLogger;
import net.fabricmc.stitch.util.StitchUtil;
public class RemapLineNumbersTask extends AbstractLoomTask {
private Object input;
private Object output;
private Object lineMapFile;
private Object input;
private Object output;
private Object lineMapFile;
@TaskAction
public void doTask() throws Throwable {
Project project = getProject();
@TaskAction
public void doTask() throws Throwable {
Project project = getProject();
project.getLogger().lifecycle(":adjusting line numbers");
LineNumberRemapper remapper = new LineNumberRemapper();
remapper.readMappings(getLineMapFile());
project.getLogger().lifecycle(":adjusting line numbers");
LineNumberRemapper remapper = new LineNumberRemapper();
remapper.readMappings(getLineMapFile());
ProgressLogger progressLogger = ProgressLogger.getProgressFactory(project, FernFlowerTask.class.getName());
progressLogger.start("Adjusting line numbers", "linemap");
ProgressLogger progressLogger = ProgressLogger.getProgressFactory(project, FernFlowerTask.class.getName());
progressLogger.start("Adjusting line numbers", "linemap");
try (StitchUtil.FileSystemDelegate inFs = StitchUtil.getJarFileSystem(getInput(), true);
StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(getOutput(), true)) {
remapper.process(progressLogger, inFs.get().getPath("/"), outFs.get().getPath("/"));
} catch (IOException e) {
throw new RuntimeException(e);
}
try (StitchUtil.FileSystemDelegate inFs = StitchUtil.getJarFileSystem(getInput(), true); StitchUtil.FileSystemDelegate outFs = StitchUtil.getJarFileSystem(getOutput(), true)) {
remapper.process(progressLogger, inFs.get().getPath("/"), outFs.get().getPath("/"));
} catch (IOException e) {
throw new RuntimeException(e);
}
progressLogger.completed();
}
progressLogger.completed();
}
//@formatter:off
@InputFile public File getInput() { return getProject().file(input); }
@InputFile public File getLineMapFile() { return getProject().file(lineMapFile); }
@OutputFile public File getOutput() { return getProject().file(output); }
public void setInput(Object input) { this.input = input; }
public void setLineMapFile(Object lineMapFile) { this.lineMapFile = lineMapFile; }
public void setOutput(Object output) { this.output = output; }
//@formatter:on
@InputFile
public File getInput() {
return getProject().file(input);
}
@InputFile
public File getLineMapFile() {
return getProject().file(lineMapFile);
}
@OutputFile
public File getOutput() {
return getProject().file(output);
}
public void setInput(Object input) {
this.input = input;
}
public void setLineMapFile(Object lineMapFile) {
this.lineMapFile = lineMapFile;
}
public void setOutput(Object output) {
this.output = output;
}
}

View File

@@ -24,13 +24,14 @@
package net.fabricmc.loom.task;
import net.fabricmc.loom.util.SourceRemapper;
import java.io.File;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import net.fabricmc.loom.util.SourceRemapper;
public class RemapSourcesJarTask extends AbstractLoomTask {
private Object input;
@@ -42,13 +43,30 @@ public class RemapSourcesJarTask extends AbstractLoomTask {
SourceRemapper.remapSources(getProject(), getInput(), getOutput(), direction.equals("named"));
}
//@formatter:off
@InputFile
public File getInput() { return getProject().file(input); }
@OutputFile public File getOutput() { return getProject().file(output == null ? input : output); }
@Input public String getTargetNamespace() { return direction; }
public void setInput(Object input) { this.input = input; }
public void setOutput(Object output) { this.output = output; }
public void setTargetNamespace(String value) { this.direction = value; }
//@formatter:on
public File getInput() {
return getProject().file(input);
}
@OutputFile
public File getOutput() {
return getProject().file(output == null ? input : output);
}
@Input
public String getTargetNamespace() {
return direction;
}
public void setInput(Object input) {
this.input = input;
}
public void setOutput(Object output) {
this.output = output;
}
public void setTargetNamespace(String value) {
this.direction = value;
}
}

View File

@@ -24,123 +24,140 @@
package net.fabricmc.loom.task.fernflower;
import net.fabricmc.loom.task.AbstractDecompileTask;
import net.fabricmc.loom.task.ForkingJavaExecTask;
import net.fabricmc.loom.util.ConsumingOutputStream;
import org.gradle.api.file.FileCollection;
import static java.text.MessageFormat.format;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.function.Supplier;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.logging.progress.ProgressLogger;
import org.gradle.internal.logging.progress.ProgressLoggerFactory;
import org.gradle.internal.service.ServiceRegistry;
import org.gradle.process.ExecResult;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import java.io.File;
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 java.util.*;
import java.util.function.Supplier;
import static java.text.MessageFormat.format;
/**
* Created by covers1624 on 9/02/19.
*/
public class FernFlowerTask extends AbstractDecompileTask implements ForkingJavaExecTask {
private boolean noFork = false;
private int numThreads = Runtime.getRuntime().availableProcessors();
private boolean noFork = false;
private int numThreads = Runtime.getRuntime().availableProcessors();
@TaskAction
public void doTask() throws Throwable {
if (!OperatingSystem.is64Bit()) {
throw new UnsupportedOperationException("FernFlowerTask requires a 64bit JVM to run due to the memory requirements");
}
@TaskAction
public void doTask() throws Throwable {
if(!OperatingSystem.is64Bit()){
throw new UnsupportedOperationException("FernFlowerTask requires a 64bit JVM to run due to the memory requirements");
}
Map<String, Object> options = new HashMap<>();
options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1");
options.put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1");
options.put(IFernflowerPreferences.LOG_LEVEL, "trace");
getLogging().captureStandardOutput(LogLevel.LIFECYCLE);
Map<String, Object> options = new HashMap<>();
options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1");
options.put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1");
options.put(IFernflowerPreferences.LOG_LEVEL, "trace");
getLogging().captureStandardOutput(LogLevel.LIFECYCLE);
List<String> args = new ArrayList<>();
List<String> args = new ArrayList<>();
options.forEach((k, v) -> args.add(format("-{0}={1}", k, v)));
args.add(getInput().getAbsolutePath());
args.add("-o=" + getOutput().getAbsolutePath());
options.forEach((k, v) -> args.add(format("-{0}={1}", k, v)));
args.add(getInput().getAbsolutePath());
args.add("-o=" + getOutput().getAbsolutePath());
if (getLineMapFile() != null) {
args.add("-l=" + getLineMapFile().getAbsolutePath());
}
args.add("-t=" + getNumThreads());
if (getLineMapFile() != null) {
args.add("-l=" + getLineMapFile().getAbsolutePath());
}
//TODO, Decompiler breaks on jemalloc, J9 module-info.class?
getLibraries().forEach(f -> args.add("-e=" + f.getAbsolutePath()));
args.add("-t=" + getNumThreads());
ServiceRegistry registry = ((ProjectInternal) getProject()).getServices();
ProgressLoggerFactory factory = registry.get(ProgressLoggerFactory.class);
ProgressLogger progressGroup = factory.newOperation(getClass()).setDescription("Decompile");
Supplier<ProgressLogger> loggerFactory = () -> {
ProgressLogger pl = factory.newOperation(getClass(), progressGroup);
pl.setDescription("decompile worker");
pl.started();
return pl;
};
Stack<ProgressLogger> freeLoggers = new Stack<>();
Map<String, ProgressLogger> inUseLoggers = new HashMap<>();
//TODO, Decompiler breaks on jemalloc, J9 module-info.class?
getLibraries().forEach(f -> args.add("-e=" + f.getAbsolutePath()));
progressGroup.started();
ExecResult result = javaexec(spec -> {
spec.setMain(ForkedFFExecutor.class.getName());
spec.jvmArgs("-Xms200m", "-Xmx3G");
spec.setArgs(args);
spec.setErrorOutput(System.err);
spec.setStandardOutput(new ConsumingOutputStream(line -> {
if (line.startsWith("Listening for transport") || !line.contains("::")) {
System.out.println(line);
return;
}
ServiceRegistry registry = ((ProjectInternal) getProject()).getServices();
ProgressLoggerFactory factory = registry.get(ProgressLoggerFactory.class);
ProgressLogger progressGroup = factory.newOperation(getClass()).setDescription("Decompile");
Supplier<ProgressLogger> loggerFactory = () -> {
ProgressLogger pl = factory.newOperation(getClass(), progressGroup);
pl.setDescription("decompile worker");
pl.started();
return pl;
};
Stack<ProgressLogger> freeLoggers = new Stack<>();
Map<String, ProgressLogger> inUseLoggers = new HashMap<>();
int sepIdx = line.indexOf("::");
String id = line.substring(0, sepIdx).trim();
String data = line.substring(sepIdx + 2).trim();
progressGroup.started();
ExecResult result = javaexec(spec -> {
spec.setMain(ForkedFFExecutor.class.getName());
spec.jvmArgs("-Xms200m", "-Xmx3G");
spec.setArgs(args);
spec.setErrorOutput(System.err);
spec.setStandardOutput(new ConsumingOutputStream(line -> {
if (line.startsWith("Listening for transport") || !line.contains("::")) {
System.out.println(line);
return;
}
ProgressLogger logger = inUseLoggers.get(id);
int sepIdx = line.indexOf("::");
String id = line.substring(0, sepIdx).trim();
String data = line.substring(sepIdx + 2).trim();
String[] segs = data.split(" ");
if (segs[0].equals("waiting")) {
if (logger != null) {
logger.progress("Idle..");
inUseLoggers.remove(id);
freeLoggers.push(logger);
}
} else {
if (logger == null) {
if (!freeLoggers.isEmpty()) {
logger = freeLoggers.pop();
} else {
logger = loggerFactory.get();
}
inUseLoggers.put(id, logger);
}
logger.progress(data);
}
}));
});
inUseLoggers.values().forEach(ProgressLogger::completed);
freeLoggers.forEach(ProgressLogger::completed);
progressGroup.completed();
ProgressLogger logger = inUseLoggers.get(id);
result.rethrowFailure();
result.assertNormalExitValue();
}
String[] segs = data.split(" ");
//@formatter:off
@Input public int getNumThreads() { return numThreads; }
@Input public boolean isNoFork() { return noFork; }
public void setNoFork(boolean noFork) { this.noFork = noFork; }
public void setNumThreads(int numThreads) { this.numThreads = numThreads; }
//@formatter:on
if (segs[0].equals("waiting")) {
if (logger != null) {
logger.progress("Idle..");
inUseLoggers.remove(id);
freeLoggers.push(logger);
}
} else {
if (logger == null) {
if (!freeLoggers.isEmpty()) {
logger = freeLoggers.pop();
} else {
logger = loggerFactory.get();
}
inUseLoggers.put(id, logger);
}
logger.progress(data);
}
}));
});
inUseLoggers.values().forEach(ProgressLogger::completed);
freeLoggers.forEach(ProgressLogger::completed);
progressGroup.completed();
result.rethrowFailure();
result.assertNormalExitValue();
}
@Input
public int getNumThreads() {
return numThreads;
}
@Input
public boolean isNoFork() {
return noFork;
}
public void setNoFork(boolean noFork) {
this.noFork = noFork;
}
public void setNumThreads(int numThreads) {
this.numThreads = numThreads;
}
}

View File

@@ -24,26 +24,29 @@
package net.fabricmc.loom.task.fernflower;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.io.File;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
public class FernFlowerUtils {
public static byte[] getBytecode(String externalPath, String internalPath) throws IOException {
File file = new File(externalPath);
if (internalPath == null) {
return InterpreterUtil.getBytes(file);
} else {
try (ZipFile archive = new ZipFile(file)) {
ZipEntry entry = archive.getEntry(internalPath);
if (entry == null) {
throw new IOException("Entry not found: " + internalPath);
}
return InterpreterUtil.getBytes(archive, entry);
}
}
File file = new File(externalPath);
if (internalPath == null) {
return InterpreterUtil.getBytes(file);
} else {
try (ZipFile archive = new ZipFile(file)) {
ZipEntry entry = archive.getEntry(internalPath);
if (entry == null) {
throw new IOException("Entry not found: " + internalPath);
}
return InterpreterUtil.getBytes(archive, entry);
}
}
}
}

View File

@@ -24,82 +24,92 @@
package net.fabricmc.loom.task.fernflower;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.jetbrains.java.decompiler.main.Fernflower;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Entry point for Forked FernFlower task.
* Takes one parameter, a single file, each line is treated as command line input.
* Forces one input file.
* Forces one output file using '-o=/path/to/output'
*
* Created by covers1624 on 11/02/19.
*/
public class ForkedFFExecutor {
public static void main(String[] args) throws IOException {
Map<String, Object> options = new HashMap<>();
File input = null;
File output = null;
File lineMap = null;
List<File> libraries = new ArrayList<>();
int numThreads = 0;
public static void main(String[] args) throws IOException {
Map<String, Object> options = new HashMap<>();
File input = null;
File output = null;
File lineMap = null;
List<File> libraries = new ArrayList<>();
int numThreads = 0;
boolean isOption = true;
boolean isOption = true;
for (String arg : args) {
if (isOption && arg.length() > 5 && arg.charAt(0) == '-' && arg.charAt(4) == '=') {
String value = arg.substring(5);
if ("true".equalsIgnoreCase(value)) {
value = "1";
} else if ("false".equalsIgnoreCase(value)) {
value = "0";
}
for (String arg : args) {
if (isOption && arg.length() > 5 && arg.charAt(0) == '-' && arg.charAt(4) == '=') {
String value = arg.substring(5);
options.put(arg.substring(1, 4), value);
} else {
isOption = false;
if (arg.startsWith("-e=")) {
libraries.add(new File(arg.substring(3)));
} else if (arg.startsWith("-o=")) {
if (output != null) {
throw new RuntimeException("Unable to set more than one output.");
}
output = new File(arg.substring(3));
} else if (arg.startsWith("-l=")) {
if (lineMap != null) {
throw new RuntimeException("Unable to set more than one lineMap file.");
}
lineMap = new File(arg.substring(3));
} else if (arg.startsWith("-t=")) {
numThreads = Integer.parseInt(arg.substring(3));
} else {
if (input != null) {
throw new RuntimeException("Unable to set more than one input.");
}
input = new File(arg);
}
}
}
if ("true".equalsIgnoreCase(value)) {
value = "1";
} else if ("false".equalsIgnoreCase(value)) {
value = "0";
}
Objects.requireNonNull(input, "Input not set.");
Objects.requireNonNull(output, "Output not set.");
options.put(arg.substring(1, 4), value);
} else {
isOption = false;
runFF(options, libraries, input, output, lineMap);
}
if (arg.startsWith("-e=")) {
libraries.add(new File(arg.substring(3)));
} else if (arg.startsWith("-o=")) {
if (output != null) {
throw new RuntimeException("Unable to set more than one output.");
}
public static void runFF(Map<String, Object> options, List<File> libraries, File input, File output, File lineMap) {
IResultSaver saver = new ThreadSafeResultSaver(() -> output, () -> lineMap);
IFernflowerLogger logger = new ThreadIDFFLogger();
Fernflower ff = new Fernflower(FernFlowerUtils::getBytecode, saver, options, logger);
for (File library : libraries) {
ff.addLibrary(library);
}
ff.addSource(input);
ff.decompileContext();
}
output = new File(arg.substring(3));
} else if (arg.startsWith("-l=")) {
if (lineMap != null) {
throw new RuntimeException("Unable to set more than one lineMap file.");
}
lineMap = new File(arg.substring(3));
} else if (arg.startsWith("-t=")) {
numThreads = Integer.parseInt(arg.substring(3));
} else {
if (input != null) {
throw new RuntimeException("Unable to set more than one input.");
}
input = new File(arg);
}
}
}
Objects.requireNonNull(input, "Input not set.");
Objects.requireNonNull(output, "Output not set.");
runFF(options, libraries, input, output, lineMap);
}
public static void runFF(Map<String, Object> options, List<File> libraries, File input, File output, File lineMap) {
IResultSaver saver = new ThreadSafeResultSaver(() -> output, () -> lineMap);
IFernflowerLogger logger = new ThreadIDFFLogger();
Fernflower ff = new Fernflower(FernFlowerUtils::getBytecode, saver, options, logger);
for (File library : libraries) {
ff.addLibrary(library);
}
ff.addSource(input);
ff.decompileContext();
}
}

View File

@@ -31,14 +31,9 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
* Created by covers1624 on 11/02/19.
*/
public class NoopFFLogger extends IFernflowerLogger {
@Override
public void writeMessage(String message, Severity severity) { }
@Override
public void writeMessage(String message, Severity severity) {
}
@Override
public void writeMessage(String message, Severity severity, Throwable t) {
}
@Override
public void writeMessage(String message, Severity severity, Throwable t) { }
}

View File

@@ -24,108 +24,108 @@
package net.fabricmc.loom.task.fernflower;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.Stack;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
/**
* This logger simply prints what each thread is doing
* to the console in a machine parsable way.
*
* Created by covers1624 on 11/02/19.
* <p>Created by covers1624 on 11/02/19.
*/
public class ThreadIDFFLogger extends IFernflowerLogger {
public final PrintStream stdOut;
public final PrintStream stdErr;
public final PrintStream stdOut;
public final PrintStream stdErr;
private ThreadLocal<Stack<String>> workingClass = ThreadLocal.withInitial(Stack::new);
private ThreadLocal<Stack<String>> line = ThreadLocal.withInitial(Stack::new);
private ThreadLocal<Stack<String>> workingClass = ThreadLocal.withInitial(Stack::new);
private ThreadLocal<Stack<String>> line = ThreadLocal.withInitial(Stack::new);
public ThreadIDFFLogger() {
this(System.err, System.out);
}
public ThreadIDFFLogger() {
this(System.err, System.out);
}
public ThreadIDFFLogger(PrintStream stdOut, PrintStream stdErr) {
this.stdOut = stdOut;
this.stdErr = stdErr;
}
public ThreadIDFFLogger(PrintStream stdOut, PrintStream stdErr) {
this.stdOut = stdOut;
this.stdErr = stdErr;
}
@Override
public void writeMessage(String message, Severity severity) {
System.err.println(message);
}
@Override
public void writeMessage(String message, Severity severity) {
System.err.println(message);
}
@Override
public void writeMessage(String message, Severity severity, Throwable t) {
System.err.println(message);
t.printStackTrace(System.err);
}
@Override
public void writeMessage(String message, Severity severity, Throwable t) {
System.err.println(message);
t.printStackTrace(System.err);
}
private void print() {
Thread thread = Thread.currentThread();
long id = thread.getId();
private void print() {
Thread thread = Thread.currentThread();
long id = thread.getId();
if (line.get().isEmpty()) {
System.out.println(MessageFormat.format("{0} :: waiting", id));
return;
}
String line = this.line.get().peek();
System.out.println(MessageFormat.format("{0} :: {1}", id, line).trim());
}
if (line.get().isEmpty()) {
System.out.println(MessageFormat.format("{0} :: waiting", id));
return;
}
@Override
public void startReadingClass(String className) {
workingClass.get().push(className);
line.get().push("Decompiling " + className);
print();
}
String line = this.line.get().peek();
System.out.println(MessageFormat.format("{0} :: {1}", id, line).trim());
}
@Override
public void startClass(String className) {
workingClass.get().push(className);
line.get().push("Decompiling " + className);
print();
}
@Override
public void startReadingClass(String className) {
workingClass.get().push(className);
line.get().push("Decompiling " + className);
print();
}
@Override
public void startMethod(String methodName) {
String className = workingClass.get().peek();
line.get().push("Decompiling " + className + "." + methodName.substring(0, methodName.indexOf(" ")));
print();
}
@Override
public void startClass(String className) {
workingClass.get().push(className);
line.get().push("Decompiling " + className);
print();
}
@Override
public void endMethod() {
line.get().pop();
print();
}
@Override
public void startMethod(String methodName) {
String className = workingClass.get().peek();
line.get().push("Decompiling " + className + "." + methodName.substring(0, methodName.indexOf(" ")));
print();
}
@Override
public void endClass() {
line.get().pop();
workingClass.get().pop();
print();
}
@Override
public void endMethod() {
line.get().pop();
print();
}
@Override
public void startWriteClass(String className) {
line.get().push("Writing " + className);
print();
}
@Override
public void endClass() {
line.get().pop();
workingClass.get().pop();
print();
}
@Override
public void endWriteClass() {
line.get().pop();
print();
}
@Override
public void startWriteClass(String className) {
line.get().push("Writing " + className);
print();
}
@Override
public void endReadingClass() {
line.get().pop();
workingClass.get().pop();
print();
}
@Override
public void endWriteClass() {
line.get().pop();
print();
}
@Override
public void endReadingClass() {
line.get().pop();
workingClass.get().pop();
print();
}
}

View File

@@ -24,11 +24,11 @@
package net.fabricmc.loom.task.fernflower;
import net.fabricmc.fernflower.api.IFabricResultSaver;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
import java.io.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -42,108 +42,136 @@ import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
import net.fabricmc.fernflower.api.IFabricResultSaver;
/**
* Created by covers1624 on 18/02/19.
*/
public class ThreadSafeResultSaver implements IResultSaver, IFabricResultSaver {
private final Supplier<File> output;
private final Supplier<File> lineMapFile;
private final Supplier<File> output;
private final Supplier<File> lineMapFile;
public Map<String, ZipOutputStream> outputStreams = new HashMap<>();
public Map<String, ExecutorService> saveExecutors = new HashMap<>();
public PrintWriter lineMapWriter;
public Map<String, ZipOutputStream> outputStreams = new HashMap<>();
public Map<String, ExecutorService> saveExecutors = new HashMap<>();
public PrintWriter lineMapWriter;
public ThreadSafeResultSaver(Supplier<File> output, Supplier<File> lineMapFile) {
this.output = output;
this.lineMapFile = lineMapFile;
}
public ThreadSafeResultSaver(Supplier<File> output, Supplier<File> lineMapFile) {
this.output = output;
this.lineMapFile = lineMapFile;
}
@Override
public void createArchive(String path, String archiveName, Manifest manifest) {
String key = path + "/" + archiveName;
File file = output.get();
try {
FileOutputStream fos = new FileOutputStream(file);
ZipOutputStream zos = manifest == null ? new ZipOutputStream(fos) : new JarOutputStream(fos, manifest);
outputStreams.put(key, zos);
saveExecutors.put(key, Executors.newSingleThreadExecutor());
} catch (IOException e) {
throw new RuntimeException("Unable to create archive: " + file, e);
}
if (lineMapFile.get() != null) {
try {
lineMapWriter = new PrintWriter(new FileWriter(lineMapFile.get()));
} catch (IOException e) {
throw new RuntimeException("Unable to create line mapping file: " + lineMapFile.get(), e);
}
}
}
@Override
public void createArchive(String path, String archiveName, Manifest manifest) {
String key = path + "/" + archiveName;
File file = output.get();
@Override
public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content) {
this.saveClassEntry(path, archiveName, qualifiedName, entryName, content, null);
}
try {
FileOutputStream fos = new FileOutputStream(file);
ZipOutputStream zos = manifest == null ? new ZipOutputStream(fos) : new JarOutputStream(fos, manifest);
outputStreams.put(key, zos);
saveExecutors.put(key, Executors.newSingleThreadExecutor());
} catch (IOException e) {
throw new RuntimeException("Unable to create archive: " + file, e);
}
@Override
public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content, int[] mapping) {
String key = path + "/" + archiveName;
ExecutorService executor = saveExecutors.get(key);
executor.submit(() -> {
ZipOutputStream zos = outputStreams.get(key);
try {
zos.putNextEntry(new ZipEntry(entryName));
if (content != null) {
zos.write(content.getBytes(StandardCharsets.UTF_8));
}
} catch (IOException e) {
DecompilerContext.getLogger().writeMessage("Cannot write entry " + entryName, e);
}
if (mapping != null && lineMapWriter != null) {
int maxLine = 0;
int maxLineDest = 0;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < mapping.length; i += 2) {
maxLine = Math.max(maxLine, mapping[i]);
maxLineDest = Math.max(maxLineDest, mapping[i + 1]);
builder.append("\t").append(mapping[i]).append("\t").append(mapping[i + 1]).append("\n");
}
lineMapWriter.println(qualifiedName + "\t" + maxLine + "\t" + maxLineDest);
lineMapWriter.println(builder.toString());
}
});
}
if (lineMapFile.get() != null) {
try {
lineMapWriter = new PrintWriter(new FileWriter(lineMapFile.get()));
} catch (IOException e) {
throw new RuntimeException("Unable to create line mapping file: " + lineMapFile.get(), e);
}
}
}
@Override
public void closeArchive(String path, String archiveName) {
String key = path + "/" + archiveName;
ExecutorService executor = saveExecutors.get(key);
Future<?> closeFuture = executor.submit(() -> {
ZipOutputStream zos = outputStreams.get(key);
try {
zos.close();
} catch (IOException e) {
throw new RuntimeException("Unable to close zip. " + key, e);
}
});
executor.shutdown();
try {
closeFuture.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
outputStreams.remove(key);
saveExecutors.remove(key);
if (lineMapWriter != null) {
lineMapWriter.flush();
lineMapWriter.close();
}
}
@Override
public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content) {
this.saveClassEntry(path, archiveName, qualifiedName, entryName, content, null);
}
//@formatter:off
@Override public void saveFolder(String path) { }
@Override public void copyFile(String source, String path, String entryName) { }
@Override public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) { }
@Override public void saveDirEntry(String path, String archiveName, String entryName) { }
@Override public void copyEntry(String source, String path, String archiveName, String entry) { }
//@formatter:on
@Override
public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content, int[] mapping) {
String key = path + "/" + archiveName;
ExecutorService executor = saveExecutors.get(key);
executor.submit(() -> {
ZipOutputStream zos = outputStreams.get(key);
try {
zos.putNextEntry(new ZipEntry(entryName));
if (content != null) {
zos.write(content.getBytes(StandardCharsets.UTF_8));
}
} catch (IOException e) {
DecompilerContext.getLogger().writeMessage("Cannot write entry " + entryName, e);
}
if (mapping != null && lineMapWriter != null) {
int maxLine = 0;
int maxLineDest = 0;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < mapping.length; i += 2) {
maxLine = Math.max(maxLine, mapping[i]);
maxLineDest = Math.max(maxLineDest, mapping[i + 1]);
builder.append("\t").append(mapping[i]).append("\t").append(mapping[i + 1]).append("\n");
}
lineMapWriter.println(qualifiedName + "\t" + maxLine + "\t" + maxLineDest);
lineMapWriter.println(builder.toString());
}
});
}
@Override
public void closeArchive(String path, String archiveName) {
String key = path + "/" + archiveName;
ExecutorService executor = saveExecutors.get(key);
Future<?> closeFuture = executor.submit(() -> {
ZipOutputStream zos = outputStreams.get(key);
try {
zos.close();
} catch (IOException e) {
throw new RuntimeException("Unable to close zip. " + key, e);
}
});
executor.shutdown();
try {
closeFuture.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
outputStreams.remove(key);
saveExecutors.remove(key);
if (lineMapWriter != null) {
lineMapWriter.flush();
lineMapWriter.close();
}
}
@Override
public void saveFolder(String path) {
}
@Override
public void copyFile(String source, String path, String entryName) {
}
@Override
public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) {
}
@Override
public void saveDirEntry(String path, String archiveName, String entryName) {
}
@Override
public void copyEntry(String source, String path, String archiveName, String entry) {
}
}