decompiler: move generated lines as it is stated in debug line table (disabled for now)

This commit is contained in:
Egor.Ushakov 2014-10-07 20:37:21 +04:00
parent 9f9da912f6
commit 125441a88f
18 changed files with 231 additions and 40 deletions

View File

@ -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 // get the class node with the content method
ClassNode classNode = node; ClassNode classNode = node;
while (classNode != null && classNode.type == ClassNode.CLASS_LAMBDA) { while (classNode != null && classNode.type == ClassNode.CLASS_LAMBDA) {
@ -160,7 +160,7 @@ public class ClassWriter {
DecompilerContext.getLogger().endWriteClass(); 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); ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE);
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node); DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node);
@ -279,7 +279,7 @@ public class ClassWriter {
DecompilerContext.getLogger().endWriteClass(); 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 lineSeparator = DecompilerContext.getNewLineSeparator();
String indentString = InterpreterUtil.getIndentString(indent); String indentString = InterpreterUtil.getIndentString(indent);
@ -390,7 +390,7 @@ public class ClassWriter {
buffer.append(lineSeparator); 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 indentString = InterpreterUtil.getIndentString(indent);
String lineSeparator = DecompilerContext.getNewLineSeparator(); String lineSeparator = DecompilerContext.getNewLineSeparator();
@ -479,7 +479,7 @@ public class ClassWriter {
private static void methodLambdaToJava(ClassNode lambdaNode, private static void methodLambdaToJava(ClassNode lambdaNode,
ClassNode classNode, ClassNode classNode,
StructMethod mt, StructMethod mt,
StringBuilder buffer, TextBuffer buffer,
int indent, int indent,
boolean codeOnly, BytecodeMappingTracer tracer) { boolean codeOnly, BytecodeMappingTracer tracer) {
ClassWrapper classWrapper = classNode.wrapper; 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; ClassWrapper wrapper = node.wrapper;
StructClass cl = wrapper.getClassStruct(); StructClass cl = wrapper.getClassStruct();
MethodWrapper methodWrapper = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor()); MethodWrapper methodWrapper = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor());
@ -586,6 +586,15 @@ public class ClassWriter {
boolean isDeprecated = mt.getAttributes().containsKey("Deprecated"); boolean isDeprecated = mt.getAttributes().containsKey("Deprecated");
boolean clinit = false, init = false, dinit = false; 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()); MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor());
int flags = mt.getAccessFlags(); int flags = mt.getAccessFlags();
@ -800,6 +809,8 @@ public class ClassWriter {
buffer.append(' '); buffer.append(' ');
} }
//TODO: for now only start line set
buffer.setCurrentLine(startLine);
buffer.append('{'); buffer.append('{');
buffer.append(lineSeparator); buffer.append(lineSeparator);
@ -861,13 +872,13 @@ public class ClassWriter {
return true; 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); buffer.append(indentString).append("/** @deprecated */").append(lineSeparator);
} }
private enum MType {CLASS, FIELD, METHOD} 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; if (oldName == null) return;
InterpreterUtil.appendIndent(buffer, indent); InterpreterUtil.appendIndent(buffer, indent);
@ -915,14 +926,14 @@ public class ClassWriter {
return typeText; 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); buffer.append(indentString).append("// $FF: ").append(comment).append(lineSeparator);
} }
private static final String[] ANNOTATION_ATTRIBUTES = { private static final String[] ANNOTATION_ATTRIBUTES = {
StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS}; 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 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 = { private static final String[] PARAMETER_ANNOTATION_ATTRIBUTES = {
StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; 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 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 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 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; flags &= allowed;
if (!isInterface) excluded = 0; if (!isInterface) excluded = 0;
for (int modifier : MODIFIERS.keySet()) { for (int modifier : MODIFIERS.keySet()) {
@ -994,7 +1005,7 @@ public class ClassWriter {
} }
} }
private static void appendTypeParameters(StringBuilder buffer, List<String> parameters, List<List<GenericType>> bounds) { private static void appendTypeParameters(TextBuffer buffer, List<String> parameters, List<List<GenericType>> bounds) {
buffer.append('<'); buffer.append('<');
for (int i = 0; i < parameters.size(); i++) { for (int i = 0; i < parameters.size(); i++) {

View File

@ -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); ClassNode root = mapRootClasses.get(cl.qualifiedName);
if (root.type != ClassNode.CLASS_ROOT) { if (root.type != ClassNode.CLASS_ROOT) {
return; return;
@ -260,7 +260,7 @@ public class ClassesProcessor {
new NestedMemberAccess().propagateMemberAccess(root); new NestedMemberAccess().propagateMemberAccess(root);
StringBuilder classBuffer = new StringBuilder(AVERAGE_CLASS_SIZE); TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE);
new ClassWriter().classToJava(root, classBuffer, 0); new ClassWriter().classToJava(root, classBuffer, 0);
String lineSeparator = DecompilerContext.getNewLineSeparator(); String lineSeparator = DecompilerContext.getNewLineSeparator();

View File

@ -80,11 +80,11 @@ public class Fernflower implements IDecompiledData {
} }
@Override @Override
public String getClassContent(StructClass cl) { public TextBuffer getClassContent(StructClass cl) {
try { try {
StringBuilder buffer = new StringBuilder(ClassesProcessor.AVERAGE_CLASS_SIZE); TextBuffer buffer = new TextBuffer(ClassesProcessor.AVERAGE_CLASS_SIZE);
classesProcessor.writeClass(cl, buffer); classesProcessor.writeClass(cl, buffer);
return buffer.toString(); return buffer;
} }
catch (Throwable ex) { catch (Throwable ex) {
DecompilerContext.getLogger().writeMessage("Class " + cl.qualifiedName + " couldn't be fully decompiled.", ex); DecompilerContext.getLogger().writeMessage("Class " + cl.qualifiedName + " couldn't be fully decompiled.", ex);

View File

@ -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<Integer, Integer> 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<Integer> linesWithMarks = new ArrayList<Integer>(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<Integer, Integer> 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<Integer, Integer>();
}
}
public void insert(int offset, String s) {
if (myLineToOffsetMapping != null) {
throw new IllegalStateException("insert not yet supported with Line mapping");
}
myStringBuilder.insert(offset, s);
}
}

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.InterpreterUtil;
public class BytecodeSourceMapper { 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 lineSeparator = DecompilerContext.getNewLineSeparator();
String indentstr1 = InterpreterUtil.getIndentString(1); String indentstr1 = InterpreterUtil.getIndentString(1);

View File

@ -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;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.struct.StructContext; import org.jetbrains.java.decompiler.struct.StructContext;
import java.util.*; import java.util.*;
@ -107,7 +108,7 @@ public class ImportCollector {
return retname == null ? nshort : retname; return retname == null ? nshort : retname;
} }
public int writeImports(StringBuilder buffer) { public int writeImports(TextBuffer buffer) {
int importlines_written = 0; int importlines_written = 0;
String new_line_separator = DecompilerContext.getNewLineSeparator(); String new_line_separator = DecompilerContext.getNewLineSeparator();

View File

@ -17,6 +17,7 @@ package org.jetbrains.java.decompiler.main.decompiler;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.Fernflower; 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.IBytecodeProvider;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IResultSaver; import org.jetbrains.java.decompiler.main.extern.IResultSaver;
@ -181,12 +182,12 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver {
} }
@Override @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); File file = new File(getAbsolutePath(path), entryName);
try { try {
Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8"); Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8");
try { try {
out.write(content); out.write(content.toString());
} }
finally { finally {
out.close(); out.close();

View File

@ -45,6 +45,7 @@ public interface IFernflowerPreferences {
String LAMBDA_TO_ANONYMOUS_CLASS = "lac"; String LAMBDA_TO_ANONYMOUS_CLASS = "lac";
String BYTECODE_SOURCE_MAPPING = "bsm"; String BYTECODE_SOURCE_MAPPING = "bsm";
String USE_DEBUG_LINE_NUMBERS = "udl";
String LOG_LEVEL = "log"; String LOG_LEVEL = "log";
String MAX_PROCESSING_METHOD = "mpm"; String MAX_PROCESSING_METHOD = "mpm";
@ -80,6 +81,7 @@ public interface IFernflowerPreferences {
put(LAMBDA_TO_ANONYMOUS_CLASS, "0"); put(LAMBDA_TO_ANONYMOUS_CLASS, "0");
put(BYTECODE_SOURCE_MAPPING, "0"); put(BYTECODE_SOURCE_MAPPING, "0");
put(USE_DEBUG_LINE_NUMBERS, "0");
put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name());
put(MAX_PROCESSING_METHOD, "0"); put(MAX_PROCESSING_METHOD, "0");

View File

@ -15,6 +15,8 @@
*/ */
package org.jetbrains.java.decompiler.main.extern; package org.jetbrains.java.decompiler.main.extern;
import org.jetbrains.java.decompiler.main.TextBuffer;
import java.util.jar.Manifest; import java.util.jar.Manifest;
public interface IResultSaver { public interface IResultSaver {
@ -22,7 +24,7 @@ public interface IResultSaver {
void copyFile(String source, String path, String entryName); 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); void createArchive(String path, String archiveName, Manifest manifest);

View File

@ -20,6 +20,7 @@ import org.jetbrains.java.decompiler.code.Instruction;
import org.jetbrains.java.decompiler.code.InstructionSequence; import org.jetbrains.java.decompiler.code.InstructionSequence;
import org.jetbrains.java.decompiler.code.cfg.BasicBlock; import org.jetbrains.java.decompiler.code.cfg.BasicBlock;
import org.jetbrains.java.decompiler.main.DecompilerContext; 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.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.modules.decompiler.exps.*; import org.jetbrains.java.decompiler.modules.decompiler.exps.*;
import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph; import org.jetbrains.java.decompiler.modules.decompiler.sforms.DirectGraph;
@ -857,14 +858,14 @@ public class ExprProcessor implements CodeConstants {
return defaultval; 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) { boolean castNull, BytecodeMappingTracer tracer) {
return getCastedExprent(exprent, leftType, buffer, indent, castNull, false, tracer); return getCastedExprent(exprent, leftType, buffer, indent, castNull, false, tracer);
} }
public static boolean getCastedExprent(Exprent exprent, public static boolean getCastedExprent(Exprent exprent,
VarType leftType, VarType leftType,
StringBuilder buffer, TextBuffer buffer,
int indent, int indent,
boolean castNull, boolean castNull,
boolean castAlways, BytecodeMappingTracer tracer) { boolean castAlways, BytecodeMappingTracer tracer) {

View File

@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext; 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.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
@ -81,7 +82,7 @@ public class ExitExprent extends Exprent {
tracer.addMapping(bytecode); tracer.addMapping(bytecode);
if (exittype == EXIT_RETURN) { if (exittype == EXIT_RETURN) {
StringBuilder buffer = new StringBuilder(); TextBuffer buffer = new TextBuffer();
if (rettype.type != CodeConstants.TYPE_VOID) { if (rettype.type != CodeConstants.TYPE_VOID) {
buffer.append(" "); buffer.append(" ");
@ -115,7 +116,7 @@ public class ExitExprent extends Exprent {
if (classname != null) { if (classname != null) {
VarType exctype = new VarType(classname, true); VarType exctype = new VarType(classname, true);
StringBuilder buffer = new StringBuilder(); TextBuffer buffer = new TextBuffer();
ExprProcessor.getCastedExprent(value, exctype, buffer, indent, false, tracer); ExprProcessor.getCastedExprent(value, exctype, buffer, indent, false, tracer);
return "throw " + buffer.toString(); return "throw " + buffer.toString();

View File

@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext; 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.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
@ -137,7 +138,7 @@ public class FieldExprent extends Exprent {
buf.append("super"); buf.append("super");
} }
else { 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); boolean casted = ExprProcessor.getCastedExprent(instance, new VarType(CodeConstants.TYPE_OBJECT, 0, classname), buff, indent, true, tracer);
String res = buff.toString(); String res = buff.toString();

View File

@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext; 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.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
@ -360,7 +361,7 @@ public class InvocationExprent extends Exprent {
buf.append(", "); 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); ExprProcessor.getCastedExprent(lstParameters.get(i), descriptor.params[i], buff, indent, true, setAmbiguousParameters.contains(i), tracer);
buf.append(buff); buf.append(buff);

View File

@ -19,6 +19,7 @@ import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassWriter; import org.jetbrains.java.decompiler.main.ClassWriter;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext; 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.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
@ -172,7 +173,7 @@ public class NewExprent extends Exprent {
@Override @Override
public String toJava(int indent, BytecodeMappingTracer tracer) { public String toJava(int indent, BytecodeMappingTracer tracer) {
StringBuilder buf = new StringBuilder(); TextBuffer buf = new TextBuffer();
if (anonymous) { 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); ExprProcessor.getCastedExprent(param, invsuper.getDescriptor().params[i], buff, indent, true, tracer);
buf.append(buff); buf.append(buff);
@ -317,7 +318,7 @@ public class NewExprent extends Exprent {
buf.append(", "); buf.append(", ");
} }
StringBuilder buff = new StringBuilder(); TextBuffer buff = new TextBuffer();
ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buff, indent, true, tracer); ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buff, indent, true, tracer);
buf.append(buff); buf.append(buff);
@ -373,7 +374,7 @@ public class NewExprent extends Exprent {
if (i > 0) { if (i > 0) {
buf.append(", "); buf.append(", ");
} }
StringBuilder buff = new StringBuilder(); TextBuffer buff = new TextBuffer();
ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buff, indent, false, tracer); ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buff, indent, false, tracer);
buf.append(buff); buf.append(buff);

View File

@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassWriter; import org.jetbrains.java.decompiler.main.ClassWriter;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; 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.collectors.BytecodeMappingTracer;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
@ -83,7 +84,7 @@ public class VarExprent extends Exprent {
@Override @Override
public String toJava(int indent, BytecodeMappingTracer tracer) { public String toJava(int indent, BytecodeMappingTracer tracer) {
StringBuilder buffer = new StringBuilder(); TextBuffer buffer = new TextBuffer();
tracer.addMapping(bytecode); tracer.addMapping(bytecode);

View File

@ -15,6 +15,7 @@
*/ */
package org.jetbrains.java.decompiler.struct; 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.main.extern.IResultSaver;
import org.jetbrains.java.decompiler.struct.lazy.LazyLoader; import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import org.jetbrains.java.decompiler.struct.lazy.LazyLoader.Link; import org.jetbrains.java.decompiler.struct.lazy.LazyLoader.Link;
@ -110,7 +111,7 @@ public class ContextUnit {
StructClass cl = classes.get(i); StructClass cl = classes.get(i);
String entryName = decompiledData.getClassEntryName(cl, classEntries.get(i)); String entryName = decompiledData.getClassEntryName(cl, classEntries.get(i));
if (entryName != null) { if (entryName != null) {
String content = decompiledData.getClassContent(cl); TextBuffer content = decompiledData.getClassContent(cl);
if (content != null) { if (content != null) {
resultSaver.saveClassFile(filename, cl.qualifiedName, entryName, content); resultSaver.saveClassFile(filename, cl.qualifiedName, entryName, content);
} }
@ -142,8 +143,8 @@ public class ContextUnit {
StructClass cl = classes.get(i); StructClass cl = classes.get(i);
String entryName = decompiledData.getClassEntryName(cl, classEntries.get(i)); String entryName = decompiledData.getClassEntryName(cl, classEntries.get(i));
if (entryName != null) { if (entryName != null) {
String content = decompiledData.getClassContent(cl); TextBuffer content = decompiledData.getClassContent(cl);
resultSaver.saveClassEntry(archivePath, filename, cl.qualifiedName, entryName, content); resultSaver.saveClassEntry(archivePath, filename, cl.qualifiedName, entryName, content.toString());
} }
} }

View File

@ -15,9 +15,11 @@
*/ */
package org.jetbrains.java.decompiler.struct; package org.jetbrains.java.decompiler.struct;
import org.jetbrains.java.decompiler.main.TextBuffer;
public interface IDecompiledData { public interface IDecompiledData {
String getClassEntryName(StructClass cl, String entryname); String getClassEntryName(StructClass cl, String entryname);
String getClassContent(StructClass cl); TextBuffer getClassContent(StructClass cl);
} }

View File

@ -16,6 +16,7 @@
package org.jetbrains.java.decompiler.util; package org.jetbrains.java.decompiler.util;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import java.io.*; import java.io.*;
@ -91,12 +92,12 @@ public class InterpreterUtil {
public static String getIndentString(int length) { public static String getIndentString(int length) {
if (length == 0) return ""; if (length == 0) return "";
StringBuilder buf = new StringBuilder(); TextBuffer buf = new TextBuffer();
appendIndent(buf, length); appendIndent(buf, length);
return buf.toString(); return buf.toString();
} }
public static void appendIndent(StringBuilder buffer, int length) { public static void appendIndent(TextBuffer buffer, int length) {
if (length == 0) return; if (length == 0) return;
String indent = (String)DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING); String indent = (String)DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING);
while (length-- > 0) { while (length-- > 0) {