aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/net/fabricmc/loom/decompilers/fernflower
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/net/fabricmc/loom/decompilers/fernflower')
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java163
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractForkedFFExecutor.java107
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricFernFlowerDecompiler.java39
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/FernflowerLogger.java (renamed from src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricForkedFFExecutor.java)64
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/ForkingJavaExec.java70
-rw-r--r--src/main/java/net/fabricmc/loom/decompilers/fernflower/ThreadIDFFLogger.java127
6 files changed, 76 insertions, 494 deletions
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java
deleted file mode 100644
index f059ed36..00000000
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractFernFlowerDecompiler.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * This file is part of fabric-loom, licensed under the MIT License (MIT).
- *
- * Copyright (c) 2019-2021 FabricMC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.fabricmc.loom.decompilers.fernflower;
-
-import static java.text.MessageFormat.format;
-
-import java.nio.file.Path;
-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.gradle.api.Project;
-import org.gradle.api.internal.project.ProjectInternal;
-import org.gradle.api.logging.LogLevel;
-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 net.fabricmc.loom.api.decompilers.DecompilationMetadata;
-import net.fabricmc.loom.api.decompilers.LoomDecompiler;
-import net.fabricmc.loom.util.ConsumingOutputStream;
-import net.fabricmc.loom.util.OperatingSystem;
-
-public abstract class AbstractFernFlowerDecompiler implements LoomDecompiler {
- private final Project project;
-
- protected AbstractFernFlowerDecompiler(Project project) {
- this.project = project;
- }
-
- public abstract Class<? extends AbstractForkedFFExecutor> fernFlowerExecutor();
-
- @Override
- public void decompile(Path compiledJar, Path sourcesDestination, Path linemapDestination, DecompilationMetadata metaData) {
- if (!OperatingSystem.is64Bit()) {
- throw new UnsupportedOperationException("FernFlower decompiler requires a 64bit JVM to run due to the memory requirements");
- }
-
- project.getLogging().captureStandardOutput(LogLevel.LIFECYCLE);
-
- Map<String, Object> options = new HashMap<>() {{
- put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1");
- put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1");
- put(IFernflowerPreferences.REMOVE_SYNTHETIC, "1");
- put(IFernflowerPreferences.LOG_LEVEL, "trace");
- put(IFernflowerPreferences.THREADS, metaData.numberOfThreads());
- put(IFernflowerPreferences.INDENT_STRING, "\t");
- }};
-
- List<String> args = new ArrayList<>();
-
- options.forEach((k, v) -> args.add(format("-{0}={1}", k, v)));
- args.add(absolutePathOf(compiledJar));
- args.add("-o=" + absolutePathOf(sourcesDestination));
- args.add("-l=" + absolutePathOf(linemapDestination));
- args.add("-m=" + absolutePathOf(metaData.javaDocs()));
-
- // TODO, Decompiler breaks on jemalloc, J9 module-info.class?
- for (Path library : metaData.libraries()) {
- args.add("-e=" + absolutePathOf(library));
- }
-
- ServiceRegistry registry = ((ProjectInternal) project).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<>();
-
- progressGroup.started();
- ExecResult result = ForkingJavaExec.javaexec(
- project,
- spec -> {
- spec.getMainClass().set(fernFlowerExecutor().getName());
- spec.jvmArgs("-Xms200m", "-Xmx3G");
- spec.setArgs(args);
- spec.setErrorOutput(new ConsumingOutputStream(line -> {
- if (line.startsWith("Inconsistent inner class entries")) {
- // Suppress this
- return;
- }
-
- System.err.println(line);
- }));
- spec.setStandardOutput(new ConsumingOutputStream(line -> {
- if (line.startsWith("Listening for transport") || !line.contains("::")) {
- System.out.println(line);
- return;
- }
-
- int sepIdx = line.indexOf("::");
- String id = line.substring(0, sepIdx).trim();
- String data = line.substring(sepIdx + 2).trim();
-
- ProgressLogger logger = inUseLoggers.get(id);
-
- 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();
-
- result.rethrowFailure();
- result.assertNormalExitValue();
- }
-
- private static String absolutePathOf(Path path) {
- return path.toAbsolutePath().toString();
- }
-}
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractForkedFFExecutor.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractForkedFFExecutor.java
deleted file mode 100644
index 2435233e..00000000
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/AbstractForkedFFExecutor.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * This file is part of fabric-loom, licensed under the MIT License (MIT).
- *
- * Copyright (c) 2019-2020 FabricMC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.fabricmc.loom.decompilers.fernflower;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * 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.
- * <p>Extending classes MUST have a standard "public static void main(args)".
- * They may then call AbstractForkedFFExecutor#decompile for it to use the overridden AbstractForkedFFExecutor#runFF
- * </p>
- */
-public abstract class AbstractForkedFFExecutor {
- public static void decompile(String[] args, AbstractForkedFFExecutor ffExecutor) {
- Map<String, Object> options = new HashMap<>();
- File input = null;
- File output = null;
- File lineMap = null;
- File mappings = null;
- List<File> libraries = new ArrayList<>();
-
- 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";
- }
-
- 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("-m=")) {
- if (mappings != null) {
- throw new RuntimeException("Unable to use more than one mappings file.");
- }
-
- mappings = new File(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.");
- Objects.requireNonNull(mappings, "Mappings not set.");
-
- ffExecutor.runFF(options, libraries, input, output, lineMap, mappings);
- }
-
- public abstract void runFF(Map<String, Object> options, List<File> libraries, File input, File output, File lineMap, File mappings);
-}
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricFernFlowerDecompiler.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricFernFlowerDecompiler.java
index b3663773..c3009448 100644
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricFernFlowerDecompiler.java
+++ b/src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricFernFlowerDecompiler.java
@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
- * Copyright (c) 2018-2020 FabricMC
+ * Copyright (c) 2019-2021 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,20 +24,43 @@
package net.fabricmc.loom.decompilers.fernflower;
-import org.gradle.api.Project;
+import java.nio.file.Path;
+import java.util.Map;
-public class FabricFernFlowerDecompiler extends AbstractFernFlowerDecompiler {
- public FabricFernFlowerDecompiler(Project project) {
- super(project);
- }
+import org.jetbrains.java.decompiler.main.Fernflower;
+import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
+import org.jetbrains.java.decompiler.main.extern.IResultSaver;
+
+import net.fabricmc.fernflower.api.IFabricJavadocProvider;
+import net.fabricmc.loom.api.decompilers.DecompilationMetadata;
+import net.fabricmc.loom.api.decompilers.LoomDecompiler;
+public final class FabricFernFlowerDecompiler implements LoomDecompiler {
@Override
public String name() {
return "FabricFlower"; // Or something else?
}
@Override
- public Class<? extends AbstractForkedFFExecutor> fernFlowerExecutor() {
- return FabricForkedFFExecutor.class;
+ public void decompile(Path compiledJar, Path sourcesDestination, Path linemapDestination, DecompilationMetadata metaData) {
+ Map<String, Object> options = Map.of(
+ IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1",
+ IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1",
+ IFernflowerPreferences.REMOVE_SYNTHETIC, "1",
+ IFernflowerPreferences.LOG_LEVEL, "trace",
+ IFernflowerPreferences.THREADS, String.valueOf(metaData.numberOfThreads()),
+ IFernflowerPreferences.INDENT_STRING, "\t",
+ IFabricJavadocProvider.PROPERTY_NAME, new TinyJavadocProvider(metaData.javaDocs().toFile())
+ );
+
+ IResultSaver saver = new ThreadSafeResultSaver(sourcesDestination::toFile, linemapDestination::toFile);
+ Fernflower ff = new Fernflower(FernFlowerUtils::getBytecode, saver, options, new FernflowerLogger(metaData.logger()));
+
+ for (Path library : metaData.libraries()) {
+ ff.addLibrary(library.toFile());
+ }
+
+ ff.addSource(compiledJar.toFile());
+ ff.decompileContext();
}
}
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricForkedFFExecutor.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/FernflowerLogger.java
index e88c8086..a98060e9 100644
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/FabricForkedFFExecutor.java
+++ b/src/main/java/net/fabricmc/loom/decompilers/fernflower/FernflowerLogger.java
@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
- * Copyright (c) 2018-2020 FabricMC
+ * Copyright (c) 2021 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,34 +24,60 @@
package net.fabricmc.loom.decompilers.fernflower;
-import java.io.File;
-import java.util.List;
-import java.util.Map;
+import java.io.IOException;
-import org.jetbrains.java.decompiler.main.Fernflower;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
-import org.jetbrains.java.decompiler.main.extern.IResultSaver;
-import net.fabricmc.fernflower.api.IFabricJavadocProvider;
+import net.fabricmc.loom.util.IOStringConsumer;
-public class FabricForkedFFExecutor extends AbstractForkedFFExecutor {
- public static void main(String[] args) {
- AbstractForkedFFExecutor.decompile(args, new FabricForkedFFExecutor());
+public class FernflowerLogger extends IFernflowerLogger {
+ private final IOStringConsumer logger;
+
+ public FernflowerLogger(IOStringConsumer logger) {
+ this.logger = logger;
}
@Override
- public void runFF(Map<String, Object> options, List<File> libraries, File input, File output, File lineMap, File mappings) {
- options.put(IFabricJavadocProvider.PROPERTY_NAME, new TinyJavadocProvider(mappings));
+ public void writeMessage(String message, Severity severity) {
+ if (message.contains("Inconsistent inner class entries for")) return;
+ System.err.println(message);
+ }
- IResultSaver saver = new ThreadSafeResultSaver(() -> output, () -> lineMap);
- IFernflowerLogger logger = new ThreadIDFFLogger();
- Fernflower ff = new Fernflower(FernFlowerUtils::getBytecode, saver, options, logger);
+ @Override
+ public void writeMessage(String message, Severity severity, Throwable t) {
+ writeMessage(message, severity);
+ }
- for (File library : libraries) {
- ff.addLibrary(library);
+ private void write(String data) {
+ try {
+ logger.accept(data);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to log", e);
}
+ }
+
+ @Override
+ public void startReadingClass(String className) {
+ write("Decompiling " + className);
+ }
+
+ @Override
+ public void startClass(String className) {
+ write("Decompiling " + className);
+ }
+
+ @Override
+ public void startWriteClass(String className) {
+ // Nope
+ }
- ff.addSource(input);
- ff.decompileContext();
+ @Override
+ public void startMethod(String methodName) {
+ // Nope
+ }
+
+ @Override
+ public void endMethod() {
+ // Nope
}
}
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/ForkingJavaExec.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/ForkingJavaExec.java
deleted file mode 100644
index bbcd80de..00000000
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/ForkingJavaExec.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is part of fabric-loom, licensed under the MIT License (MIT).
- *
- * Copyright (c) 2016-2021 FabricMC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.fabricmc.loom.decompilers.fernflower;
-
-import java.net.URL;
-import java.net.URLClassLoader;
-
-import org.gradle.api.Action;
-import org.gradle.api.Project;
-import org.gradle.api.artifacts.ConfigurationContainer;
-import org.gradle.api.artifacts.dsl.DependencyHandler;
-import org.gradle.api.file.FileCollection;
-import org.gradle.process.ExecResult;
-import org.gradle.process.JavaExecSpec;
-
-/**
- * Simple utility class for a Task that wishes to execute a java process
- * with the classpath of the gradle plugin plus groovy.
- *
- * <p>Created by covers1624 on 11/02/19.
- */
-public class ForkingJavaExec {
- public static ExecResult javaexec(Project project, Action<? super JavaExecSpec> action) {
- return project.javaexec(spec -> {
- spec.classpath(getClasspath(project));
- action.execute(spec);
- });
- }
-
- private static Object getClasspath(Project project) {
- if (System.getProperty("fabric.loom.test") != null) {
- return getTestClasspath();
- }
-
- return getRuntimeClasspath(project.getRootProject().getPlugins().hasPlugin("fabric-loom") ? project.getRootProject() : project);
- }
-
- private static FileCollection getRuntimeClasspath(Project project) {
- ConfigurationContainer configurations = project.getBuildscript().getConfigurations();
- DependencyHandler handler = project.getDependencies();
- return configurations.getByName("classpath")
- .plus(configurations.detachedConfiguration(handler.localGroovy()));
- }
-
- private static URL[] getTestClasspath() {
- return ((URLClassLoader) ForkingJavaExec.class.getClassLoader()).getURLs();
- }
-}
diff --git a/src/main/java/net/fabricmc/loom/decompilers/fernflower/ThreadIDFFLogger.java b/src/main/java/net/fabricmc/loom/decompilers/fernflower/ThreadIDFFLogger.java
deleted file mode 100644
index a7b617bc..00000000
--- a/src/main/java/net/fabricmc/loom/decompilers/fernflower/ThreadIDFFLogger.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * This file is part of fabric-loom, licensed under the MIT License (MIT).
- *
- * Copyright (c) 2019-2020 FabricMC
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package net.fabricmc.loom.decompilers.fernflower;
-
-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.
- *
- * <p>Created by covers1624 on 11/02/19.
- */
-public class ThreadIDFFLogger extends IFernflowerLogger {
- public final PrintStream stdOut;
- public final PrintStream stdErr;
-
- private final ThreadLocal<Stack<String>> workingClass = ThreadLocal.withInitial(Stack::new);
- private final ThreadLocal<Stack<String>> line = ThreadLocal.withInitial(Stack::new);
-
- public ThreadIDFFLogger() {
- this(System.err, System.out);
- }
-
- 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, Throwable t) {
- System.err.println(message);
- t.printStackTrace(System.err);
- }
-
- 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());
- }
-
- @Override
- public void startReadingClass(String className) {
- workingClass.get().push(className);
- line.get().push("Decompiling " + className);
- print();
- }
-
- @Override
- public void startClass(String className) {
- workingClass.get().push(className);
- line.get().push("Decompiling " + className);
- print();
- }
-
- @Override
- public void startMethod(String methodName) {
- // No need to print out methods
- }
-
- @Override
- public void endMethod() {
- }
-
- @Override
- public void endClass() {
- line.get().pop();
- workingClass.get().pop();
- print();
- }
-
- @Override
- public void startWriteClass(String className) {
- line.get().push("Writing " + className);
- print();
- }
-
- @Override
- public void endWriteClass() {
- line.get().pop();
- print();
- }
-
- @Override
- public void endReadingClass() {
- line.get().pop();
- workingClass.get().pop();
- print();
- }
-}