From 125441a88fc58f74ecfe2c1081a04b6c4d05ea61 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 7 Oct 2014 20:37:21 +0400 Subject: [PATCH] decompiler: move generated lines as it is stated in debug line table (disabled for now) --- .../java/decompiler/main/ClassWriter.java | 37 ++-- .../decompiler/main/ClassesProcessor.java | 4 +- .../java/decompiler/main/Fernflower.java | 6 +- .../java/decompiler/main/TextBuffer.java | 163 ++++++++++++++++++ .../main/collectors/BytecodeSourceMapper.java | 3 +- .../main/collectors/ImportCollector.java | 3 +- .../main/decompiler/ConsoleDecompiler.java | 5 +- .../main/extern/IFernflowerPreferences.java | 2 + .../decompiler/main/extern/IResultSaver.java | 4 +- .../modules/decompiler/ExprProcessor.java | 5 +- .../modules/decompiler/exps/ExitExprent.java | 5 +- .../modules/decompiler/exps/FieldExprent.java | 3 +- .../decompiler/exps/InvocationExprent.java | 3 +- .../modules/decompiler/exps/NewExprent.java | 9 +- .../modules/decompiler/exps/VarExprent.java | 3 +- .../java/decompiler/struct/ContextUnit.java | 7 +- .../decompiler/struct/IDecompiledData.java | 4 +- .../java/decompiler/util/InterpreterUtil.java | 5 +- 18 files changed, 231 insertions(+), 40 deletions(-) create mode 100644 src/org/jetbrains/java/decompiler/main/TextBuffer.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 0383dd4..61507fb 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -76,7 +76,7 @@ public class ClassWriter { } } - public void classLambdaToJava(ClassNode node, StringBuilder buffer, Exprent method_object, int indent) { + public void classLambdaToJava(ClassNode node, TextBuffer buffer, Exprent method_object, int indent) { // get the class node with the content method ClassNode classNode = node; while (classNode != null && classNode.type == ClassNode.CLASS_LAMBDA) { @@ -160,7 +160,7 @@ public class ClassWriter { DecompilerContext.getLogger().endWriteClass(); } - public void classToJava(ClassNode node, StringBuilder buffer, int indent) { + public void classToJava(ClassNode node, TextBuffer buffer, int indent) { ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node); @@ -279,7 +279,7 @@ public class ClassWriter { DecompilerContext.getLogger().endWriteClass(); } - private void writeClassDefinition(ClassNode node, StringBuilder buffer, int indent) { + private void writeClassDefinition(ClassNode node, TextBuffer buffer, int indent) { String lineSeparator = DecompilerContext.getNewLineSeparator(); String indentString = InterpreterUtil.getIndentString(indent); @@ -390,7 +390,7 @@ public class ClassWriter { buffer.append(lineSeparator); } - private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, StringBuilder buffer, int indent, BytecodeMappingTracer tracer) { + private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { String indentString = InterpreterUtil.getIndentString(indent); String lineSeparator = DecompilerContext.getNewLineSeparator(); @@ -479,7 +479,7 @@ public class ClassWriter { private static void methodLambdaToJava(ClassNode lambdaNode, ClassNode classNode, StructMethod mt, - StringBuilder buffer, + TextBuffer buffer, int indent, boolean codeOnly, BytecodeMappingTracer tracer) { ClassWrapper classWrapper = classNode.wrapper; @@ -565,7 +565,7 @@ public class ClassWriter { } } - private boolean methodToJava(ClassNode node, StructMethod mt, StringBuilder buffer, int indent, BytecodeMappingTracer tracer) { + private boolean methodToJava(ClassNode node, StructMethod mt, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { ClassWrapper wrapper = node.wrapper; StructClass cl = wrapper.getClassStruct(); MethodWrapper methodWrapper = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()); @@ -586,6 +586,15 @@ public class ClassWriter { boolean isDeprecated = mt.getAttributes().containsKey("Deprecated"); boolean clinit = false, init = false, dinit = false; + int startLine = -1; + if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_LINE_NUMBERS)) { + StructLineNumberTableAttribute lineNumberTable = + (StructLineNumberTableAttribute)mt.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); + if (lineNumberTable != null) { + startLine = lineNumberTable.getFirstLine(); + } + } + MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); int flags = mt.getAccessFlags(); @@ -800,6 +809,8 @@ public class ClassWriter { buffer.append(' '); } + //TODO: for now only start line set + buffer.setCurrentLine(startLine); buffer.append('{'); buffer.append(lineSeparator); @@ -861,13 +872,13 @@ public class ClassWriter { return true; } - private static void appendDeprecation(StringBuilder buffer, String indentString, String lineSeparator) { + private static void appendDeprecation(TextBuffer buffer, String indentString, String lineSeparator) { buffer.append(indentString).append("/** @deprecated */").append(lineSeparator); } private enum MType {CLASS, FIELD, METHOD} - private static void appendRenameComment(StringBuilder buffer, String oldName, MType type, int indent, String lineSeparator) { + private static void appendRenameComment(TextBuffer buffer, String oldName, MType type, int indent, String lineSeparator) { if (oldName == null) return; InterpreterUtil.appendIndent(buffer, indent); @@ -915,14 +926,14 @@ public class ClassWriter { return typeText; } - private static void appendComment(StringBuilder buffer, String comment, String indentString, String lineSeparator) { + private static void appendComment(TextBuffer buffer, String comment, String indentString, String lineSeparator) { buffer.append(indentString).append("// $FF: ").append(comment).append(lineSeparator); } private static final String[] ANNOTATION_ATTRIBUTES = { StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS}; - private static void appendAnnotations(StringBuilder buffer, StructMember mb, int indent, String lineSeparator) { + private static void appendAnnotations(TextBuffer buffer, StructMember mb, int indent, String lineSeparator) { BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one @@ -939,7 +950,7 @@ public class ClassWriter { private static final String[] PARAMETER_ANNOTATION_ATTRIBUTES = { StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; - private static void appendParameterAnnotations(StringBuilder buffer, StructMethod mt, int param) { + private static void appendParameterAnnotations(TextBuffer buffer, StructMethod mt, int param) { BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one @@ -984,7 +995,7 @@ public class ClassWriter { private static final int FIELD_EXCLUDED = CodeConstants.ACC_PUBLIC | CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL; private static final int METHOD_EXCLUDED = CodeConstants.ACC_PUBLIC | CodeConstants.ACC_ABSTRACT; - private static void appendModifiers(StringBuilder buffer, int flags, int allowed, boolean isInterface, int excluded) { + private static void appendModifiers(TextBuffer buffer, int flags, int allowed, boolean isInterface, int excluded) { flags &= allowed; if (!isInterface) excluded = 0; for (int modifier : MODIFIERS.keySet()) { @@ -994,7 +1005,7 @@ public class ClassWriter { } } - private static void appendTypeParameters(StringBuilder buffer, List parameters, List> bounds) { + private static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { buffer.append('<'); for (int i = 0; i < parameters.size(); i++) { diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index c79e355..42f4719 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -236,7 +236,7 @@ public class ClassesProcessor { } } - public void writeClass(StructClass cl, StringBuilder buffer) throws IOException { + public void writeClass(StructClass cl, TextBuffer buffer) throws IOException { ClassNode root = mapRootClasses.get(cl.qualifiedName); if (root.type != ClassNode.CLASS_ROOT) { return; @@ -260,7 +260,7 @@ public class ClassesProcessor { new NestedMemberAccess().propagateMemberAccess(root); - StringBuilder classBuffer = new StringBuilder(AVERAGE_CLASS_SIZE); + TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE); new ClassWriter().classToJava(root, classBuffer, 0); String lineSeparator = DecompilerContext.getNewLineSeparator(); diff --git a/src/org/jetbrains/java/decompiler/main/Fernflower.java b/src/org/jetbrains/java/decompiler/main/Fernflower.java index 324a394..4988bc0 100644 --- a/src/org/jetbrains/java/decompiler/main/Fernflower.java +++ b/src/org/jetbrains/java/decompiler/main/Fernflower.java @@ -80,11 +80,11 @@ public class Fernflower implements IDecompiledData { } @Override - public String getClassContent(StructClass cl) { + public TextBuffer getClassContent(StructClass cl) { try { - StringBuilder buffer = new StringBuilder(ClassesProcessor.AVERAGE_CLASS_SIZE); + TextBuffer buffer = new TextBuffer(ClassesProcessor.AVERAGE_CLASS_SIZE); classesProcessor.writeClass(cl, buffer); - return buffer.toString(); + return buffer; } catch (Throwable ex) { DecompilerContext.getLogger().writeMessage("Class " + cl.qualifiedName + " couldn't be fully decompiled.", ex); diff --git a/src/org/jetbrains/java/decompiler/main/TextBuffer.java b/src/org/jetbrains/java/decompiler/main/TextBuffer.java new file mode 100644 index 0000000..6d279bf --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/TextBuffer.java @@ -0,0 +1,163 @@ +/* + * 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; + +import java.util.*; + +/** + * Allows to connect text with resulting lines + * + * @author egor + */ +public class TextBuffer { + private final String myLineSeparator = DecompilerContext.getNewLineSeparator(); + private final StringBuilder myStringBuilder; + private Map myLineToOffsetMapping = null; + + public TextBuffer() { + myStringBuilder = new StringBuilder(); + } + + public TextBuffer(int size) { + myStringBuilder = new StringBuilder(size); + } + + public void setCurrentLine(int line) { + if (line >= 0) { + checkMapCreated(); + myLineToOffsetMapping.put(line, myStringBuilder.length()+1); + } + } + + public TextBuffer append(String str) { + myStringBuilder.append(str); + return this; + } + + public TextBuffer append(char ch) { + myStringBuilder.append(ch); + return this; + } + + public TextBuffer appendLineSeparator() { + myStringBuilder.append(myLineSeparator); + return this; + } + + public void addBanner(String banner) { + myStringBuilder.insert(0, banner); + if (myLineToOffsetMapping != null) { + for (Integer line : myLineToOffsetMapping.keySet()) { + myLineToOffsetMapping.put(line, myLineToOffsetMapping.get(line) + banner.length()); + } + } + } + + @Override + public String toString() { + String original = myStringBuilder.toString(); + if (myLineToOffsetMapping == null || myLineToOffsetMapping.isEmpty()) { + return original; + } + else { + StringBuilder res = new StringBuilder(); + String[] srcLines = original.split(myLineSeparator); + int currentLineStartOffset = 0; + int currentLine = 0; + int previousMarkLine = 0; + int dumpedLines = 0; + ArrayList linesWithMarks = new ArrayList(myLineToOffsetMapping.keySet()); + Collections.sort(linesWithMarks); + for (Integer markLine : linesWithMarks) { + Integer markOffset = myLineToOffsetMapping.get(markLine); + while (currentLine < srcLines.length) { + String line = srcLines[currentLine]; + int lineEnd = currentLineStartOffset + line.length() + myLineSeparator.length(); + if (markOffset >= currentLineStartOffset && markOffset <= lineEnd) { + int requiredLinesNumber = markLine - dumpedLines; + dumpedLines = markLine; + appendLines(res, srcLines, previousMarkLine, currentLine, requiredLinesNumber); + previousMarkLine = currentLine; + break; + } + currentLineStartOffset = lineEnd; + currentLine++; + } + } + if (previousMarkLine < srcLines.length) { + appendLines(res, srcLines, previousMarkLine, srcLines.length, srcLines.length - previousMarkLine); + } + + return res.toString(); + } + } + + private void appendLines(StringBuilder res, String[] srcLines, int from, int to, int requiredLineNumber) { + if (to - from > requiredLineNumber) { + int separatorsRequired = to - from - requiredLineNumber - 1; + for (int i = from; i < to; i++) { + res.append(srcLines[i]); + if (separatorsRequired-- > 0) { + res.append(myLineSeparator); + } + } + res.append(myLineSeparator); + } + else if (to - from <= requiredLineNumber) { + for (int i = from; i < to; i++) { + res.append(srcLines[i]).append(myLineSeparator); + } + for (int i = 0; i < requiredLineNumber - to + from; i++) { + res.append(myLineSeparator); + } + } + } + + public int length() { + return myStringBuilder.length(); + } + + public String substring(int start) { + return myStringBuilder.substring(start); + } + + public void setLength(int position) { + myStringBuilder.setLength(position); + } + + public void append(TextBuffer buffer) { + if (buffer.myLineToOffsetMapping != null && !buffer.myLineToOffsetMapping.isEmpty()) { + checkMapCreated(); + for (Map.Entry entry : buffer.myLineToOffsetMapping.entrySet()) { + myLineToOffsetMapping.put(entry.getKey(), entry.getValue() + myStringBuilder.length()); + } + } + myStringBuilder.append(buffer.myStringBuilder); + } + + private void checkMapCreated() { + if (myLineToOffsetMapping == null) { + myLineToOffsetMapping = new HashMap(); + } + } + + public void insert(int offset, String s) { + if (myLineToOffsetMapping != null) { + throw new IllegalStateException("insert not yet supported with Line mapping"); + } + myStringBuilder.insert(offset, s); + } +} diff --git a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java index 53f92b2..36c8ac8 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map.Entry; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.util.InterpreterUtil; public class BytecodeSourceMapper { @@ -37,7 +38,7 @@ public class BytecodeSourceMapper { } } - public void dumpMapping(StringBuilder buffer) { + public void dumpMapping(TextBuffer buffer) { String lineSeparator = DecompilerContext.getNewLineSeparator(); String indentstr1 = InterpreterUtil.getIndentString(1); diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index bd5e011..c66a3e0 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.main.collectors; import org.jetbrains.java.decompiler.main.ClassesProcessor; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.struct.StructContext; import java.util.*; @@ -107,7 +108,7 @@ public class ImportCollector { return retname == null ? nshort : retname; } - public int writeImports(StringBuilder buffer) { + public int writeImports(TextBuffer buffer) { int importlines_written = 0; String new_line_separator = DecompilerContext.getNewLineSeparator(); diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java index a486d9f..43cfafb 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java @@ -17,6 +17,7 @@ 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.TextBuffer; import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IResultSaver; @@ -181,12 +182,12 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { } @Override - public void saveClassFile(String path, String qualifiedName, String entryName, String content) { + public void saveClassFile(String path, String qualifiedName, String entryName, TextBuffer content) { File file = new File(getAbsolutePath(path), entryName); try { Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8"); try { - out.write(content); + out.write(content.toString()); } finally { out.close(); diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java index ce81e3c..b5f6ac0 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java @@ -45,6 +45,7 @@ public interface IFernflowerPreferences { String LAMBDA_TO_ANONYMOUS_CLASS = "lac"; String BYTECODE_SOURCE_MAPPING = "bsm"; + String USE_DEBUG_LINE_NUMBERS = "udl"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; @@ -80,6 +81,7 @@ public interface IFernflowerPreferences { put(LAMBDA_TO_ANONYMOUS_CLASS, "0"); put(BYTECODE_SOURCE_MAPPING, "0"); + put(USE_DEBUG_LINE_NUMBERS, "0"); put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); put(MAX_PROCESSING_METHOD, "0"); diff --git a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java b/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java index 1e6a7d4..5b4b7e0 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IResultSaver.java @@ -15,6 +15,8 @@ */ package org.jetbrains.java.decompiler.main.extern; +import org.jetbrains.java.decompiler.main.TextBuffer; + import java.util.jar.Manifest; public interface IResultSaver { @@ -22,7 +24,7 @@ public interface IResultSaver { void copyFile(String source, String path, String entryName); - void saveClassFile(String path, String qualifiedName, String entryName, String content); + void saveClassFile(String path, String qualifiedName, String entryName, TextBuffer content); void createArchive(String path, String archiveName, Manifest manifest); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index dc28485..e283fdf 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -20,6 +20,7 @@ import org.jetbrains.java.decompiler.code.Instruction; import org.jetbrains.java.decompiler.code.InstructionSequence; import org.jetbrains.java.decompiler.code.cfg.BasicBlock; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.modules.decompiler.exps.*; import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; @@ -857,14 +858,14 @@ public class ExprProcessor implements CodeConstants { return defaultval; } - public static boolean getCastedExprent(Exprent exprent, VarType leftType, StringBuilder buffer, int indent, + public static boolean getCastedExprent(Exprent exprent, VarType leftType, TextBuffer buffer, int indent, boolean castNull, BytecodeMappingTracer tracer) { return getCastedExprent(exprent, leftType, buffer, indent, castNull, false, tracer); } public static boolean getCastedExprent(Exprent exprent, VarType leftType, - StringBuilder buffer, + TextBuffer buffer, int indent, boolean castNull, boolean castAlways, BytecodeMappingTracer tracer) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java index e03bc8d..e54b365 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -81,7 +82,7 @@ public class ExitExprent extends Exprent { tracer.addMapping(bytecode); if (exittype == EXIT_RETURN) { - StringBuilder buffer = new StringBuilder(); + TextBuffer buffer = new TextBuffer(); if (rettype.type != CodeConstants.TYPE_VOID) { buffer.append(" "); @@ -115,7 +116,7 @@ public class ExitExprent extends Exprent { if (classname != null) { VarType exctype = new VarType(classname, true); - StringBuilder buffer = new StringBuilder(); + TextBuffer buffer = new TextBuffer(); ExprProcessor.getCastedExprent(value, exctype, buffer, indent, false, tracer); return "throw " + buffer.toString(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java index ce7d72f..e51615d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -137,7 +138,7 @@ public class FieldExprent extends Exprent { buf.append("super"); } else { - StringBuilder buff = new StringBuilder(); + TextBuffer buff = new TextBuffer(); boolean casted = ExprProcessor.getCastedExprent(instance, new VarType(CodeConstants.TYPE_OBJECT, 0, classname), buff, indent, true, tracer); String res = buff.toString(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index e782b23..92d549e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; @@ -360,7 +361,7 @@ public class InvocationExprent extends Exprent { buf.append(", "); } - StringBuilder buff = new StringBuilder(); + TextBuffer buff = new TextBuffer(); ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, setAmbiguousParameters.contains(i), tracer); buf.append(buff); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index 8395a3d..5006d30 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassWriter; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -172,7 +173,7 @@ public class NewExprent extends Exprent { @Override public String toJava(int indent, BytecodeMappingTracer tracer) { - StringBuilder buf = new StringBuilder(); + TextBuffer buf = new TextBuffer(); if (anonymous) { @@ -220,7 +221,7 @@ public class NewExprent extends Exprent { } } - StringBuilder buff = new StringBuilder(); + TextBuffer buff = new TextBuffer(); ExprProcessor.getCastedExprent(param, invsuper.getDescriptor().params[i], buff, indent, true, tracer); buf.append(buff); @@ -317,7 +318,7 @@ public class NewExprent extends Exprent { buf.append(", "); } - StringBuilder buff = new StringBuilder(); + TextBuffer buff = new TextBuffer(); ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buff, indent, true, tracer); buf.append(buff); @@ -373,7 +374,7 @@ public class NewExprent extends Exprent { if (i > 0) { buf.append(", "); } - StringBuilder buff = new StringBuilder(); + TextBuffer buff = new TextBuffer(); ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buff, indent, false, tracer); buf.append(buff); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java index 16eba3a..16e6c64 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassWriter; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; @@ -83,7 +84,7 @@ public class VarExprent extends Exprent { @Override public String toJava(int indent, BytecodeMappingTracer tracer) { - StringBuilder buffer = new StringBuilder(); + TextBuffer buffer = new TextBuffer(); tracer.addMapping(bytecode); diff --git a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java index 819ae64..dd68544 100644 --- a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java +++ b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java @@ -15,6 +15,7 @@ */ package org.jetbrains.java.decompiler.struct; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.extern.IResultSaver; import org.jetbrains.java.decompiler.struct.lazy.LazyLoader; import org.jetbrains.java.decompiler.struct.lazy.LazyLoader.Link; @@ -110,7 +111,7 @@ public class ContextUnit { StructClass cl = classes.get(i); String entryName = decompiledData.getClassEntryName(cl, classEntries.get(i)); if (entryName != null) { - String content = decompiledData.getClassContent(cl); + TextBuffer content = decompiledData.getClassContent(cl); if (content != null) { resultSaver.saveClassFile(filename, cl.qualifiedName, entryName, content); } @@ -142,8 +143,8 @@ public class ContextUnit { StructClass cl = classes.get(i); String entryName = decompiledData.getClassEntryName(cl, classEntries.get(i)); if (entryName != null) { - String content = decompiledData.getClassContent(cl); - resultSaver.saveClassEntry(archivePath, filename, cl.qualifiedName, entryName, content); + TextBuffer content = decompiledData.getClassContent(cl); + resultSaver.saveClassEntry(archivePath, filename, cl.qualifiedName, entryName, content.toString()); } } diff --git a/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java b/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java index f309b0e..25f1f88 100644 --- a/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java +++ b/src/org/jetbrains/java/decompiler/struct/IDecompiledData.java @@ -15,9 +15,11 @@ */ package org.jetbrains.java.decompiler.struct; +import org.jetbrains.java.decompiler.main.TextBuffer; + public interface IDecompiledData { String getClassEntryName(StructClass cl, String entryname); - String getClassContent(StructClass cl); + TextBuffer getClassContent(StructClass cl); } diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java index eaada90..50411bc 100644 --- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -16,6 +16,7 @@ package org.jetbrains.java.decompiler.util; import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import java.io.*; @@ -91,12 +92,12 @@ public class InterpreterUtil { public static String getIndentString(int length) { if (length == 0) return ""; - StringBuilder buf = new StringBuilder(); + TextBuffer buf = new TextBuffer(); appendIndent(buf, length); return buf.toString(); } - public static void appendIndent(StringBuilder buffer, int length) { + public static void appendIndent(TextBuffer buffer, int length) { if (length == 0) return; String indent = (String)DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING); while (length-- > 0) {