From ff382a6fdfec77d9b9cb3165eb7eb2989abb604f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 5 Sep 2014 13:12:40 +0400 Subject: [PATCH] java-decompiler: fixes and cleanups - console decompiler: resource closing, lookup instead of scan, error reporting - logger interface reworked - saver interface renamed - bytecode provider returns byte array (to reduce stream leakage) - extra level of context unit avoided - unneeded exceptions, dead code, formatting --- .../java/decompiler/main/ClassWriter.java | 2 +- .../decompiler/main/ClassesProcessor.java | 7 +- .../decompiler/main/DecompilerContext.java | 10 +- .../java/decompiler/main/Fernflower.java | 19 +- ...IdeDecompiler.java => BaseDecompiler.java} | 19 +- .../main/decompiler/ConsoleDecompiler.java | 376 ++++++++---------- .../main/decompiler/PrintStreamLogger.java | 80 ++++ .../main/decompiler/WebDecompiler.java | 78 ---- .../decompiler/helper/PrintStreamLogger.java | 84 ---- .../main/extern/IBytecodeProvider.java | 5 +- .../main/extern/IFernflowerLogger.java | 46 +-- .../main/extern/IFernflowerPreferences.java | 1 + ...DecompilatSaver.java => IResultSaver.java} | 19 +- .../decompiler/main/rels/ClassWrapper.java | 2 +- .../main/rels/MethodProcessorThread.java | 2 +- .../main/rels/NestedClassProcessor.java | 9 +- .../modules/decompiler/DomHelper.java | 7 +- .../modules/decompiler/stats/Statement.java | 2 +- .../modules/renamer/IdentifierConverter.java | 4 +- .../java/decompiler/struct/ContextUnit.java | 146 +++---- .../java/decompiler/struct/StructClass.java | 5 +- .../java/decompiler/struct/StructContext.java | 180 ++++----- .../java/decompiler/struct/StructMethod.java | 3 +- .../struct/attr/StructGeneralAttribute.java | 3 +- .../decompiler/struct/lazy/LazyLoader.java | 10 +- .../decompiler/util/DataInputFullStream.java | 6 +- .../java/decompiler/util/InterpreterUtil.java | 25 ++ .../java/decompiler/SingleClassesTest.java | 4 +- 28 files changed, 482 insertions(+), 672 deletions(-) rename src/org/jetbrains/java/decompiler/main/decompiler/{IdeDecompiler.java => BaseDecompiler.java} (69%) create mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/PrintStreamLogger.java delete mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/WebDecompiler.java delete mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/helper/PrintStreamLogger.java rename src/org/jetbrains/java/decompiler/main/extern/{IDecompilatSaver.java => IResultSaver.java} (62%) diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 29307e5..63f60ba 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -630,7 +630,7 @@ public class ClassWriter { if (isEnum && init) actualParams -= 2; if (actualParams != descriptor.params.size()) { String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor(); - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.WARNING); + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); descriptor = null; } } diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 74c86d0..6faad08 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -113,7 +113,7 @@ public class ClassesProcessor { else { if (!InterpreterUtil.equalObjectArrays(arrold, arr)) { DecompilerContext.getLogger() - .writeMessage("Inconsistent inner class entries for " + innername + "!", IFernflowerLogger.WARNING); + .writeMessage("Inconsistent inner class entries for " + innername + "!", IFernflowerLogger.Severity.WARN); } } @@ -178,7 +178,8 @@ public class ClassesProcessor { ClassNode nestednode = mapRootClasses.get(nestedClass); if (nestednode == null) { - DecompilerContext.getLogger().writeMessage("Nested class " + nestedClass + " missing!", IFernflowerLogger.WARNING); + DecompilerContext.getLogger().writeMessage("Nested class " + nestedClass + " missing!", + IFernflowerLogger.Severity.WARN); continue; } @@ -204,7 +205,7 @@ public class ClassesProcessor { if (interfaces.length > 0) { if (interfaces.length > 1) { DecompilerContext.getLogger() - .writeMessage("Inconsistent anonymous class definition: " + cl.qualifiedName, IFernflowerLogger.WARNING); + .writeMessage("Inconsistent anonymous class definition: " + cl.qualifiedName, IFernflowerLogger.Severity.WARN); } nestednode.anonimousClassType = new VarType(cl.getInterface(0), true); } diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java index 54c426b..b600250 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -132,12 +132,12 @@ public class DecompilerContext { public static void setLogger(IFernflowerLogger logger) { if (logger != null) { - String severity = (String)getProperty(IFernflowerPreferences.LOG_LEVEL); - if (severity != null) { - Integer iSeverity = IFernflowerLogger.mapLogLevel.get(severity.toUpperCase(Locale.US)); - if (iSeverity != null) { - logger.setSeverity(iSeverity); + String level = (String)getProperty(IFernflowerPreferences.LOG_LEVEL); + if (level != null) { + try { + logger.setSeverity(IFernflowerLogger.Severity.valueOf(level.toUpperCase(Locale.US))); } + catch (IllegalArgumentException ignore) { } } } getCurrentContext().logger = logger; diff --git a/src/org/jetbrains/java/decompiler/main/Fernflower.java b/src/org/jetbrains/java/decompiler/main/Fernflower.java index 34f9196..62b8ee4 100644 --- a/src/org/jetbrains/java/decompiler/main/Fernflower.java +++ b/src/org/jetbrains/java/decompiler/main/Fernflower.java @@ -18,7 +18,8 @@ package org.jetbrains.java.decompiler.main; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.collectors.CounterContainer; import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; -import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; +import org.jetbrains.java.decompiler.main.extern.IResultSaver; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.renamer.IdentifierConverter; import org.jetbrains.java.decompiler.struct.IDecompiledData; @@ -28,16 +29,16 @@ import org.jetbrains.java.decompiler.struct.lazy.LazyLoader; import java.util.Map; - public class Fernflower implements IDecompiledData { private StructContext structContext; private ClassesProcessor classesProcessor; - public Fernflower(IBytecodeProvider provider, IDecompilatSaver saver, Map propertiesCustom) { + public Fernflower(IBytecodeProvider provider, IResultSaver saver, Map options, IFernflowerLogger logger) { structContext = new StructContext(saver, this, new LazyLoader(provider)); - DecompilerContext.initContext(propertiesCustom); + DecompilerContext.initContext(options); DecompilerContext.setCounterContainer(new CounterContainer()); + DecompilerContext.setLogger(logger); } public void decompileContext() { @@ -57,6 +58,11 @@ public class Fernflower implements IDecompiledData { DecompilerContext.setCurrentContext(null); } + public StructContext getStructContext() { + return structContext; + } + + @Override public String getClassEntryName(StructClass cl, String entryName) { ClassNode node = classesProcessor.getMapRootClasses().get(cl.qualifiedName); if (node.type != ClassNode.CLASS_ROOT) { @@ -73,10 +79,7 @@ public class Fernflower implements IDecompiledData { } } - public StructContext getStructContext() { - return structContext; - } - + @Override public String getClassContent(StructClass cl) { try { StringBuilder buffer = new StringBuilder(); diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java similarity index 69% rename from src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java rename to src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java index 212a8bd..07b8578 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java @@ -15,28 +15,21 @@ */ package org.jetbrains.java.decompiler.main.decompiler; -import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.Fernflower; import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; -import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver; 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.HashMap; +import java.util.Map; +public class BaseDecompiler { -public class IdeDecompiler { + private final Fernflower fernflower; - private Fernflower fernflower; - - public IdeDecompiler(IBytecodeProvider provider, - IDecompilatSaver saver, IFernflowerLogger logger, - HashMap propertiesCustom) { - - fernflower = new Fernflower(provider, saver, propertiesCustom); - - DecompilerContext.setLogger(logger); + public BaseDecompiler(IBytecodeProvider provider, IResultSaver saver, Map options, IFernflowerLogger logger) { + fernflower = new Fernflower(provider, saver, options, logger); } public void addSpace(File file, boolean isOwn) throws IOException { diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java index d499324..a486d9f 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java @@ -17,10 +17,9 @@ package org.jetbrains.java.decompiler.main.decompiler; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.Fernflower; -import org.jetbrains.java.decompiler.main.decompiler.helper.PrintStreamLogger; import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; -import org.jetbrains.java.decompiler.main.extern.IDecompilatSaver; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; +import org.jetbrains.java.decompiler.main.extern.IResultSaver; import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.io.*; @@ -31,108 +30,97 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace"}) -public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver { +public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { - private File root; + @SuppressWarnings("UseOfSystemOutOrSystemErr") + public static void main(String[] args) { + if (args.length < 2) { + System.out.println( + "Usage: java -jar fernflower.jar [-