From ff382a6fdfec77d9b9cb3165eb7eb2989abb604f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 5 Sep 2014 13:12:40 +0400 Subject: 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 +- .../java/decompiler/main/ClassesProcessor.java | 7 +- .../java/decompiler/main/DecompilerContext.java | 10 +- .../jetbrains/java/decompiler/main/Fernflower.java | 19 +- .../decompiler/main/decompiler/BaseDecompiler.java | 47 +++ .../main/decompiler/ConsoleDecompiler.java | 376 ++++++++++----------- .../decompiler/main/decompiler/IdeDecompiler.java | 54 --- .../main/decompiler/PrintStreamLogger.java | 80 +++++ .../decompiler/main/decompiler/WebDecompiler.java | 78 ----- .../main/decompiler/helper/PrintStreamLogger.java | 84 ----- .../decompiler/main/extern/IBytecodeProvider.java | 5 +- .../decompiler/main/extern/IDecompilatSaver.java | 39 --- .../decompiler/main/extern/IFernflowerLogger.java | 46 ++- .../main/extern/IFernflowerPreferences.java | 1 + .../java/decompiler/main/extern/IResultSaver.java | 36 ++ .../java/decompiler/main/rels/ClassWrapper.java | 2 +- .../main/rels/MethodProcessorThread.java | 2 +- .../decompiler/main/rels/NestedClassProcessor.java | 9 +- .../decompiler/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 +- .../java/decompiler/struct/lazy/LazyLoader.java | 10 +- .../java/decompiler/util/DataInputFullStream.java | 6 +- .../java/decompiler/util/InterpreterUtil.java | 25 ++ .../java/decompiler/SingleClassesTest.java | 4 +- 30 files changed, 551 insertions(+), 741 deletions(-) create mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java delete mode 100644 src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java 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 delete mode 100644 src/org/jetbrains/java/decompiler/main/extern/IDecompilatSaver.java create mode 100644 src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java 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/BaseDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java new file mode 100644 index 0000000..07b8578 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.main.decompiler; + +import org.jetbrains.java.decompiler.main.Fernflower; +import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; +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.Map; + +public class BaseDecompiler { + + private final Fernflower fernflower; + + 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 { + fernflower.getStructContext().addSpace(file, isOwn); + } + + public void decompileContext() { + try { + fernflower.decompileContext(); + } + finally { + fernflower.clearContext(); + } + } +} 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 [-