diff --git a/jode/NEWS b/jode/NEWS index 9fb9f6b..2d2bc84 100644 --- a/jode/NEWS +++ b/jode/NEWS @@ -1,3 +1,7 @@ +New in 1.0.94 +* break long lines +* small bug fixes + New in 1.0.93 * anonymous and inner class decompilation reworked. * replaced a bash specific construct in acinclude.m4 diff --git a/jode/jode/decompiler/ClassAnalyzer.java.in b/jode/jode/decompiler/ClassAnalyzer.java.in index ce89427..298bdfa 100644 --- a/jode/jode/decompiler/ClassAnalyzer.java.in +++ b/jode/jode/decompiler/ClassAnalyzer.java.in @@ -177,11 +177,11 @@ public class ClassAnalyzer return outerValues; } - public void addBlockInitializer(int index, - StructuredBlock initializer) { + public void addBlockInitializer(int index, StructuredBlock initializer) { if (blockInitializers[index] == null) blockInitializers[index] = initializer; - blockInitializers[index].appendBlock(initializer); + else + blockInitializers[index].appendBlock(initializer); } public void initialize() { @@ -423,7 +423,7 @@ public class ClassAnalyzer for (int i=0; i< fields.length; i++) { if (blockInitializers[i] != null) { if (needNewLine) - writer.println(""); + writer.println(); writer.openBrace(); writer.tab(); blockInitializers[i].dumpSource(writer); @@ -439,13 +439,13 @@ public class ClassAnalyzer if (fields[i].skipWriting()) continue; if (needFieldNewLine) - writer.println(""); + writer.println(); fields[i].dumpSource(writer); needNewLine = true; } if (blockInitializers[fields.length] != null) { if (needNewLine) - writer.println(""); + writer.println(); writer.openBrace(); writer.tab(); blockInitializers[fields.length].dumpSource(writer); @@ -455,7 +455,7 @@ public class ClassAnalyzer } for (int i=0; i< inners.length; i++) { if (needNewLine) - writer.println(""); + writer.println(); if ((Options.options & Options.OPTION_IMMEDIATE) != 0) { // We now do the analyzation we skipped before. @@ -489,7 +489,7 @@ public class ClassAnalyzer if (methods[i].skipWriting()) continue; if (needNewLine) - writer.println(""); + writer.println(); if (pl != null) { double methodCompl = methods[i].getComplexity() * subScale; @@ -520,6 +520,7 @@ public class ClassAnalyzer return; } + writer.startOp(writer.NO_PAREN, 0); /* Clear the SUPER bit, which is also used as SYNCHRONIZED bit. */ int modifiedModifiers = modifiers & ~Modifier.SYNCHRONIZED; if (clazz.isInterface()) @@ -538,26 +539,30 @@ public class ClassAnalyzer /* interface is in modif */ if (!clazz.isInterface()) writer.print("class "); - writer.println(name); - writer.tab(); + writer.print(name); ClassInfo superClazz = clazz.getSuperclass(); if (superClazz != null && superClazz != ClassInfo.javaLangObject) { - writer.println("extends " + (writer.getClassString - (superClazz, Scope.CLASSNAME))); + writer.breakOp(); + writer.print(" extends " + (writer.getClassString + (superClazz, Scope.CLASSNAME))); } ClassInfo[] interfaces = clazz.getInterfaces(); if (interfaces.length > 0) { - writer.print(clazz.isInterface() ? "extends " : "implements "); + writer.breakOp(); + writer.print(clazz.isInterface() ? " extends " : " implements "); + writer.startOp(writer.EXPL_PAREN, 1); for (int i=0; i < interfaces.length; i++) { - if (i > 0) + if (i > 0) { writer.print(", "); + writer.breakOp(); + } writer.print(writer.getClassString (interfaces[i], Scope.CLASSNAME)); } - writer.println(""); + writer.endOp(); } - writer.untab(); + writer.println(); writer.openBrace(); writer.tab(); diff --git a/jode/jode/decompiler/FieldAnalyzer.java.in b/jode/jode/decompiler/FieldAnalyzer.java.in index b4131e1..0ac9c4f 100644 --- a/jode/jode/decompiler/FieldAnalyzer.java.in +++ b/jode/jode/decompiler/FieldAnalyzer.java.in @@ -176,6 +176,7 @@ public class FieldAnalyzer implements Analyzer { | Modifier.STATIC | Modifier.FINAL); */ + writer.startOp(writer.NO_PAREN, 0); String modif = Modifier.toString(modifiedModifiers); if (modif.length() > 0) writer.print(modif+" "); @@ -183,9 +184,11 @@ public class FieldAnalyzer implements Analyzer { writer.printType(type); writer.print(" " + fieldName); if (constant != null) { - writer.print(" = "); - constant.dumpExpression(writer); + writer.breakOp(); + writer.print(" = "); + constant.dumpExpression(writer.IMPL_PAREN, writer); } + writer.endOp(); writer.println(";"); } diff --git a/jode/jode/decompiler/MethodAnalyzer.java.in b/jode/jode/decompiler/MethodAnalyzer.java.in index 0092891..c72e8f2 100644 --- a/jode/jode/decompiler/MethodAnalyzer.java.in +++ b/jode/jode/decompiler/MethodAnalyzer.java.in @@ -838,17 +838,18 @@ public class MethodAnalyzer implements Scope, ClassDeclarer { if (isConstructor() && isStatic()) modifiedModifiers &= ~Modifier.FINAL; - - String delim =""; + writer.startOp(writer.NO_PAREN, 1); + String delim = ""; if (minfo.isSynthetic()) { writer.print("/*synthetic*/"); delim = " "; } String modif = Modifier.toString(modifiedModifiers); - writer.print(delim + modif); - if (modif.length() > 0) + if (modif.length() > 0) { + writer.print(delim + modif); delim = " "; + } if (isConstructor && (isStatic() || (classAnalyzer.getName() == null @@ -862,24 +863,35 @@ public class MethodAnalyzer implements Scope, ClassDeclarer { writer.printType(getReturnType()); writer.print(" " + methodName); } + writer.breakOp(); writer.print("("); - int offset = skipParams + (isStatic() ? 0 : 1); + writer.startOp(writer.EXPL_PAREN, 0); + int offset = skipParams + (isStatic() ? 0 : 1); for (int i = offset; i < param.length; i++) { - if (i > offset) + if (i > offset) { writer.print(", "); + writer.breakOp(); + } param[i].dumpDeclaration(writer); } + writer.endOp(); writer.print(")"); } if (exceptions.length > 0) { - writer.println(""); - writer.print("throws "); + writer.breakOp(); + writer.print(" throws "); + writer.startOp(writer.EXPL_PAREN, 2); for (int i= 0; i< exceptions.length; i++) { - if (i > 0) - writer.print(", "); + if (i > 0) { + writer.print(","); + writer.breakOp(); + writer.print(" "); + } writer.printType(exceptions[i]); } + writer.endOp(); } + writer.endOp(); if (code != null) { writer.openBrace(); writer.tab(); diff --git a/jode/jode/decompiler/TabbedPrintWriter.java b/jode/jode/decompiler/TabbedPrintWriter.java index 4ed8acf..b8df179 100644 --- a/jode/jode/decompiler/TabbedPrintWriter.java +++ b/jode/jode/decompiler/TabbedPrintWriter.java @@ -20,34 +20,467 @@ package jode.decompiler; import java.io.*; import java.util.Stack; +import java.util.Vector; +import java.util.Enumeration; +import jode.AssertError; import jode.GlobalOptions; import jode.bytecode.ClassInfo; import jode.bytecode.InnerClassInfo; import jode.type.*; public class TabbedPrintWriter { - boolean atbol; - int indentsize; - int currentIndent = 0; - String indentStr = ""; - PrintWriter pw; - ImportHandler imports; - Stack scopes = new Stack(); + /* The indentation size. */ + private int indentsize; + /* The size of a tab, MAXINT if we shouldn't use tabs at all. */ + private int tabWidth; + private int lineWidth; + private int currentIndent = 0; + private String indentStr = ""; + private PrintWriter pw; + private ImportHandler imports; + private Stack scopes = new Stack(); + + private StringBuffer currentLine; + private BreakPoint currentBP; + public final static int EXPL_PAREN = 0; + public final static int NO_PAREN = 1; + public final static int IMPL_PAREN = 2; + public final static int DONT_BREAK = 3; + + /** + * Convert the numeric indentation to a string. + */ + protected String makeIndentStr(int indent) { + String tabSpaceString = /* (tab x 20) . (space x 20) */ + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t "; + if (indent < 0) + return "NEGATIVEINDENT"+indent; + + int tabs = indent / tabWidth; + indent -= tabs * tabWidth; + if (tabs <= 20 && indent <= 20) { + /* The fast way. */ + return tabSpaceString.substring(20 - tabs, 20 + indent); + } else { + /* the not so fast way */ + StringBuffer sb = new StringBuffer(tabs + indent); + while (tabs > 20) { + sb.append(tabSpaceString.substring(0,20)); + tabs -= 20; + } + sb.append(tabSpaceString.substring(0, tabs)); + while (indent > 20) { + sb.append(tabSpaceString.substring(20)); + indent -= 20; + } + sb.append(tabSpaceString.substring(40 - indent)); + return sb.toString(); + } + } + + class BreakPoint { + int options; + int breakPenalty; + int breakPos; + int startPos; + BreakPoint parentBP; + Vector childBPs; + int nesting = 0; + int endPos; + int whatBreak = 0; + + public BreakPoint(BreakPoint parent, int position) { + this.breakPos = position; + this.parentBP = parent; + this.options = DONT_BREAK; + this.breakPenalty = 0; + this.startPos = -1; + this.endPos = -1; + this.whatBreak = 0; + this.childBPs = null; + } + + public void startOp(int opts, int penalty, int pos) { + if (startPos != -1) { + System.err.println("WARNING: missing breakOp"); + Thread.dumpStack(); + return; + } + startPos = pos; + options = opts; + breakPenalty = penalty; + childBPs = new Vector(); + breakOp(pos); + } + + public void breakOp(int pos) { + childBPs.addElement (new BreakPoint(this, pos)); + } + + public void endOp(int pos) { + endPos = pos; + if (childBPs.size() == 1) { + BreakPoint child = + (BreakPoint) currentBP.childBPs.elementAt(0); + if (child.startPos == -1) { + startPos = endPos = -1; + childBPs = null; + } else if (child.startPos == currentBP.startPos + && child.endPos == currentBP.endPos) { + if (options == DONT_BREAK) + options = child.options; + childBPs = child.childBPs; + } + } + } + + public void dump(String line) { + if (startPos == -1) { + pw.print(line); + } else { + pw.print(line.substring(0, startPos)); + dumpRegion(line); + pw.print(line.substring(endPos)); + } + } + + public void dumpRegion(String line) { + String parens = "{\010{}\010}<\010<>\010>[\010[]\010]`\010`'\010'" + .substring(options*6, options*6+6); + pw.print(parens.substring(0,3)); + Enumeration enum = childBPs.elements(); + int cur = startPos; + BreakPoint child = (BreakPoint) enum.nextElement(); + if (child.startPos >= 0) { + pw.print(line.substring(cur, child.startPos)); + child.dumpRegion(line); + cur = child.endPos; + } + while (enum.hasMoreElements()) { + child = (BreakPoint) enum.nextElement(); + pw.print(line.substring(cur, child.breakPos)); + pw.print("!\010!"+breakPenalty); + cur = child.breakPos; + if (child.startPos >= 0) { + pw.print(line.substring(child.breakPos, child.startPos)); + child.dumpRegion(line); + cur = child.endPos; + } + } + pw.print(line.substring(cur, endPos)); + pw.print(parens.substring(3)); + } + + public void printLines(int indent, String line) { + if (startPos == -1) { + pw.print(line); + } else { + pw.print(line.substring(0, startPos)); + printRegion(indent + startPos, line); + pw.print(line.substring(endPos)); + } + } + + public void printRegion(int indent, String line) { + if (options == IMPL_PAREN) { + pw.print("("); + indent++; + } + + Enumeration enum = childBPs.elements(); + int cur = startPos; + BreakPoint child = (BreakPoint) enum.nextElement(); + if (child.startPos >= 0) { + pw.print(line.substring(cur, child.startPos)); + child.printRegion(indent + child.startPos - cur, line); + cur = child.endPos; + } + if (options == NO_PAREN) + indent += indentsize; + String indentStr = makeIndentStr(indent); + while (enum.hasMoreElements()) { + child = (BreakPoint) enum.nextElement(); + pw.print(line.substring(cur, child.breakPos)); + pw.println(); + pw.print(indentStr); + cur = child.breakPos; + if (cur < endPos && line.charAt(cur) == ' ') + cur++; + if (child.startPos >= 0) { + pw.print(line.substring(cur, child.startPos)); + child.printRegion(indent + child.startPos - cur, line); + cur = child.endPos; + } + } + pw.print(line.substring(cur, endPos)); + if (options == IMPL_PAREN) + pw.print(")"); + } + + public BreakPoint commitMinPenalty(int space, int lastSpace, + int minPenalty) { + if (startPos == -1 || lastSpace > endPos - startPos + || minPenalty == 10 * (endPos - startPos - lastSpace)) { + /* We don't have to break anything */ + startPos = -1; + childBPs = null; + return this; + } + + int size = childBPs.size(); + if (size > 1 && options != DONT_BREAK) { + /* penalty if we are breaking the line here. */ + int breakPen + = getBreakPenalty(space, lastSpace, minPenalty + 1); +// pw.print("commit[bp="+breakPen+";"+minPenalty+";" +// +space+","+lastSpace+"]"); + if (minPenalty == breakPen) { + commitBreakPenalty(space, lastSpace, breakPen); + return this; + } + } + + /* penalty if we are breaking only one child */ + for (int i=0; i < size; i++) { + BreakPoint child = (BreakPoint) childBPs.elementAt(i); + int front = child.startPos - startPos; + int tail = endPos - child.endPos; + int needPenalty = minPenalty - (i < size - 1 ? 1 : 0); + if (needPenalty == + child.getMinPenalty(space - front, + lastSpace - front - tail, + needPenalty + 1)) { + child = child.commitMinPenalty(space - front, + lastSpace - front - tail, + needPenalty); + child.breakPos = breakPos; + return child; + } + } + pw.println("XXXXXXXXXXX CAN'T COMMIT"); + startPos = -1; + childBPs = null; + return this; + } + + public int getMinPenalty(int space, int lastSpace, int minPenalty) { +// pw.print("getMinPenalty["+startPos+","+endPos+"]("+space+","+lastSpace+","+minPenalty+") "); + if (10 * -lastSpace >= minPenalty) { +// pw.println("= minPenalty"); + return minPenalty; + } + + if (startPos == -1) + return 10 * -lastSpace; + + if (lastSpace > endPos - startPos) { +// pw.println("= NULL"); + return 0; + } + + if (minPenalty <= 1) { +// pw.println("= ONE"); + return minPenalty; + } + + if (minPenalty > 10 * (endPos - startPos - lastSpace)) + minPenalty = 10 * (endPos - startPos - lastSpace); + +// pw.print("[mp="+minPenalty+"]"); + + int size = childBPs.size(); + if (size == 0) + return minPenalty; + + if (size > 1 && options != DONT_BREAK) { + /* penalty if we are breaking at this level. */ + minPenalty = getBreakPenalty(space, lastSpace, minPenalty); +// pw.print("[bp="+minPenalty+"]"); + } + + /* penalty if we are breaking only one child */ + for (int i=0; i < size; i++) { + BreakPoint child = (BreakPoint) childBPs.elementAt(i); + int front = child.startPos - startPos; + int tail = endPos - child.endPos; + int penalty = (i < size - 1 ? 1 : 0); + minPenalty = penalty + + child.getMinPenalty(space - front, + lastSpace - front - tail, + minPenalty - penalty); + } +// pw.println("= "+minPenalty); + return minPenalty; + } + + public void commitBreakPenalty(int space, int lastSpace, + int minPenalty) { +// pw.println("commitBreakPenalty: "+startPos+","+endPos+";" +// +space+","+lastSpace+";"+minPenalty); + + if (options == IMPL_PAREN) { + space--; + lastSpace -= 2; + } + + Enumeration enum = childBPs.elements(); + childBPs = new Vector(); + int currInd = 0; + BreakPoint lastChild, nextChild; + boolean indentNext = options == NO_PAREN; + for (lastChild = (BreakPoint) enum.nextElement(); + enum.hasMoreElements(); lastChild = nextChild) { + nextChild = (BreakPoint) enum.nextElement(); + int childStart = lastChild.breakPos; + int childEnd = nextChild.breakPos; + + if (currInd > 0) { + currInd += childEnd - childStart; + if (currInd <= space) + continue; + } + if (childStart < endPos + && currentLine.charAt(childStart) == ' ') + childStart++; + + if (childEnd - childStart > space) { + int front = lastChild.startPos - childStart; + int tail = childEnd - lastChild.endPos; + int childPenalty = lastChild.getMinPenalty + (space - front, space - front - tail, minPenalty); + currInd = 0; + childBPs.addElement + (lastChild.commitMinPenalty + (space - front, space - front - tail, childPenalty)); + } else { + lastChild.startPos = -1; + lastChild.childBPs = null; + childBPs.addElement(lastChild); + currInd = childEnd - childStart; + } + + if (indentNext) { + space -= indentsize; + lastSpace -= indentsize; + indentNext = false; + } + } + int childStart = lastChild.breakPos; + if (currInd > 0 && currInd + endPos - childStart <= lastSpace) + return; + + if (childStart < endPos + && currentLine.charAt(childStart) == ' ') + childStart++; + if (endPos - childStart > lastSpace) { + int front = lastChild.startPos - childStart; + int tail = endPos - lastChild.endPos; + int childPenalty = lastChild.getMinPenalty + (space - front, lastSpace - front - tail, minPenalty + 1); + childBPs.addElement + (lastChild.commitMinPenalty + (space - front, lastSpace - front - tail, childPenalty)); + } else { + lastChild.startPos = -1; + lastChild.childBPs = null; + childBPs.addElement(lastChild); + } + } + + public int getBreakPenalty(int space, int lastSpace, int minPenalty) { + int penalty = breakPenalty; + int currInd = 0; + if (options == IMPL_PAREN) { + space--; + lastSpace -= 2; + } + if (space < 0) + return minPenalty; + Enumeration enum = childBPs.elements(); + BreakPoint lastChild, nextChild; + boolean indentNext = options == NO_PAREN; + for (lastChild = (BreakPoint) enum.nextElement(); + enum.hasMoreElements(); lastChild = nextChild) { + nextChild = (BreakPoint) enum.nextElement(); + int childStart = lastChild.breakPos; + int childEnd = nextChild.breakPos; + + if (currInd > 0) { + currInd += childEnd - childStart; + if (currInd <= space) + continue; + + penalty++; + if (indentNext) { + space -= indentsize; + lastSpace -= indentsize; + indentNext = false; + } + } + + if (childStart < endPos + && currentLine.charAt(childStart) == ' ') + childStart++; + + if (childEnd - childStart > space) { + int front = lastChild.startPos - childStart; + int tail = childEnd - lastChild.endPos; + penalty += 1 + lastChild.getMinPenalty + (space - front, space - front - tail, + minPenalty - penalty - 1); + + if (indentNext) { + space -= indentsize; + lastSpace -= indentsize; + indentNext = false; + } + currInd = 0; + } else + currInd = childEnd - childStart; + + if (penalty >= minPenalty) + return minPenalty; + } + int childStart = lastChild.breakPos; + if (currInd > 0) { + if (currInd + endPos - childStart <= lastSpace) + return penalty; + + penalty++; + if (indentNext) { + space -= indentsize; + lastSpace -= indentsize; + indentNext = false; + } + } + if (childStart < endPos + && currentLine.charAt(childStart) == ' ') + childStart++; + if (endPos - childStart > lastSpace) { + int front = lastChild.startPos - childStart; + int tail = endPos - lastChild.endPos; + penalty += lastChild.getMinPenalty + (space - front, lastSpace - front - tail, + minPenalty - penalty); + } + if (penalty < minPenalty) + return penalty; + return minPenalty; + } + } public TabbedPrintWriter (OutputStream os, ImportHandler imports, boolean autoFlush) { pw = new PrintWriter(os, autoFlush); this.imports = imports; - this.indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK); - atbol = true; + init(); } public TabbedPrintWriter (Writer os, ImportHandler imports, boolean autoFlush) { pw = new PrintWriter(os, autoFlush); this.imports = imports; - this.indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK); - atbol = true; + init(); } public TabbedPrintWriter (OutputStream os, ImportHandler imports) { @@ -66,82 +499,101 @@ public class TabbedPrintWriter { this(os, null); } - /** - * Convert the numeric indentation to a string. - */ - protected void makeIndentStr() { - int tabs = (currentIndent >> 3); - // This is a very fast implementation. - if (tabs <= 20) - indentStr = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t " - .substring(20 - tabs, 20 + (currentIndent&7)); - else { - /* the slow way */ - StringBuffer sb = new StringBuffer(tabs+7); - while (tabs > 20) { - sb.append("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t " - .substring(0,20)); - tabs -= 20; - } - sb.append("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t " - .substring(20 - tabs, 20 + (currentIndent&7))); - indentStr = sb.toString(); - } + public void init() { + this.indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK); + this.tabWidth = 8; + this.lineWidth = 79; + currentLine = new StringBuffer(); + currentBP = new BreakPoint(null, 0); + currentBP.startOp(DONT_BREAK, 1, 0); } public void tab() { currentIndent += indentsize; - makeIndentStr(); + indentStr = makeIndentStr(currentIndent); } public void untab() { currentIndent -= indentsize; - makeIndentStr(); + indentStr = makeIndentStr(currentIndent); + } + + public void startOp(int options, int penalty) { + currentBP = (BreakPoint) currentBP.childBPs.lastElement(); + currentBP.startOp(options, penalty, currentLine.length()); + } + + public void breakOp() { + int pos = currentLine.length(); + if (pos > currentBP.startPos && currentLine.charAt(pos-1) == ' ') + pos--; + currentBP.breakOp(pos); + } + + public void endOp() { + currentBP.endOp(currentLine.length()); + currentBP = currentBP.parentBP; + if (currentBP == null) + throw new NullPointerException(); + } + + public Object saveOps() { + Stack state = new Stack(); + int pos = currentLine.length(); + while (currentBP.parentBP != null) { + state.push(new Integer(currentBP.options)); + state.push(new Integer(currentBP.breakPenalty)); + currentBP.endPos = pos; + currentBP = currentBP.parentBP; + } + return state; + } + + public void restoreOps(Object s) { + Stack state = (Stack) s; + while (!state.isEmpty()) { + int penalty = ((Integer) state.pop()).intValue(); + int options = ((Integer) state.pop()).intValue(); + startOp(options, penalty); + } } public void println(String str) { - if (atbol) - pw.print(indentStr); - pw.println(str); - atbol = true; + print(str); + println(); } public void println() { + currentBP.endPos = currentLine.length(); + +// pw.print(indentStr); +// currentBP.dump(currentLine.toString()); +// pw.println(); + + int lw = lineWidth - currentIndent; + int minPenalty = currentBP.getMinPenalty(lw, lw, Integer.MAX_VALUE/2); + currentBP = currentBP.commitMinPenalty(lw, lw, minPenalty); + +// pw.print(indentStr); +// currentBP.dump(currentLine.toString()); +// pw.println(); + pw.print(indentStr); + currentBP.printLines(currentIndent, currentLine.toString()); pw.println(); - atbol = true; + + currentLine.setLength(0); + currentBP = new BreakPoint(null, 0); + currentBP.startOp(DONT_BREAK, 1, 0); } public void print(String str) { - if (atbol) - pw.print(indentStr); - pw.print(str); - atbol = false; + currentLine.append(str); } public void printType(Type type) { print(getTypeString(type)); } - /** - * Print a opening brace with the current indentation style. - * Called at the end of the line of the instance that opens the - * brace. It doesn't do a tab stop after opening the brace. - */ - public void openBrace() { - if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) - if (atbol) - println("{"); - else - println(" {"); - else { - if (!atbol) - println(); - if (currentIndent > 0) - tab(); - println("{"); - } - } - public void pushScope(Scope scope) { scopes.push(scope); } @@ -282,6 +734,24 @@ public class TabbedPrintWriter { return type.toString(); } + /** + * Print a opening brace with the current indentation style. + * Called at the end of the line of the instance that opens the + * brace. It doesn't do a tab stop after opening the brace. + */ + public void openBrace() { + if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) { + print(currentLine.length() > 0 ? " {" : "{"); + println(); + } else { + if (currentLine.length() > 0) + println(); + if (currentIndent > 0) + tab(); + println("{"); + } + } + /** * Print a opening brace with the current indentation style. * Called at the end of the line of the instance that opens the @@ -291,7 +761,7 @@ public class TabbedPrintWriter { if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) println("{"); else { - if (!atbol) + if (currentLine.length() > 0) println(); if (currentIndent > 0) tab(); diff --git a/jode/jode/expr/ArrayLoadOperator.java b/jode/jode/expr/ArrayLoadOperator.java index dc85842..73f7ab5 100644 --- a/jode/jode/expr/ArrayLoadOperator.java +++ b/jode/jode/expr/ArrayLoadOperator.java @@ -50,6 +50,7 @@ public class ArrayLoadOperator extends Operator { public void dumpExpression(TabbedPrintWriter writer) throws java.io.IOException { subExpressions[0].dumpExpression(writer, 950); + writer.breakOp(); writer.print("["); subExpressions[1].dumpExpression(writer, 0); writer.print("]"); diff --git a/jode/jode/expr/BinaryOperator.java b/jode/jode/expr/BinaryOperator.java index cffb98d..06e033d 100644 --- a/jode/jode/expr/BinaryOperator.java +++ b/jode/jode/expr/BinaryOperator.java @@ -87,6 +87,7 @@ public class BinaryOperator extends Operator { public void dumpExpression(TabbedPrintWriter writer) throws java.io.IOException { subExpressions[0].dumpExpression(writer, getPriority()); + writer.breakOp(); writer.print(getOperatorString()); subExpressions[1].dumpExpression(writer, getPriority()+1); } diff --git a/jode/jode/expr/CheckCastOperator.java b/jode/jode/expr/CheckCastOperator.java index 843a0ec..8de6151 100644 --- a/jode/jode/expr/CheckCastOperator.java +++ b/jode/jode/expr/CheckCastOperator.java @@ -56,6 +56,7 @@ public class CheckCastOperator extends Operator { writer.print("("); writer.printType(castType); writer.print(") "); + writer.breakOp(); /* There are special cases where a cast isn't allowed. We must cast * to the common super type before. This cases always give a runtime @@ -66,6 +67,7 @@ public class CheckCastOperator extends Operator { writer.print("("); writer.printType(superType); writer.print(") "); + writer.breakOp(); } subExpressions[0].dumpExpression(writer, 700); } diff --git a/jode/jode/expr/CompareBinaryOperator.java b/jode/jode/expr/CompareBinaryOperator.java index 06b1fee..7e964f5 100644 --- a/jode/jode/expr/CompareBinaryOperator.java +++ b/jode/jode/expr/CompareBinaryOperator.java @@ -86,7 +86,8 @@ public class CompareBinaryOperator extends Operator { public void dumpExpression(TabbedPrintWriter writer) throws java.io.IOException { - subExpressions[0].dumpExpression(writer, getPriority()); + subExpressions[0].dumpExpression(writer, getPriority()+1); + writer.breakOp(); writer.print(getOperatorString()); subExpressions[1].dumpExpression(writer, getPriority()+1); } diff --git a/jode/jode/expr/CompareUnaryOperator.java b/jode/jode/expr/CompareUnaryOperator.java index 46641bd..93e6f8a 100644 --- a/jode/jode/expr/CompareUnaryOperator.java +++ b/jode/jode/expr/CompareUnaryOperator.java @@ -108,7 +108,8 @@ public class CompareUnaryOperator extends Operator { public void dumpExpression(TabbedPrintWriter writer) throws java.io.IOException { - subExpressions[0].dumpExpression(writer, getPriority()); + subExpressions[0].dumpExpression(writer, getPriority()+1); + writer.breakOp(); writer.print(getOperatorString()); writer.print(objectType?"null":"0"); } diff --git a/jode/jode/expr/ConstantArrayOperator.java b/jode/jode/expr/ConstantArrayOperator.java index 9e0f9f5..0a3be5a 100644 --- a/jode/jode/expr/ConstantArrayOperator.java +++ b/jode/jode/expr/ConstantArrayOperator.java @@ -99,24 +99,22 @@ public class ConstantArrayOperator extends Operator { if (!isInitializer) { writer.print("new "); writer.printType(type.getHint()); + writer.breakOp(); writer.print(" "); } - writer.openBraceNoSpace(); - writer.tab(); + writer.print("{ "); + writer.startOp(writer.EXPL_PAREN, 0); for (int i=0; i< subExpressions.length; i++) { if (i>0) { - if (i % 10 == 0) - writer.println(","); - else - writer.print(", "); + writer.print(", "); + writer.breakOp(); } if (subExpressions[i] != null) subExpressions[i].dumpExpression(writer, 0); else empty.dumpExpression(writer, 0); } - writer.println(); - writer.untab(); - writer.closeBraceNoSpace(); + writer.endOp(); + writer.print(" }"); } } diff --git a/jode/jode/expr/Expression.java.in b/jode/jode/expr/Expression.java.in index 9749201..8e2cd4f 100644 --- a/jode/jode/expr/Expression.java.in +++ b/jode/jode/expr/Expression.java.in @@ -96,7 +96,6 @@ public abstract class Expression { return parent; } - /** * Get priority of the operator. * Currently this priorities are known: @@ -121,6 +120,13 @@ public abstract class Expression { */ public abstract int getPriority(); + /** + * Get the penalty for splitting up this operator. + */ + public int getBreakPenalty() { + return 0; + } + /** * Get the number of operands. * @return The number of stack entries this expression needs. @@ -237,29 +243,56 @@ public abstract class Expression { public abstract void dumpExpression(TabbedPrintWriter writer) throws java.io.IOException; + public void dumpExpression(int options, TabbedPrintWriter writer) + throws java.io.IOException + { + writer.startOp(options, getBreakPenalty()); + dumpExpression(writer); + writer.endOp(); + } + public void dumpExpression(TabbedPrintWriter writer, int minPriority) throws java.io.IOException { + int options; boolean needParen1 = false, needParen2 = false; - if (type == Type.tError) { - if (minPriority > 700) { - needParen1 = true; - writer.print("("); - } - writer.print("/*TYPE ERROR*/ "); - minPriority = 700; - } + boolean needEndOp1 = false, needEndOp2 = false; + + String typecast = ""; + + if (type == Type.tError) + typecast = "/*TYPE_ERROR*/"; else if ((GlobalOptions.debuggingFlags - & GlobalOptions.DEBUG_TYPES) != 0) { + & GlobalOptions.DEBUG_TYPES) != 0) + typecast = "(TYPE "+type+")"; + + if (typecast != "") { if (minPriority > 700) { needParen1 = true; + needEndOp1 = true; writer.print("("); + writer.startOp(writer.EXPL_PAREN, 0); + } else if (minPriority < 700) { + needEndOp1 = true; + writer.startOp(writer.IMPL_PAREN, 1); } - writer.print("(TYPE "+type+") "); + writer.print(typecast); + writer.breakOp(); + writer.print(" "); minPriority = 700; } - if (getPriority() < minPriority) { + + int priority = getPriority(); + if (priority < minPriority) { needParen2 = true; + needEndOp2 = true; writer.print("("); + writer.startOp(writer.EXPL_PAREN, getBreakPenalty()); + } else if (priority != minPriority) { + needEndOp2 = true; + if (getType() == Type.tVoid) + writer.startOp(writer.NO_PAREN, getBreakPenalty()); + else + writer.startOp(writer.IMPL_PAREN, 1 + getBreakPenalty()); } try { @@ -268,10 +301,16 @@ public abstract class Expression { writer.print("(RUNTIME ERROR IN EXPRESSION)"); } - if (needParen2) - writer.print(")"); - if (needParen1) - writer.print(")"); + if (needEndOp2) { + writer.endOp(); + if (needParen2) + writer.print(")"); + } + if (needEndOp1) { + writer.endOp(); + if (needParen1) + writer.print(")"); + } } public String toString() { diff --git a/jode/jode/expr/FieldOperator.java.in b/jode/jode/expr/FieldOperator.java.in index 6384981..951f874 100644 --- a/jode/jode/expr/FieldOperator.java.in +++ b/jode/jode/expr/FieldOperator.java.in @@ -181,15 +181,22 @@ public abstract class FieldOperator extends Operator { if (!classType.equals(Type.tClass(methodAnalyzer.getClazz())) || methodAnalyzer.findLocal(fieldName) != null) { writer.printType(classType); + writer.breakOp(); writer.print("."); } writer.print(fieldName); } else if (needsCast(subExpressions[0].getType().getCanonic())) { - writer.print("(("); + writer.print("("); + writer.startOp(writer.EXPL_PAREN, 1); + writer.print("("); writer.printType(classType); writer.print(") "); + writer.breakOp(); subExpressions[0].dumpExpression(writer, 700); - writer.print(")."); + writer.endOp(); + writer.print(")"); + writer.breakOp(); + writer.print("."); writer.print(fieldName); } else { if (opIsThis) { @@ -200,6 +207,7 @@ public abstract class FieldOperator extends Operator { if (scope == null || writer.conflicts(fieldName, scope, Scope.FIELDNAME)) { thisOp.dumpExpression(writer, 950); + writer.breakOp(); writer.print("."); } else if (writer.conflicts(fieldName, scope, Scope.AMBIGUOUSNAME) @@ -216,16 +224,18 @@ public abstract class FieldOperator extends Operator { ana = (ClassAnalyzer) ana.getParent(); if (ana == scope) // For a simple outer class we can say this - writer.print("this."); + writer.print("this"); else { // For a class that owns a method that owns // us, we have to give the full class name thisOp.dumpExpression(writer, 950); - writer.print("."); } + writer.breakOp(); + writer.print("."); } } else { subExpressions[0].dumpExpression(writer, 950); + writer.breakOp(); writer.print("."); } writer.print(fieldName); diff --git a/jode/jode/expr/IfThenElseOperator.java b/jode/jode/expr/IfThenElseOperator.java index b73c60c..586460e 100644 --- a/jode/jode/expr/IfThenElseOperator.java +++ b/jode/jode/expr/IfThenElseOperator.java @@ -103,15 +103,22 @@ public class IfThenElseOperator extends Operator { public void dumpExpression(TabbedPrintWriter writer) throws java.io.IOException { subExpressions[0].dumpExpression(writer, 201); + writer.breakOp(); writer.print(" ? "); + int subPriority = 0; if (!subExpressions[1].getType().getHint().isOfType (subExpressions[2].getType())) { + writer.startOp(writer.IMPL_PAREN, 2); /* We need a cast here */ writer.print("("); writer.printType(getType().getHint()); writer.print(") "); + subPriority = 700; } - subExpressions[1].dumpExpression(writer, 0); + subExpressions[1].dumpExpression(writer, subPriority); + if (subPriority == 700) + writer.endOp(); + writer.breakOp(); writer.print(" : "); subExpressions[2].dumpExpression(writer, 200); } diff --git a/jode/jode/expr/InstanceOfOperator.java b/jode/jode/expr/InstanceOfOperator.java index d025a7c..44b3366 100644 --- a/jode/jode/expr/InstanceOfOperator.java +++ b/jode/jode/expr/InstanceOfOperator.java @@ -51,12 +51,16 @@ public class InstanceOfOperator extends Operator { Type superType = instanceType.getCastHelper(subExpressions[0].getType()); if (superType != null) { + writer.startOp(writer.IMPL_PAREN, 2); writer.print("("); writer.printType(superType); writer.print(") "); + writer.breakOp(); subExpressions[0].dumpExpression(writer, 700); + writer.endOp(); } else subExpressions[0].dumpExpression(writer, 550); + writer.breakOp(); writer.print(" instanceof "); writer.printType(instanceType); } diff --git a/jode/jode/expr/InvokeOperator.java.in b/jode/jode/expr/InvokeOperator.java.in index 4ecd8fd..007ea3a 100644 --- a/jode/jode/expr/InvokeOperator.java.in +++ b/jode/jode/expr/InvokeOperator.java.in @@ -799,6 +799,10 @@ public final class InvokeOperator extends Operator } } } + + public int getBreakPenalty() { + return 5; + } /* Invokes never equals: they may return different values even if * they have the same parameters. @@ -816,6 +820,7 @@ public final class InvokeOperator extends Operator for (int i=0; i< subExpressions.length; i++) paramTypes[i] = subExpressions[i].getType().getCanonic(); + writer.startOp(writer.NO_PAREN, 0); switch (methodFlag) { case CONSTRUCTOR: { @@ -903,19 +908,25 @@ public final class InvokeOperator extends Operator if (writer.conflicts(outer.name, scope, Scope.CLASSNAME)) { qualifiedNew = true; outerExpr.dumpExpression(writer, 950); + writer.breakOp(); writer.print("."); } } else { qualifiedNew = true; if (outerExpr.getType() instanceof NullType) { - writer.print("(("); + writer.print("("); + writer.startOp(writer.EXPL_PAREN, 1); + writer.print("("); writer.printType(Type.tClass (ClassInfo.forName(outer.outer))); writer.print(") "); + writer.breakOp(); outerExpr.dumpExpression(writer, 700); + writer.endOp(); writer.print(")"); } else outerExpr.dumpExpression(writer, 950); + writer.breakOp(); writer.print("."); } } @@ -939,10 +950,16 @@ public final class InvokeOperator extends Operator writer.print("super"); break; } - - writer.print("((UNCONSTRUCTED)"); - subExpressions[0].dumpExpression(writer, 950); - writer.print(")."); + + writer.print("("); + writer.startOp(writer.EXPL_PAREN, 0); + writer.print("(UNCONSTRUCTED)"); + writer.breakOp(); + subExpressions[0].dumpExpression(writer, 700); + writer.endOp(); + writer.print(")"); + writer.breakOp(); + writer.print("."); writer.printType(Type.tClass(clazz)); break; } @@ -956,17 +973,23 @@ public final class InvokeOperator extends Operator ClassInfo superClazz = getClassInfo().getSuperclass(); paramTypes[0] = superClazz == null ? Type.tObject : Type.tClass(superClazz); + writer.breakOp(); writer.print("."); } else { /* XXX check if this is a private method. */ } } else { - writer.print("((NON VIRTUAL "); + writer.print("("); + writer.startOp(writer.EXPL_PAREN, 0); + writer.print("(NON VIRTUAL "); writer.printType(classType); - writer.print(")"); - paramTypes[0] = classType; + writer.print(") "); + writer.breakOp(); subExpressions[0].dumpExpression(writer, 700); - writer.print(")."); + writer.endOp(); + writer.print(")"); + writer.breakOp(); + writer.print("."); } writer.print(methodName); break; @@ -978,13 +1001,18 @@ public final class InvokeOperator extends Operator if (paramTypes[0].equals(classType)) subExpressions[0].dumpExpression(writer, 950); else { - writer.print("(("); + writer.print("("); + writer.startOp(writer.EXPL_PAREN, 0); + writer.print("("); writer.printType(classType); - writer.print(")"); + writer.print(") "); + writer.breakOp(); paramTypes[0] = classType; subExpressions[0].dumpExpression(writer, 700); + writer.endOp(); writer.print(")"); } + writer.breakOp(); writer.print("."); writer.print(methodName); break; @@ -996,6 +1024,7 @@ public final class InvokeOperator extends Operator if (scope == null ||writer.conflicts(methodName, scope, Scope.METHODNAME)) { writer.printType(classType); + writer.breakOp(); writer.print("."); } writer.print(methodName); @@ -1009,6 +1038,7 @@ public final class InvokeOperator extends Operator Scope.CLASSSCOPE); if (writer.conflicts(methodName, scope, Scope.METHODNAME)) { thisOp.dumpExpression(writer, 950); + writer.breakOp(); writer.print("."); } else if (/* This is a inherited field conflicting * with a field name in some outer class. @@ -1020,61 +1050,78 @@ public final class InvokeOperator extends Operator while (ana.getParent() instanceof ClassAnalyzer && ana != scope) ana = (ClassAnalyzer) ana.getParent(); - if (ana == scope) + if (ana == scope) { // For a simple outer class we can say this - writer.print("this."); - else { + writer.print("this"); + } else { // For a class that owns a method that owns // us, we have to give the full class name thisOp.dumpExpression(writer, 950); - writer.print("."); } + writer.breakOp(); + writer.print("."); } } else { if (needsCast(0, paramTypes)){ - writer.print("(("); + writer.print("("); + writer.startOp(writer.EXPL_PAREN, 1); + writer.print("("); writer.printType(classType); writer.print(") "); + writer.breakOp(); subExpressions[0].dumpExpression(writer, 700); + writer.endOp(); writer.print(")"); paramTypes[0] = classType; } else subExpressions[0].dumpExpression(writer, 950); + writer.breakOp(); writer.print("."); } writer.print(methodName); } + writer.endOp(); + writer.breakOp(); writer.print("("); + writer.startOp(writer.EXPL_PAREN, 0); boolean first = true; int offset = skippedArgs; while (arg < length) { - if (!first) + if (!first) { writer.print(", "); - else + writer.breakOp(); + } else first = false; int priority = 0; if (needsCast(arg, paramTypes)) { Type castType = methodType.getParameterTypes()[arg-offset]; + writer.startOp(writer.IMPL_PAREN, 1); writer.print("("); writer.printType(castType); writer.print(") "); + writer.breakOp(); paramTypes[arg] = castType; priority = 700; } subExpressions[arg++].dumpExpression(writer, priority); + if (priority == 700) + writer.endOp(); } + writer.endOp(); writer.print(")"); if (anonymousNew) { /* If this was an anonymous constructor call, we must now * dump the source code of the anonymous class. */ + Object state = writer.saveOps(); writer.openBrace(); writer.tab(); clazzAna.dumpBlock(writer); writer.untab(); writer.closeBraceNoSpace(); + writer.restoreOps(state); } } diff --git a/jode/jode/expr/StoreInstruction.java b/jode/jode/expr/StoreInstruction.java index 4cde61e..1870977 100644 --- a/jode/jode/expr/StoreInstruction.java +++ b/jode/jode/expr/StoreInstruction.java @@ -112,6 +112,7 @@ public class StoreInstruction extends Operator throws java.io.IOException { subExpressions[0].dumpExpression(writer, 950); + writer.breakOp(); writer.print(getOperatorString()); subExpressions[1].dumpExpression(writer, 100); } diff --git a/jode/jode/expr/StringAddOperator.java b/jode/jode/expr/StringAddOperator.java index 4c3c473..f4d695a 100644 --- a/jode/jode/expr/StringAddOperator.java +++ b/jode/jode/expr/StringAddOperator.java @@ -49,10 +49,14 @@ public class StringAddOperator extends Operator { throws java.io.IOException { if (!subExpressions[0].getType().isOfType(Type.tString) - && !subExpressions[1].getType().isOfType(Type.tString)) - writer.print("\"\" + "); + && !subExpressions[1].getType().isOfType(Type.tString)) { + writer.print("\"\""); + writer.breakOp(); + writer.print(getOperatorString()); + } subExpressions[0].dumpExpression(writer, 610); + writer.breakOp(); writer.print(getOperatorString()); subExpressions[1].dumpExpression(writer, 611); } diff --git a/jode/jode/flow/ConditionalBlock.java b/jode/jode/flow/ConditionalBlock.java index a47a5f7..d7d007b 100644 --- a/jode/jode/flow/ConditionalBlock.java +++ b/jode/jode/flow/ConditionalBlock.java @@ -123,7 +123,7 @@ public class ConditionalBlock extends InstructionContainer { throws java.io.IOException { writer.print("IF ("); - instr.dumpExpression(writer); + instr.dumpExpression(writer.EXPL_PAREN, writer); writer.println(")"); writer.tab(); trueBlock.dumpSource(writer); diff --git a/jode/jode/flow/IfThenElseBlock.java.in b/jode/jode/flow/IfThenElseBlock.java.in index e91260a..7936a2f 100644 --- a/jode/jode/flow/IfThenElseBlock.java.in +++ b/jode/jode/flow/IfThenElseBlock.java.in @@ -165,7 +165,7 @@ public class IfThenElseBlock extends StructuredBlock { { boolean needBrace = thenBlock.needsBraces(); writer.print("if ("); - cond.dumpExpression(writer); + cond.dumpExpression(writer.EXPL_PAREN, writer); writer.print(")"); if (needBrace) writer.openBrace(); diff --git a/jode/jode/flow/InstructionBlock.java.in b/jode/jode/flow/InstructionBlock.java.in index 8738f18..ad8a4dc 100644 --- a/jode/jode/flow/InstructionBlock.java.in +++ b/jode/jode/flow/InstructionBlock.java.in @@ -140,15 +140,21 @@ public class InstructionBlock extends InstructionContainer { StoreInstruction store = (StoreInstruction) instr; LocalInfo local = ((LocalStoreOperator) store.getLValue()).getLocalInfo(); + writer.startOp(writer.NO_PAREN, 0); local.dumpDeclaration(writer); + writer.breakOp(); writer.print(" = "); - store.getSubExpressions()[1].dumpExpression(writer); + store.getSubExpressions()[1].dumpExpression(writer.IMPL_PAREN, + writer); + writer.endOp(); } else { - if (instr.getType() != Type.tVoid) - writer.print("PUSH "); - try { - instr.dumpExpression(writer); + + if (instr.getType() != Type.tVoid) { + writer.print("PUSH "); + instr.dumpExpression(writer.IMPL_PAREN, writer); + } else + instr.dumpExpression(writer.NO_PAREN, writer); } catch (RuntimeException ex) { writer.print("(RUNTIME ERROR IN EXPRESSION)"); } diff --git a/jode/jode/flow/LoopBlock.java.in b/jode/jode/flow/LoopBlock.java.in index c602bd3..0d050bc 100644 --- a/jode/jode/flow/LoopBlock.java.in +++ b/jode/jode/flow/LoopBlock.java.in @@ -313,7 +313,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock { writer.print("for (;;)"); else { writer.print("while ("); - cond.dumpExpression(writer); + cond.dumpExpression(writer.EXPL_PAREN, writer); writer.print(")"); } break; @@ -322,21 +322,30 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock { break; case FOR: writer.print("for ("); + writer.startOp(writer.EXPL_PAREN, 0); if (initInstr != null) { if (isDeclaration) { - writer.printType(((LocalStoreOperator) - ((CombineableOperator) initInstr) - .getLValue()) - .getLocalInfo().getType().getHint()); - writer.print(" "); - } - initInstr.dumpExpression(writer); - } else + StoreInstruction store = (StoreInstruction) initInstr; + LocalInfo local = ((LocalStoreOperator) store + .getLValue()).getLocalInfo(); + writer.startOp(writer.NO_PAREN, 1); + local.dumpDeclaration(writer); + writer.breakOp(); + writer.print(" = "); + store.getSubExpressions()[1].dumpExpression(writer, 100); + writer.endOp(); + } else + initInstr.dumpExpression(writer.NO_PAREN, writer); + } else { writer.print("/**/"); + } writer.print("; "); - cond.dumpExpression(writer); + writer.breakOp(); + cond.dumpExpression(writer.IMPL_PAREN, writer); writer.print("; "); - incrInstr.dumpExpression(writer); + writer.breakOp(); + incrInstr.dumpExpression(writer.NO_PAREN, writer); + writer.endOp(); writer.print(")"); break; } @@ -351,13 +360,12 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock { if (needBrace) writer.closeBraceContinue(); writer.print("while ("); - cond.dumpExpression(writer); + cond.dumpExpression(writer.EXPL_PAREN, writer); writer.println(");"); } else if (needBrace) writer.closeBrace(); } - boolean mayChangeJump = true; /** diff --git a/jode/jode/flow/ReturnBlock.java b/jode/jode/flow/ReturnBlock.java index 88605dc..de0c3de 100644 --- a/jode/jode/flow/ReturnBlock.java +++ b/jode/jode/flow/ReturnBlock.java @@ -77,7 +77,7 @@ public class ReturnBlock extends InstructionContainer { writer.print("return"); if (instr != null) { writer.print(" "); - instr.dumpExpression(writer); + instr.dumpExpression(writer.IMPL_PAREN, writer); } writer.println(";"); } diff --git a/jode/jode/flow/SwitchBlock.java b/jode/jode/flow/SwitchBlock.java index 0b75a4d..7fba962 100644 --- a/jode/jode/flow/SwitchBlock.java +++ b/jode/jode/flow/SwitchBlock.java @@ -195,7 +195,7 @@ implements BreakableBlock { writer.tab(); } writer.print("switch ("); - instr.dumpExpression(writer); + instr.dumpExpression(writer.EXPL_PAREN, writer); writer.print(")"); writer.openBrace(); for (int i=0; i < caseBlocks.length; i++) diff --git a/jode/jode/flow/SynchronizedBlock.java.in b/jode/jode/flow/SynchronizedBlock.java.in index be3c331..cdec0f9 100644 --- a/jode/jode/flow/SynchronizedBlock.java.in +++ b/jode/jode/flow/SynchronizedBlock.java.in @@ -89,7 +89,7 @@ public class SynchronizedBlock extends StructuredBlock { writer.println("MISSING MONITORENTER"); writer.print("synchronized ("); if (object != null) - object.dumpExpression(writer); + object.dumpExpression(writer.EXPL_PAREN, writer); else writer.print(local.getName()); writer.print(")"); diff --git a/jode/jode/flow/ThrowBlock.java b/jode/jode/flow/ThrowBlock.java index c994278..bf6937d 100644 --- a/jode/jode/flow/ThrowBlock.java +++ b/jode/jode/flow/ThrowBlock.java @@ -33,7 +33,7 @@ public class ThrowBlock extends ReturnBlock { throws java.io.IOException { writer.print("throw "); - instr.dumpExpression(writer); + instr.dumpExpression(writer.NO_PAREN, writer); writer.println(";"); } }