[java decompiler] reworks setting/accessing decompiler context

master
Roman Shevchenko 7 years ago
parent fbc3165138
commit 71d8f4d689
  1. 17
      src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
  2. 150
      src/org/jetbrains/java/decompiler/main/DecompilerContext.java
  3. 62
      src/org/jetbrains/java/decompiler/main/Fernflower.java
  4. 3
      src/org/jetbrains/java/decompiler/main/collectors/CounterContainer.java
  5. 5
      src/org/jetbrains/java/decompiler/main/decompiler/BaseDecompiler.java
  6. 6
      src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
  7. 19
      src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
  8. 9
      src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java
  9. 2
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java
  10. 7
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java
  11. 5
      src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java
  12. 5
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java
  13. 5
      src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java
  14. 34
      src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java
  15. 19
      src/org/jetbrains/java/decompiler/modules/renamer/PoolInterceptor.java
  16. 7
      test/org/jetbrains/java/decompiler/DecompilerTestFixture.java

@ -3,7 +3,6 @@ package org.jetbrains.java.decompiler.main;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.collectors.BytecodeSourceMapper;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.main.collectors.ImportCollector;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
@ -28,6 +27,7 @@ import java.util.Map.Entry;
public class ClassesProcessor {
public static final int AVERAGE_CLASS_SIZE = 16 * 1024;
private final StructContext context;
private final Map<String, ClassNode> mapRootClasses = new HashMap<>();
private static class Inner {
@ -41,6 +41,10 @@ public class ClassesProcessor {
}
public ClassesProcessor(StructContext context) {
this.context = context;
}
public void loadClasses(IIdentifierRenamer renamer) {
Map<String, Inner> mapInnerClasses = new HashMap<>();
Map<String, Set<String>> mapNestedClassReferences = new HashMap<>();
Map<String, Set<String>> mapEnclosingClassReferences = new HashMap<>();
@ -64,13 +68,12 @@ public class ClassesProcessor {
if (savedName != null) {
simpleName = savedName;
}
else if (simpleName != null && DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
IIdentifierRenamer renamer = DecompilerContext.getPoolInterceptor().getHelper();
if (renamer.toBeRenamed(IIdentifierRenamer.Type.ELEMENT_CLASS, simpleName, null, null)) {
else if (simpleName != null &&
renamer != null &&
renamer.toBeRenamed(IIdentifierRenamer.Type.ELEMENT_CLASS, simpleName, null, null)) {
simpleName = renamer.getNextClassName(innerName, simpleName);
mapNewSimpleNames.put(innerName, simpleName);
}
}
Inner rec = new Inner();
rec.simpleName = simpleName;
@ -223,9 +226,7 @@ public class ClassesProcessor {
DecompilerContext.getLogger().startReadingClass(cl.qualifiedName);
try {
ImportCollector importCollector = new ImportCollector(root);
DecompilerContext.setImportCollector(importCollector);
DecompilerContext.setCounterContainer(new CounterContainer());
DecompilerContext.setBytecodeSourceMapper(new BytecodeSourceMapper());
DecompilerContext.startClass(importCollector);
new LambdaProcessor().processClass(root);

@ -4,142 +4,142 @@ package org.jetbrains.java.decompiler.main;
import org.jetbrains.java.decompiler.main.collectors.BytecodeSourceMapper;
import org.jetbrains.java.decompiler.main.collectors.CounterContainer;
import org.jetbrains.java.decompiler.main.collectors.ImportCollector;
import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor;
import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor;
import org.jetbrains.java.decompiler.struct.StructContext;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
public class DecompilerContext {
public static final String CURRENT_CLASS = "CURRENT_CLASS";
public static final String CURRENT_CLASS_WRAPPER = "CURRENT_CLASS_WRAPPER";
public static final String CURRENT_CLASS_NODE = "CURRENT_CLASS_NODE";
public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER";
public static final String CURRENT_VAR_PROCESSOR = "CURRENT_VAR_PROCESSOR";
private static final ThreadLocal<DecompilerContext> currentContext = new ThreadLocal<>();
private static volatile DecompilerContext currentContext = null;
private final Map<String, Object> properties;
private StructContext structContext;
private final IFernflowerLogger logger;
private final StructContext structContext;
private final ClassesProcessor classProcessor;
private final PoolInterceptor poolInterceptor;
private ImportCollector importCollector;
private VarNamesCollector varNamescollector;
private VarProcessor varProcessor;
private CounterContainer counterContainer;
private ClassesProcessor classProcessor;
private PoolInterceptor poolInterceptor;
private IFernflowerLogger logger;
private BytecodeSourceMapper bytecodeSourceMapper;
private DecompilerContext(Map<String, Object> properties) {
private DecompilerContext(Map<String, Object> properties,
IFernflowerLogger logger,
StructContext structContext,
ClassesProcessor classProcessor,
PoolInterceptor interceptor) {
this.properties = properties;
}
this.logger = logger;
this.structContext = structContext;
this.classProcessor = classProcessor;
this.poolInterceptor = interceptor;
this.counterContainer = new CounterContainer();
}
// *****************************************************************************
// context setup and update
// *****************************************************************************
public static void initContext(Map<String, Object> customProperties,
IFernflowerLogger logger,
StructContext structContext,
ClassesProcessor classProcessor,
PoolInterceptor interceptor) {
Objects.requireNonNull(logger);
Objects.requireNonNull(structContext);
Objects.requireNonNull(classProcessor);
public static void initContext(Map<String, Object> propertiesCustom) {
Map<String, Object> properties = new HashMap<>(IFernflowerPreferences.DEFAULTS);
if (propertiesCustom != null) {
properties.putAll(propertiesCustom);
}
currentContext.set(new DecompilerContext(properties));
if (customProperties != null) {
properties.putAll(customProperties);
}
public static DecompilerContext getCurrentContext() {
return currentContext.get();
String level = (String)properties.get(IFernflowerPreferences.LOG_LEVEL);
if (level != null) {
try {
logger.setSeverity(IFernflowerLogger.Severity.valueOf(level.toUpperCase(Locale.US)));
}
public static void setCurrentContext(DecompilerContext context) {
currentContext.set(context);
catch (IllegalArgumentException ignore) { }
}
public static Object getProperty(String key) {
return getCurrentContext().properties.get(key);
currentContext = new DecompilerContext(properties, logger, structContext, classProcessor, interceptor);
}
public static void setProperty(String key, Object value) {
getCurrentContext().properties.put(key, value);
public static void clearContext() {
currentContext = null;
}
public static boolean getOption(String key) {
return "1".equals(getCurrentContext().properties.get(key));
public static void setProperty(String key, Object value) {
currentContext.properties.put(key, value);
}
public static ImportCollector getImportCollector() {
return getCurrentContext().importCollector;
public static void startClass(ImportCollector importCollector) {
currentContext.importCollector = importCollector;
currentContext.counterContainer = new CounterContainer();
currentContext.bytecodeSourceMapper = new BytecodeSourceMapper();
}
public static void setImportCollector(ImportCollector importCollector) {
getCurrentContext().importCollector = importCollector;
public static void startMethod(VarProcessor varProcessor) {
currentContext.varProcessor = varProcessor;
currentContext.counterContainer = new CounterContainer();
}
public static VarNamesCollector getVarNamesCollector() {
return getCurrentContext().varNamescollector;
}
// *****************************************************************************
// context access
// *****************************************************************************
public static void setVarNamesCollector(VarNamesCollector varNamesCollector) {
getCurrentContext().varNamescollector = varNamesCollector;
public static Object getProperty(String key) {
return currentContext.properties.get(key);
}
public static StructContext getStructContext() {
return getCurrentContext().structContext;
public static boolean getOption(String key) {
return "1".equals(getProperty(key));
}
public static void setStructContext(StructContext structContext) {
getCurrentContext().structContext = structContext;
public static String getNewLineSeparator() {
return getOption(IFernflowerPreferences.NEW_LINE_SEPARATOR) ?
IFernflowerPreferences.LINE_SEPARATOR_UNX : IFernflowerPreferences.LINE_SEPARATOR_WIN;
}
public static CounterContainer getCounterContainer() {
return getCurrentContext().counterContainer;
public static IFernflowerLogger getLogger() {
return currentContext.logger;
}
public static void setCounterContainer(CounterContainer counterContainer) {
getCurrentContext().counterContainer = counterContainer;
public static StructContext getStructContext() {
return currentContext.structContext;
}
public static ClassesProcessor getClassProcessor() {
return getCurrentContext().classProcessor;
}
public static void setClassProcessor(ClassesProcessor classProcessor) {
getCurrentContext().classProcessor = classProcessor;
return currentContext.classProcessor;
}
public static PoolInterceptor getPoolInterceptor() {
return getCurrentContext().poolInterceptor;
}
public static void setPoolInterceptor(PoolInterceptor poolinterceptor) {
getCurrentContext().poolInterceptor = poolinterceptor;
return currentContext.poolInterceptor;
}
public static BytecodeSourceMapper getBytecodeSourceMapper() {
return getCurrentContext().bytecodeSourceMapper;
}
public static void setBytecodeSourceMapper(BytecodeSourceMapper bytecodeSourceMapper) {
getCurrentContext().bytecodeSourceMapper = bytecodeSourceMapper;
public static ImportCollector getImportCollector() {
return currentContext.importCollector;
}
public static IFernflowerLogger getLogger() {
return getCurrentContext().logger;
public static VarProcessor getVarProcessor() {
return currentContext.varProcessor;
}
public static void setLogger(IFernflowerLogger logger) {
if (logger != null) {
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;
public static CounterContainer getCounterContainer() {
return currentContext.counterContainer;
}
public static String getNewLineSeparator() {
return getOption(IFernflowerPreferences.NEW_LINE_SEPARATOR) ?
IFernflowerPreferences.LINE_SEPARATOR_UNX : IFernflowerPreferences.LINE_SEPARATOR_WIN;
public static BytecodeSourceMapper getBytecodeSourceMapper() {
return currentContext.bytecodeSourceMapper;
}
}

@ -2,12 +2,10 @@
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.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.main.extern.*;
import org.jetbrains.java.decompiler.modules.renamer.ConverterHelper;
import org.jetbrains.java.decompiler.modules.renamer.IdentifierConverter;
import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor;
import org.jetbrains.java.decompiler.struct.IDecompiledData;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructContext;
@ -16,32 +14,50 @@ import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import java.util.Map;
public class Fernflower implements IDecompiledData {
private final StructContext structContext;
private ClassesProcessor classesProcessor;
private final ClassesProcessor classProcessor;
private IIdentifierRenamer helper;
private IdentifierConverter converter;
public Fernflower(IBytecodeProvider provider, IResultSaver saver, Map<String, Object> options, IFernflowerLogger logger) {
structContext = new StructContext(saver, this, new LazyLoader(provider));
DecompilerContext.initContext(options);
DecompilerContext.setCounterContainer(new CounterContainer());
DecompilerContext.setLogger(logger);
classProcessor = new ClassesProcessor(structContext);
PoolInterceptor interceptor = null;
Object rename = options.get(IFernflowerPreferences.RENAME_ENTITIES);
if ("1".equals(rename) || rename == null && "1".equals(IFernflowerPreferences.DEFAULTS.get(IFernflowerPreferences.RENAME_ENTITIES))) {
helper = loadHelper((String)options.get(IFernflowerPreferences.USER_RENAMER_CLASS));
interceptor = new PoolInterceptor();
converter = new IdentifierConverter(structContext, helper, interceptor);
}
public void decompileContext() {
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
new IdentifierConverter().rename(structContext);
DecompilerContext.initContext(options, logger, structContext, classProcessor, interceptor);
}
classesProcessor = new ClassesProcessor(structContext);
public void decompileContext() {
if (converter != null) {
converter.rename();
}
DecompilerContext.setClassProcessor(classesProcessor);
DecompilerContext.setStructContext(structContext);
classProcessor.loadClasses(helper);
structContext.saveContext();
}
private static IIdentifierRenamer loadHelper(String className) {
if (className != null) {
try {
Class<?> renamerClass = Fernflower.class.getClassLoader().loadClass(className);
return (IIdentifierRenamer) renamerClass.getDeclaredConstructor().newInstance();
}
catch (Exception ignored) { }
}
return new ConverterHelper();
}
public void clearContext() {
DecompilerContext.setCurrentContext(null);
DecompilerContext.clearContext();
}
public StructContext getStructContext() {
@ -50,27 +66,25 @@ public class Fernflower implements IDecompiledData {
@Override
public String getClassEntryName(StructClass cl, String entryName) {
ClassNode node = classesProcessor.getMapRootClasses().get(cl.qualifiedName);
ClassNode node = classProcessor.getMapRootClasses().get(cl.qualifiedName);
if (node.type != ClassNode.CLASS_ROOT) {
return null;
}
else {
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
String simple_classname = cl.qualifiedName.substring(cl.qualifiedName.lastIndexOf('/') + 1);
return entryName.substring(0, entryName.lastIndexOf('/') + 1) + simple_classname + ".java";
else if (converter != null) {
String simpleClassName = cl.qualifiedName.substring(cl.qualifiedName.lastIndexOf('/') + 1);
return entryName.substring(0, entryName.lastIndexOf('/') + 1) + simpleClassName + ".java";
}
else {
return entryName.substring(0, entryName.lastIndexOf(".class")) + ".java";
}
}
}
@Override
public String getClassContent(StructClass cl) {
try {
TextBuffer buffer = new TextBuffer(ClassesProcessor.AVERAGE_CLASS_SIZE);
buffer.append(DecompilerContext.getProperty(IFernflowerPreferences.BANNER).toString());
classesProcessor.writeClass(cl, buffer);
classProcessor.writeClass(cl, buffer);
return buffer.toString();
}
catch (Throwable ex) {

@ -2,9 +2,8 @@
package org.jetbrains.java.decompiler.main.collectors;
public class CounterContainer {
public static final int STATEMENT_COUNTER = 0;
public static final int EXPRENT_COUNTER = 1;
public static final int EXPRESSION_COUNTER = 1;
public static final int VAR_COUNTER = 2;
private final int[] values = new int[]{1, 1, 1};

@ -7,18 +7,17 @@ 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;
@SuppressWarnings("unused")
public class BaseDecompiler {
private final Fernflower fernflower;
public BaseDecompiler(IBytecodeProvider provider, IResultSaver saver, Map<String, Object> options, IFernflowerLogger logger) {
fernflower = new Fernflower(provider, saver, options, logger);
}
public void addSpace(File file, boolean isOwn) throws IOException {
public void addSpace(File file, boolean isOwn) {
fernflower.getStructContext().addSpace(file, isOwn);
}

@ -17,7 +17,6 @@ import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver {
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public static void main(String[] args) {
if (args.length < 2) {
@ -102,11 +101,6 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver {
private final Map<String, ZipOutputStream> mapArchiveStreams = new HashMap<>();
private final Map<String, Set<String>> mapArchiveEntries = new HashMap<>();
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public ConsoleDecompiler(File destination, Map<String, Object> options) {
this(destination, options, new PrintStreamLogger(System.out));
}
protected ConsoleDecompiler(File destination, Map<String, Object> options, IFernflowerLogger logger) {
root = destination;
fernflower = new Fernflower(this, this, options, logger);

@ -25,7 +25,6 @@ import java.util.List;
import java.util.Set;
public class ClassWrapper {
private final StructClass classStruct;
private final Set<String> hiddenMembers = new HashSet<>();
private final VBStyleCollection<Exprent, String> staticFieldInitializers = new VBStyleCollection<>();
@ -47,15 +46,12 @@ public class ClassWrapper {
for (StructMethod mt : classStruct.getMethods()) {
DecompilerContext.getLogger().startMethod(mt.getName() + " " + mt.getDescriptor());
VarNamesCollector vc = new VarNamesCollector();
DecompilerContext.setVarNamesCollector(vc);
CounterContainer counter = new CounterContainer();
DecompilerContext.setCounterContainer(counter);
MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
VarProcessor varProc = new VarProcessor(mt, md);
DecompilerContext.setProperty(DecompilerContext.CURRENT_VAR_PROCESSOR, varProc);
DecompilerContext.startMethod(varProc);
VarNamesCollector vc = varProc.getVarNamesCollector();
CounterContainer counter = DecompilerContext.getCounterContainer();
RootStatement root = null;
@ -67,7 +63,7 @@ public class ClassWrapper {
root = MethodProcessorRunnable.codeToJava(mt, md, varProc);
}
else {
MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext.getCurrentContext());
MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc);
Thread mtThread = new Thread(mtProc, "Java decompiler");
long stopAt = System.currentTimeMillis() + maxSec * 1000;
@ -128,9 +124,8 @@ public class ClassWrapper {
}
}
catch (Throwable ex) {
DecompilerContext.getLogger().writeMessage("Method " + mt.getName() + " " + mt.getDescriptor() + " couldn't be decompiled.",
IFernflowerLogger.Severity.WARN,
ex);
String message = "Method " + mt.getName() + " " + mt.getDescriptor() + " couldn't be decompiled.";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN, ex);
isError = true;
}

@ -25,23 +25,19 @@ public class MethodProcessorRunnable implements Runnable {
private final StructMethod method;
private final MethodDescriptor methodDescriptor;
private final VarProcessor varProc;
private final DecompilerContext parentContext;
private volatile RootStatement root;
private volatile Throwable error;
private volatile boolean finished = false;
public MethodProcessorRunnable(StructMethod method, MethodDescriptor methodDescriptor, VarProcessor varProc, DecompilerContext parentContext) {
public MethodProcessorRunnable(StructMethod method, MethodDescriptor methodDescriptor, VarProcessor varProc) {
this.method = method;
this.methodDescriptor = methodDescriptor;
this.varProc = varProc;
this.parentContext = parentContext;
}
@Override
public void run() {
DecompilerContext.setCurrentContext(parentContext);
error = null;
root = null;
@ -54,9 +50,6 @@ public class MethodProcessorRunnable implements Runnable {
catch (Throwable ex) {
error = ex;
}
finally {
DecompilerContext.setCurrentContext(null);
}
finished = true;
synchronized (lock) {

@ -45,7 +45,7 @@ public class Exprent implements IMatchable {
public Exprent(int type) {
this.type = type;
this.id = DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.EXPRENT_COUNTER);
this.id = DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.EXPRESSION_COUNTER);
}
public int getPrecedence() {

@ -10,7 +10,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import java.util.ArrayList;
@ -56,7 +55,7 @@ public class CatchAllStatement extends Statement {
vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER),
new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Throwable"),
(VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR)));
DecompilerContext.getVarProcessor()));
}
@ -165,14 +164,14 @@ public class CatchAllStatement extends Statement {
if (this.monitor != null) {
cas.monitor = new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER),
VarType.VARTYPE_INT,
(VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR));
DecompilerContext.getVarProcessor());
}
if (!this.vars.isEmpty()) {
// FIXME: WTF??? vars?!
vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER),
new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/Throwable"),
(VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR)));
DecompilerContext.getVarProcessor()));
}
return cas;

@ -11,7 +11,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.DecHelper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
import org.jetbrains.java.decompiler.modules.decompiler.StatEdge;
import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor;
import org.jetbrains.java.decompiler.struct.gen.VarType;
import java.util.ArrayList;
@ -49,7 +48,7 @@ public class CatchStatement extends Statement {
vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER),
new VarType(CodeConstants.TYPE_OBJECT, 0, edge.getExceptions().get(0)),
// FIXME: for now simply the first type. Should get the first common superclass when possible.
(VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR)));
DecompilerContext.getVarProcessor()));
}
}
@ -193,7 +192,7 @@ public class CatchStatement extends Statement {
cs.exctstrings.add(new ArrayList<>(exc));
cs.vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER),
new VarType(CodeConstants.TYPE_OBJECT, 0, exc.get(0)),
(VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR)));
DecompilerContext.getVarProcessor()));
}
return cs;

@ -37,7 +37,7 @@ public class VarDefinitionHelper {
this.varproc = varproc;
VarNamesCollector vc = DecompilerContext.getVarNamesCollector();
VarNamesCollector vc = varproc.getVarNamesCollector();
boolean thisvar = !mt.hasModifier(CodeConstants.ACC_STATIC);
@ -108,8 +108,7 @@ public class VarDefinitionHelper {
public void setVarDefinitions() {
VarNamesCollector vc = DecompilerContext.getVarNamesCollector();
VarNamesCollector vc = varproc.getVarNamesCollector();
for (Entry<Integer, Statement> en : mapVarDefStatements.entrySet()) {
Statement stat = en.getValue();

@ -13,6 +13,7 @@ import java.util.*;
import java.util.Map.Entry;
public class VarProcessor {
private final VarNamesCollector varNamesCollector = new VarNamesCollector();
private final StructMethod method;
private final MethodDescriptor methodDescriptor;
private Map<VarVersionPair, String> mapVarNames = new HashMap<>();
@ -85,6 +86,10 @@ public class VarProcessor {
}
}
public VarNamesCollector getVarNamesCollector() {
return varNamesCollector;
}
public VarType getVarType(VarVersionPair pair) {
return varVersions == null ? null : varVersions.getVarType(pair);
}

@ -2,8 +2,6 @@
package org.jetbrains.java.decompiler.modules.renamer;
import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructContext;
@ -18,41 +16,25 @@ import java.io.IOException;
import java.util.*;
public class IdentifierConverter implements NewClassNameBuilder {
private StructContext context;
private IIdentifierRenamer helper;
private PoolInterceptor interceptor;
private final StructContext context;
private final IIdentifierRenamer helper;
private final PoolInterceptor interceptor;
private List<ClassWrapperNode> rootClasses = new ArrayList<>();
private List<ClassWrapperNode> rootInterfaces = new ArrayList<>();
private Map<String, Map<String, String>> interfaceNameMaps = new HashMap<>();
public void rename(StructContext context) {
try {
public IdentifierConverter(StructContext context, IIdentifierRenamer helper, PoolInterceptor interceptor) {
this.context = context;
String user_class = (String)DecompilerContext.getProperty(IFernflowerPreferences.USER_RENAMER_CLASS);
if (user_class != null) {
try {
helper = (IIdentifierRenamer)IdentifierConverter.class.getClassLoader().loadClass(user_class).newInstance();
}
catch (Exception ignored) { }
}
if (helper == null) {
helper = new ConverterHelper();
this.helper = helper;
this.interceptor = interceptor;
}
interceptor = new PoolInterceptor(helper);
public void rename() {
try {
buildInheritanceTree();
renameAllClasses();
renameInterfaces();
renameClasses();
DecompilerContext.setPoolInterceptor(interceptor);
context.reloadContext();
}
catch (IOException ex) {

@ -1,21 +1,12 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.java.decompiler.modules.renamer;
import org.jetbrains.java.decompiler.main.extern.IIdentifierRenamer;
import java.util.HashMap;
import java.util.Map;
public class PoolInterceptor {
private final IIdentifierRenamer helper;
private final HashMap<String, String> mapOldToNewNames = new HashMap<>();
private final HashMap<String, String> mapNewToOldNames = new HashMap<>();
public PoolInterceptor(IIdentifierRenamer helper) {
this.helper = helper;
}
private final Map<String, String> mapOldToNewNames = new HashMap<>();
private final Map<String, String> mapNewToOldNames = new HashMap<>();
public void addName(String oldName, String newName) {
mapOldToNewNames.put(oldName, newName);
@ -29,8 +20,4 @@ public class PoolInterceptor {
public String getOldName(String newName) {
return mapNewToOldNames.get(newName);
}
public IIdentifierRenamer getHelper() {
return helper;
}
}

@ -2,12 +2,15 @@
package org.jetbrains.java.decompiler;
import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler;
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -115,7 +118,7 @@ public class DecompilerTestFixture {
private final HashMap<String, ZipFile> zipFiles = new HashMap<>();
public TestConsoleDecompiler(File destination, Map<String, Object> options) {
super(destination, options);
super(destination, options, new PrintStreamLogger(System.out));
}
@Override

Loading…
Cancel
Save