|
|
@ -302,55 +302,65 @@ public class ClassesProcessor implements CodeConstants { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean packageInfo = cl.isSynthetic() && "package-info".equals(root.simpleName); |
|
|
|
|
|
|
|
boolean moduleInfo = cl.hasModifier(CodeConstants.ACC_MODULE) && cl.hasAttribute(StructGeneralAttribute.ATTRIBUTE_MODULE); |
|
|
|
|
|
|
|
|
|
|
|
DecompilerContext.getLogger().startReadingClass(cl.qualifiedName); |
|
|
|
DecompilerContext.getLogger().startReadingClass(cl.qualifiedName); |
|
|
|
try { |
|
|
|
try { |
|
|
|
ImportCollector importCollector = new ImportCollector(root); |
|
|
|
ImportCollector importCollector = new ImportCollector(root); |
|
|
|
DecompilerContext.startClass(importCollector); |
|
|
|
DecompilerContext.startClass(importCollector); |
|
|
|
|
|
|
|
|
|
|
|
new LambdaProcessor().processClass(root); |
|
|
|
if (packageInfo) { |
|
|
|
|
|
|
|
ClassWriter.packageInfoToJava(cl, buffer); |
|
|
|
|
|
|
|
|
|
|
|
// add simple class names to implicit import
|
|
|
|
importCollector.writeImports(buffer, false); |
|
|
|
addClassnameToImport(root, importCollector); |
|
|
|
} |
|
|
|
|
|
|
|
else if (moduleInfo) { |
|
|
|
|
|
|
|
TextBuffer moduleBuffer = new TextBuffer(AVERAGE_CLASS_SIZE); |
|
|
|
|
|
|
|
ClassWriter.moduleInfoToJava(cl, moduleBuffer); |
|
|
|
|
|
|
|
|
|
|
|
// build wrappers for all nested classes (that's where actual processing takes place)
|
|
|
|
importCollector.writeImports(buffer, true); |
|
|
|
initWrappers(root); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new NestedClassProcessor().processClass(root, root); |
|
|
|
buffer.append(moduleBuffer); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
new LambdaProcessor().processClass(root); |
|
|
|
|
|
|
|
|
|
|
|
new NestedMemberAccess().propagateMemberAccess(root); |
|
|
|
// add simple class names to implicit import
|
|
|
|
|
|
|
|
addClassNameToImport(root, importCollector); |
|
|
|
|
|
|
|
|
|
|
|
TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE); |
|
|
|
// build wrappers for all nested classes (that's where actual processing takes place)
|
|
|
|
new ClassWriter().classToJava(root, classBuffer, 0, null); |
|
|
|
initWrappers(root); |
|
|
|
|
|
|
|
|
|
|
|
int index = cl.qualifiedName.lastIndexOf("/"); |
|
|
|
new NestedClassProcessor().processClass(root, root); |
|
|
|
if (index >= 0) { |
|
|
|
|
|
|
|
String packageName = cl.qualifiedName.substring(0, index).replace('/', '.'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buffer.append("package "); |
|
|
|
new NestedMemberAccess().propagateMemberAccess(root); |
|
|
|
buffer.append(packageName); |
|
|
|
|
|
|
|
buffer.append(";"); |
|
|
|
|
|
|
|
buffer.appendLineSeparator(); |
|
|
|
|
|
|
|
buffer.appendLineSeparator(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int import_lines_written = importCollector.writeImports(buffer); |
|
|
|
TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE); |
|
|
|
if (import_lines_written > 0) { |
|
|
|
new ClassWriter().classToJava(root, classBuffer, 0, null); |
|
|
|
buffer.appendLineSeparator(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int offsetLines = buffer.countLines(); |
|
|
|
int index = cl.qualifiedName.lastIndexOf('/'); |
|
|
|
|
|
|
|
if (index >= 0) { |
|
|
|
|
|
|
|
String packageName = cl.qualifiedName.substring(0, index).replace('/', '.'); |
|
|
|
|
|
|
|
buffer.append("package ").append(packageName).append(';').appendLineSeparator().appendLineSeparator(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
buffer.append(classBuffer); |
|
|
|
importCollector.writeImports(buffer, true); |
|
|
|
|
|
|
|
|
|
|
|
if (DecompilerContext.getOption(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING)) { |
|
|
|
int offsetLines = buffer.countLines(); |
|
|
|
BytecodeSourceMapper mapper = DecompilerContext.getBytecodeSourceMapper(); |
|
|
|
|
|
|
|
mapper.addTotalOffset(offsetLines); |
|
|
|
buffer.append(classBuffer); |
|
|
|
if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_ORIGINAL_LINES)) { |
|
|
|
|
|
|
|
buffer.dumpOriginalLineNumbers(mapper.getOriginalLinesMapping()); |
|
|
|
if (DecompilerContext.getOption(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING)) { |
|
|
|
} |
|
|
|
BytecodeSourceMapper mapper = DecompilerContext.getBytecodeSourceMapper(); |
|
|
|
if (DecompilerContext.getOption(IFernflowerPreferences.UNIT_TEST_MODE)) { |
|
|
|
mapper.addTotalOffset(offsetLines); |
|
|
|
buffer.appendLineSeparator(); |
|
|
|
if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_ORIGINAL_LINES)) { |
|
|
|
mapper.dumpMapping(buffer, true); |
|
|
|
buffer.dumpOriginalLineNumbers(mapper.getOriginalLinesMapping()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (DecompilerContext.getOption(IFernflowerPreferences.UNIT_TEST_MODE)) { |
|
|
|
|
|
|
|
buffer.appendLineSeparator(); |
|
|
|
|
|
|
|
mapper.dumpMapping(buffer, true); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -375,13 +385,13 @@ public class ClassesProcessor implements CodeConstants { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void addClassnameToImport(ClassNode node, ImportCollector imp) { |
|
|
|
private static void addClassNameToImport(ClassNode node, ImportCollector imp) { |
|
|
|
if (node.simpleName != null && node.simpleName.length() > 0) { |
|
|
|
if (node.simpleName != null && node.simpleName.length() > 0) { |
|
|
|
imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false); |
|
|
|
imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (ClassNode nd : node.nested) { |
|
|
|
for (ClassNode nd : node.nested) { |
|
|
|
addClassnameToImport(nd, imp); |
|
|
|
addClassNameToImport(nd, imp); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|