Line breaking added.

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1227 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
jochen 25 years ago
parent b8e6d80e8c
commit 92878b6692
  1. 4
      jode/NEWS
  2. 37
      jode/jode/decompiler/ClassAnalyzer.java.in
  3. 7
      jode/jode/decompiler/FieldAnalyzer.java.in
  4. 32
      jode/jode/decompiler/MethodAnalyzer.java.in
  5. 598
      jode/jode/decompiler/TabbedPrintWriter.java
  6. 1
      jode/jode/expr/ArrayLoadOperator.java
  7. 1
      jode/jode/expr/BinaryOperator.java
  8. 2
      jode/jode/expr/CheckCastOperator.java
  9. 3
      jode/jode/expr/CompareBinaryOperator.java
  10. 3
      jode/jode/expr/CompareUnaryOperator.java
  11. 16
      jode/jode/expr/ConstantArrayOperator.java
  12. 71
      jode/jode/expr/Expression.java.in
  13. 18
      jode/jode/expr/FieldOperator.java.in
  14. 9
      jode/jode/expr/IfThenElseOperator.java
  15. 4
      jode/jode/expr/InstanceOfOperator.java
  16. 81
      jode/jode/expr/InvokeOperator.java.in
  17. 1
      jode/jode/expr/StoreInstruction.java
  18. 8
      jode/jode/expr/StringAddOperator.java
  19. 2
      jode/jode/flow/ConditionalBlock.java
  20. 2
      jode/jode/flow/IfThenElseBlock.java.in
  21. 16
      jode/jode/flow/InstructionBlock.java.in
  22. 34
      jode/jode/flow/LoopBlock.java.in
  23. 2
      jode/jode/flow/ReturnBlock.java
  24. 2
      jode/jode/flow/SwitchBlock.java
  25. 2
      jode/jode/flow/SynchronizedBlock.java.in
  26. 2
      jode/jode/flow/ThrowBlock.java

@ -1,3 +1,7 @@
New in 1.0.94
* break long lines
* small bug fixes
New in 1.0.93 New in 1.0.93
* anonymous and inner class decompilation reworked. * anonymous and inner class decompilation reworked.
* replaced a bash specific construct in acinclude.m4 * replaced a bash specific construct in acinclude.m4

@ -177,11 +177,11 @@ public class ClassAnalyzer
return outerValues; return outerValues;
} }
public void addBlockInitializer(int index, public void addBlockInitializer(int index, StructuredBlock initializer) {
StructuredBlock initializer) {
if (blockInitializers[index] == null) if (blockInitializers[index] == null)
blockInitializers[index] = initializer; blockInitializers[index] = initializer;
blockInitializers[index].appendBlock(initializer); else
blockInitializers[index].appendBlock(initializer);
} }
public void initialize() { public void initialize() {
@ -423,7 +423,7 @@ public class ClassAnalyzer
for (int i=0; i< fields.length; i++) { for (int i=0; i< fields.length; i++) {
if (blockInitializers[i] != null) { if (blockInitializers[i] != null) {
if (needNewLine) if (needNewLine)
writer.println(""); writer.println();
writer.openBrace(); writer.openBrace();
writer.tab(); writer.tab();
blockInitializers[i].dumpSource(writer); blockInitializers[i].dumpSource(writer);
@ -439,13 +439,13 @@ public class ClassAnalyzer
if (fields[i].skipWriting()) if (fields[i].skipWriting())
continue; continue;
if (needFieldNewLine) if (needFieldNewLine)
writer.println(""); writer.println();
fields[i].dumpSource(writer); fields[i].dumpSource(writer);
needNewLine = true; needNewLine = true;
} }
if (blockInitializers[fields.length] != null) { if (blockInitializers[fields.length] != null) {
if (needNewLine) if (needNewLine)
writer.println(""); writer.println();
writer.openBrace(); writer.openBrace();
writer.tab(); writer.tab();
blockInitializers[fields.length].dumpSource(writer); blockInitializers[fields.length].dumpSource(writer);
@ -455,7 +455,7 @@ public class ClassAnalyzer
} }
for (int i=0; i< inners.length; i++) { for (int i=0; i< inners.length; i++) {
if (needNewLine) if (needNewLine)
writer.println(""); writer.println();
if ((Options.options & Options.OPTION_IMMEDIATE) != 0) { if ((Options.options & Options.OPTION_IMMEDIATE) != 0) {
// We now do the analyzation we skipped before. // We now do the analyzation we skipped before.
@ -489,7 +489,7 @@ public class ClassAnalyzer
if (methods[i].skipWriting()) if (methods[i].skipWriting())
continue; continue;
if (needNewLine) if (needNewLine)
writer.println(""); writer.println();
if (pl != null) { if (pl != null) {
double methodCompl = methods[i].getComplexity() * subScale; double methodCompl = methods[i].getComplexity() * subScale;
@ -520,6 +520,7 @@ public class ClassAnalyzer
return; return;
} }
writer.startOp(writer.NO_PAREN, 0);
/* Clear the SUPER bit, which is also used as SYNCHRONIZED bit. */ /* Clear the SUPER bit, which is also used as SYNCHRONIZED bit. */
int modifiedModifiers = modifiers & ~Modifier.SYNCHRONIZED; int modifiedModifiers = modifiers & ~Modifier.SYNCHRONIZED;
if (clazz.isInterface()) if (clazz.isInterface())
@ -538,26 +539,30 @@ public class ClassAnalyzer
/* interface is in modif */ /* interface is in modif */
if (!clazz.isInterface()) if (!clazz.isInterface())
writer.print("class "); writer.print("class ");
writer.println(name); writer.print(name);
writer.tab();
ClassInfo superClazz = clazz.getSuperclass(); ClassInfo superClazz = clazz.getSuperclass();
if (superClazz != null && if (superClazz != null &&
superClazz != ClassInfo.javaLangObject) { superClazz != ClassInfo.javaLangObject) {
writer.println("extends " + (writer.getClassString writer.breakOp();
(superClazz, Scope.CLASSNAME))); writer.print(" extends " + (writer.getClassString
(superClazz, Scope.CLASSNAME)));
} }
ClassInfo[] interfaces = clazz.getInterfaces(); ClassInfo[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) { 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++) { for (int i=0; i < interfaces.length; i++) {
if (i > 0) if (i > 0) {
writer.print(", "); writer.print(", ");
writer.breakOp();
}
writer.print(writer.getClassString writer.print(writer.getClassString
(interfaces[i], Scope.CLASSNAME)); (interfaces[i], Scope.CLASSNAME));
} }
writer.println(""); writer.endOp();
} }
writer.untab(); writer.println();
writer.openBrace(); writer.openBrace();
writer.tab(); writer.tab();

@ -176,6 +176,7 @@ public class FieldAnalyzer implements Analyzer {
| Modifier.STATIC | Modifier.STATIC
| Modifier.FINAL); | Modifier.FINAL);
*/ */
writer.startOp(writer.NO_PAREN, 0);
String modif = Modifier.toString(modifiedModifiers); String modif = Modifier.toString(modifiedModifiers);
if (modif.length() > 0) if (modif.length() > 0)
writer.print(modif+" "); writer.print(modif+" ");
@ -183,9 +184,11 @@ public class FieldAnalyzer implements Analyzer {
writer.printType(type); writer.printType(type);
writer.print(" " + fieldName); writer.print(" " + fieldName);
if (constant != null) { if (constant != null) {
writer.print(" = "); writer.breakOp();
constant.dumpExpression(writer); writer.print(" = ");
constant.dumpExpression(writer.IMPL_PAREN, writer);
} }
writer.endOp();
writer.println(";"); writer.println(";");
} }

@ -838,17 +838,18 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (isConstructor() && isStatic()) if (isConstructor() && isStatic())
modifiedModifiers &= ~Modifier.FINAL; modifiedModifiers &= ~Modifier.FINAL;
writer.startOp(writer.NO_PAREN, 1);
String delim =""; String delim = "";
if (minfo.isSynthetic()) { if (minfo.isSynthetic()) {
writer.print("/*synthetic*/"); writer.print("/*synthetic*/");
delim = " "; delim = " ";
} }
String modif = Modifier.toString(modifiedModifiers); String modif = Modifier.toString(modifiedModifiers);
writer.print(delim + modif); if (modif.length() > 0) {
if (modif.length() > 0) writer.print(delim + modif);
delim = " "; delim = " ";
}
if (isConstructor if (isConstructor
&& (isStatic() && (isStatic()
|| (classAnalyzer.getName() == null || (classAnalyzer.getName() == null
@ -862,24 +863,35 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
writer.printType(getReturnType()); writer.printType(getReturnType());
writer.print(" " + methodName); writer.print(" " + methodName);
} }
writer.breakOp();
writer.print("("); 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++) { for (int i = offset; i < param.length; i++) {
if (i > offset) if (i > offset) {
writer.print(", "); writer.print(", ");
writer.breakOp();
}
param[i].dumpDeclaration(writer); param[i].dumpDeclaration(writer);
} }
writer.endOp();
writer.print(")"); writer.print(")");
} }
if (exceptions.length > 0) { if (exceptions.length > 0) {
writer.println(""); writer.breakOp();
writer.print("throws "); writer.print(" throws ");
writer.startOp(writer.EXPL_PAREN, 2);
for (int i= 0; i< exceptions.length; i++) { for (int i= 0; i< exceptions.length; i++) {
if (i > 0) if (i > 0) {
writer.print(", "); writer.print(",");
writer.breakOp();
writer.print(" ");
}
writer.printType(exceptions[i]); writer.printType(exceptions[i]);
} }
writer.endOp();
} }
writer.endOp();
if (code != null) { if (code != null) {
writer.openBrace(); writer.openBrace();
writer.tab(); writer.tab();

@ -20,34 +20,467 @@
package jode.decompiler; package jode.decompiler;
import java.io.*; import java.io.*;
import java.util.Stack; import java.util.Stack;
import java.util.Vector;
import java.util.Enumeration;
import jode.AssertError;
import jode.GlobalOptions; import jode.GlobalOptions;
import jode.bytecode.ClassInfo; import jode.bytecode.ClassInfo;
import jode.bytecode.InnerClassInfo; import jode.bytecode.InnerClassInfo;
import jode.type.*; import jode.type.*;
public class TabbedPrintWriter { public class TabbedPrintWriter {
boolean atbol; /* The indentation size. */
int indentsize; private int indentsize;
int currentIndent = 0; /* The size of a tab, MAXINT if we shouldn't use tabs at all. */
String indentStr = ""; private int tabWidth;
PrintWriter pw; private int lineWidth;
ImportHandler imports; private int currentIndent = 0;
Stack scopes = new Stack(); 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, public TabbedPrintWriter (OutputStream os, ImportHandler imports,
boolean autoFlush) { boolean autoFlush) {
pw = new PrintWriter(os, autoFlush); pw = new PrintWriter(os, autoFlush);
this.imports = imports; this.imports = imports;
this.indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK); init();
atbol = true;
} }
public TabbedPrintWriter (Writer os, ImportHandler imports, public TabbedPrintWriter (Writer os, ImportHandler imports,
boolean autoFlush) { boolean autoFlush) {
pw = new PrintWriter(os, autoFlush); pw = new PrintWriter(os, autoFlush);
this.imports = imports; this.imports = imports;
this.indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK); init();
atbol = true;
} }
public TabbedPrintWriter (OutputStream os, ImportHandler imports) { public TabbedPrintWriter (OutputStream os, ImportHandler imports) {
@ -66,82 +499,101 @@ public class TabbedPrintWriter {
this(os, null); this(os, null);
} }
/** public void init() {
* Convert the numeric indentation to a string. this.indentsize = (Options.outputStyle & Options.TAB_SIZE_MASK);
*/ this.tabWidth = 8;
protected void makeIndentStr() { this.lineWidth = 79;
int tabs = (currentIndent >> 3); currentLine = new StringBuffer();
// This is a very fast implementation. currentBP = new BreakPoint(null, 0);
if (tabs <= 20) currentBP.startOp(DONT_BREAK, 1, 0);
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 tab() { public void tab() {
currentIndent += indentsize; currentIndent += indentsize;
makeIndentStr(); indentStr = makeIndentStr(currentIndent);
} }
public void untab() { public void untab() {
currentIndent -= indentsize; 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) { public void println(String str) {
if (atbol) print(str);
pw.print(indentStr); println();
pw.println(str);
atbol = true;
} }
public void 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(); pw.println();
atbol = true;
currentLine.setLength(0);
currentBP = new BreakPoint(null, 0);
currentBP.startOp(DONT_BREAK, 1, 0);
} }
public void print(String str) { public void print(String str) {
if (atbol) currentLine.append(str);
pw.print(indentStr);
pw.print(str);
atbol = false;
} }
public void printType(Type type) { public void printType(Type type) {
print(getTypeString(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) { public void pushScope(Scope scope) {
scopes.push(scope); scopes.push(scope);
} }
@ -282,6 +734,24 @@ public class TabbedPrintWriter {
return type.toString(); 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. * Print a opening brace with the current indentation style.
* Called at the end of the line of the instance that opens the * 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) if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
println("{"); println("{");
else { else {
if (!atbol) if (currentLine.length() > 0)
println(); println();
if (currentIndent > 0) if (currentIndent > 0)
tab(); tab();

@ -50,6 +50,7 @@ public class ArrayLoadOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer) public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException { throws java.io.IOException {
subExpressions[0].dumpExpression(writer, 950); subExpressions[0].dumpExpression(writer, 950);
writer.breakOp();
writer.print("["); writer.print("[");
subExpressions[1].dumpExpression(writer, 0); subExpressions[1].dumpExpression(writer, 0);
writer.print("]"); writer.print("]");

@ -87,6 +87,7 @@ public class BinaryOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer) public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException { throws java.io.IOException {
subExpressions[0].dumpExpression(writer, getPriority()); subExpressions[0].dumpExpression(writer, getPriority());
writer.breakOp();
writer.print(getOperatorString()); writer.print(getOperatorString());
subExpressions[1].dumpExpression(writer, getPriority()+1); subExpressions[1].dumpExpression(writer, getPriority()+1);
} }

@ -56,6 +56,7 @@ public class CheckCastOperator extends Operator {
writer.print("("); writer.print("(");
writer.printType(castType); writer.printType(castType);
writer.print(") "); writer.print(") ");
writer.breakOp();
/* There are special cases where a cast isn't allowed. We must cast /* 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 * to the common super type before. This cases always give a runtime
@ -66,6 +67,7 @@ public class CheckCastOperator extends Operator {
writer.print("("); writer.print("(");
writer.printType(superType); writer.printType(superType);
writer.print(") "); writer.print(") ");
writer.breakOp();
} }
subExpressions[0].dumpExpression(writer, 700); subExpressions[0].dumpExpression(writer, 700);
} }

@ -86,7 +86,8 @@ public class CompareBinaryOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer) public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException { throws java.io.IOException {
subExpressions[0].dumpExpression(writer, getPriority()); subExpressions[0].dumpExpression(writer, getPriority()+1);
writer.breakOp();
writer.print(getOperatorString()); writer.print(getOperatorString());
subExpressions[1].dumpExpression(writer, getPriority()+1); subExpressions[1].dumpExpression(writer, getPriority()+1);
} }

@ -108,7 +108,8 @@ public class CompareUnaryOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer) public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException { throws java.io.IOException {
subExpressions[0].dumpExpression(writer, getPriority()); subExpressions[0].dumpExpression(writer, getPriority()+1);
writer.breakOp();
writer.print(getOperatorString()); writer.print(getOperatorString());
writer.print(objectType?"null":"0"); writer.print(objectType?"null":"0");
} }

@ -99,24 +99,22 @@ public class ConstantArrayOperator extends Operator {
if (!isInitializer) { if (!isInitializer) {
writer.print("new "); writer.print("new ");
writer.printType(type.getHint()); writer.printType(type.getHint());
writer.breakOp();
writer.print(" "); writer.print(" ");
} }
writer.openBraceNoSpace(); writer.print("{ ");
writer.tab(); writer.startOp(writer.EXPL_PAREN, 0);
for (int i=0; i< subExpressions.length; i++) { for (int i=0; i< subExpressions.length; i++) {
if (i>0) { if (i>0) {
if (i % 10 == 0) writer.print(", ");
writer.println(","); writer.breakOp();
else
writer.print(", ");
} }
if (subExpressions[i] != null) if (subExpressions[i] != null)
subExpressions[i].dumpExpression(writer, 0); subExpressions[i].dumpExpression(writer, 0);
else else
empty.dumpExpression(writer, 0); empty.dumpExpression(writer, 0);
} }
writer.println(); writer.endOp();
writer.untab(); writer.print(" }");
writer.closeBraceNoSpace();
} }
} }

@ -96,7 +96,6 @@ public abstract class Expression {
return parent; return parent;
} }
/** /**
* Get priority of the operator. * Get priority of the operator.
* Currently this priorities are known: * Currently this priorities are known:
@ -121,6 +120,13 @@ public abstract class Expression {
*/ */
public abstract int getPriority(); public abstract int getPriority();
/**
* Get the penalty for splitting up this operator.
*/
public int getBreakPenalty() {
return 0;
}
/** /**
* Get the number of operands. * Get the number of operands.
* @return The number of stack entries this expression needs. * @return The number of stack entries this expression needs.
@ -237,29 +243,56 @@ public abstract class Expression {
public abstract void dumpExpression(TabbedPrintWriter writer) public abstract void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException; 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) public void dumpExpression(TabbedPrintWriter writer, int minPriority)
throws java.io.IOException { throws java.io.IOException {
int options;
boolean needParen1 = false, needParen2 = false; boolean needParen1 = false, needParen2 = false;
if (type == Type.tError) { boolean needEndOp1 = false, needEndOp2 = false;
if (minPriority > 700) {
needParen1 = true; String typecast = "";
writer.print("(");
} if (type == Type.tError)
writer.print("/*TYPE ERROR*/ "); typecast = "/*TYPE_ERROR*/";
minPriority = 700;
}
else if ((GlobalOptions.debuggingFlags else if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_TYPES) != 0) { & GlobalOptions.DEBUG_TYPES) != 0)
typecast = "(TYPE "+type+")";
if (typecast != "") {
if (minPriority > 700) { if (minPriority > 700) {
needParen1 = true; needParen1 = true;
needEndOp1 = true;
writer.print("("); 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; minPriority = 700;
} }
if (getPriority() < minPriority) {
int priority = getPriority();
if (priority < minPriority) {
needParen2 = true; needParen2 = true;
needEndOp2 = true;
writer.print("("); 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 { try {
@ -268,10 +301,16 @@ public abstract class Expression {
writer.print("(RUNTIME ERROR IN EXPRESSION)"); writer.print("(RUNTIME ERROR IN EXPRESSION)");
} }
if (needParen2) if (needEndOp2) {
writer.print(")"); writer.endOp();
if (needParen1) if (needParen2)
writer.print(")"); writer.print(")");
}
if (needEndOp1) {
writer.endOp();
if (needParen1)
writer.print(")");
}
} }
public String toString() { public String toString() {

@ -181,15 +181,22 @@ public abstract class FieldOperator extends Operator {
if (!classType.equals(Type.tClass(methodAnalyzer.getClazz())) if (!classType.equals(Type.tClass(methodAnalyzer.getClazz()))
|| methodAnalyzer.findLocal(fieldName) != null) { || methodAnalyzer.findLocal(fieldName) != null) {
writer.printType(classType); writer.printType(classType);
writer.breakOp();
writer.print("."); writer.print(".");
} }
writer.print(fieldName); writer.print(fieldName);
} else if (needsCast(subExpressions[0].getType().getCanonic())) { } else if (needsCast(subExpressions[0].getType().getCanonic())) {
writer.print("(("); writer.print("(");
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(classType); writer.printType(classType);
writer.print(") "); writer.print(") ");
writer.breakOp();
subExpressions[0].dumpExpression(writer, 700); subExpressions[0].dumpExpression(writer, 700);
writer.print(")."); writer.endOp();
writer.print(")");
writer.breakOp();
writer.print(".");
writer.print(fieldName); writer.print(fieldName);
} else { } else {
if (opIsThis) { if (opIsThis) {
@ -200,6 +207,7 @@ public abstract class FieldOperator extends Operator {
if (scope == null || writer.conflicts(fieldName, scope, if (scope == null || writer.conflicts(fieldName, scope,
Scope.FIELDNAME)) { Scope.FIELDNAME)) {
thisOp.dumpExpression(writer, 950); thisOp.dumpExpression(writer, 950);
writer.breakOp();
writer.print("."); writer.print(".");
} else if (writer.conflicts(fieldName, scope, } else if (writer.conflicts(fieldName, scope,
Scope.AMBIGUOUSNAME) Scope.AMBIGUOUSNAME)
@ -216,16 +224,18 @@ public abstract class FieldOperator extends Operator {
ana = (ClassAnalyzer) ana.getParent(); ana = (ClassAnalyzer) ana.getParent();
if (ana == scope) if (ana == scope)
// For a simple outer class we can say this // For a simple outer class we can say this
writer.print("this."); writer.print("this");
else { else {
// For a class that owns a method that owns // For a class that owns a method that owns
// us, we have to give the full class name // us, we have to give the full class name
thisOp.dumpExpression(writer, 950); thisOp.dumpExpression(writer, 950);
writer.print(".");
} }
writer.breakOp();
writer.print(".");
} }
} else { } else {
subExpressions[0].dumpExpression(writer, 950); subExpressions[0].dumpExpression(writer, 950);
writer.breakOp();
writer.print("."); writer.print(".");
} }
writer.print(fieldName); writer.print(fieldName);

@ -103,15 +103,22 @@ public class IfThenElseOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer) public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException { throws java.io.IOException {
subExpressions[0].dumpExpression(writer, 201); subExpressions[0].dumpExpression(writer, 201);
writer.breakOp();
writer.print(" ? "); writer.print(" ? ");
int subPriority = 0;
if (!subExpressions[1].getType().getHint().isOfType if (!subExpressions[1].getType().getHint().isOfType
(subExpressions[2].getType())) { (subExpressions[2].getType())) {
writer.startOp(writer.IMPL_PAREN, 2);
/* We need a cast here */ /* We need a cast here */
writer.print("("); writer.print("(");
writer.printType(getType().getHint()); writer.printType(getType().getHint());
writer.print(") "); writer.print(") ");
subPriority = 700;
} }
subExpressions[1].dumpExpression(writer, 0); subExpressions[1].dumpExpression(writer, subPriority);
if (subPriority == 700)
writer.endOp();
writer.breakOp();
writer.print(" : "); writer.print(" : ");
subExpressions[2].dumpExpression(writer, 200); subExpressions[2].dumpExpression(writer, 200);
} }

@ -51,12 +51,16 @@ public class InstanceOfOperator extends Operator {
Type superType Type superType
= instanceType.getCastHelper(subExpressions[0].getType()); = instanceType.getCastHelper(subExpressions[0].getType());
if (superType != null) { if (superType != null) {
writer.startOp(writer.IMPL_PAREN, 2);
writer.print("("); writer.print("(");
writer.printType(superType); writer.printType(superType);
writer.print(") "); writer.print(") ");
writer.breakOp();
subExpressions[0].dumpExpression(writer, 700); subExpressions[0].dumpExpression(writer, 700);
writer.endOp();
} else } else
subExpressions[0].dumpExpression(writer, 550); subExpressions[0].dumpExpression(writer, 550);
writer.breakOp();
writer.print(" instanceof "); writer.print(" instanceof ");
writer.printType(instanceType); writer.printType(instanceType);
} }

@ -800,6 +800,10 @@ public final class InvokeOperator extends Operator
} }
} }
public int getBreakPenalty() {
return 5;
}
/* Invokes never equals: they may return different values even if /* Invokes never equals: they may return different values even if
* they have the same parameters. * they have the same parameters.
*/ */
@ -816,6 +820,7 @@ public final class InvokeOperator extends Operator
for (int i=0; i< subExpressions.length; i++) for (int i=0; i< subExpressions.length; i++)
paramTypes[i] = subExpressions[i].getType().getCanonic(); paramTypes[i] = subExpressions[i].getType().getCanonic();
writer.startOp(writer.NO_PAREN, 0);
switch (methodFlag) { switch (methodFlag) {
case CONSTRUCTOR: { case CONSTRUCTOR: {
@ -903,19 +908,25 @@ public final class InvokeOperator extends Operator
if (writer.conflicts(outer.name, scope, Scope.CLASSNAME)) { if (writer.conflicts(outer.name, scope, Scope.CLASSNAME)) {
qualifiedNew = true; qualifiedNew = true;
outerExpr.dumpExpression(writer, 950); outerExpr.dumpExpression(writer, 950);
writer.breakOp();
writer.print("."); writer.print(".");
} }
} else { } else {
qualifiedNew = true; qualifiedNew = true;
if (outerExpr.getType() instanceof NullType) { if (outerExpr.getType() instanceof NullType) {
writer.print("(("); writer.print("(");
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(Type.tClass writer.printType(Type.tClass
(ClassInfo.forName(outer.outer))); (ClassInfo.forName(outer.outer)));
writer.print(") "); writer.print(") ");
writer.breakOp();
outerExpr.dumpExpression(writer, 700); outerExpr.dumpExpression(writer, 700);
writer.endOp();
writer.print(")"); writer.print(")");
} else } else
outerExpr.dumpExpression(writer, 950); outerExpr.dumpExpression(writer, 950);
writer.breakOp();
writer.print("."); writer.print(".");
} }
} }
@ -940,9 +951,15 @@ public final class InvokeOperator extends Operator
break; break;
} }
writer.print("((UNCONSTRUCTED)"); writer.print("(");
subExpressions[0].dumpExpression(writer, 950); writer.startOp(writer.EXPL_PAREN, 0);
writer.print(")."); writer.print("(UNCONSTRUCTED)");
writer.breakOp();
subExpressions[0].dumpExpression(writer, 700);
writer.endOp();
writer.print(")");
writer.breakOp();
writer.print(".");
writer.printType(Type.tClass(clazz)); writer.printType(Type.tClass(clazz));
break; break;
} }
@ -956,17 +973,23 @@ public final class InvokeOperator extends Operator
ClassInfo superClazz = getClassInfo().getSuperclass(); ClassInfo superClazz = getClassInfo().getSuperclass();
paramTypes[0] = superClazz == null paramTypes[0] = superClazz == null
? Type.tObject : Type.tClass(superClazz); ? Type.tObject : Type.tClass(superClazz);
writer.breakOp();
writer.print("."); writer.print(".");
} else { } else {
/* XXX check if this is a private method. */ /* XXX check if this is a private method. */
} }
} else { } else {
writer.print("((NON VIRTUAL "); writer.print("(");
writer.startOp(writer.EXPL_PAREN, 0);
writer.print("(NON VIRTUAL ");
writer.printType(classType); writer.printType(classType);
writer.print(")"); writer.print(") ");
paramTypes[0] = classType; writer.breakOp();
subExpressions[0].dumpExpression(writer, 700); subExpressions[0].dumpExpression(writer, 700);
writer.print(")."); writer.endOp();
writer.print(")");
writer.breakOp();
writer.print(".");
} }
writer.print(methodName); writer.print(methodName);
break; break;
@ -978,13 +1001,18 @@ public final class InvokeOperator extends Operator
if (paramTypes[0].equals(classType)) if (paramTypes[0].equals(classType))
subExpressions[0].dumpExpression(writer, 950); subExpressions[0].dumpExpression(writer, 950);
else { else {
writer.print("(("); writer.print("(");
writer.startOp(writer.EXPL_PAREN, 0);
writer.print("(");
writer.printType(classType); writer.printType(classType);
writer.print(")"); writer.print(") ");
writer.breakOp();
paramTypes[0] = classType; paramTypes[0] = classType;
subExpressions[0].dumpExpression(writer, 700); subExpressions[0].dumpExpression(writer, 700);
writer.endOp();
writer.print(")"); writer.print(")");
} }
writer.breakOp();
writer.print("."); writer.print(".");
writer.print(methodName); writer.print(methodName);
break; break;
@ -996,6 +1024,7 @@ public final class InvokeOperator extends Operator
if (scope == null if (scope == null
||writer.conflicts(methodName, scope, Scope.METHODNAME)) { ||writer.conflicts(methodName, scope, Scope.METHODNAME)) {
writer.printType(classType); writer.printType(classType);
writer.breakOp();
writer.print("."); writer.print(".");
} }
writer.print(methodName); writer.print(methodName);
@ -1009,6 +1038,7 @@ public final class InvokeOperator extends Operator
Scope.CLASSSCOPE); Scope.CLASSSCOPE);
if (writer.conflicts(methodName, scope, Scope.METHODNAME)) { if (writer.conflicts(methodName, scope, Scope.METHODNAME)) {
thisOp.dumpExpression(writer, 950); thisOp.dumpExpression(writer, 950);
writer.breakOp();
writer.print("."); writer.print(".");
} else if (/* This is a inherited field conflicting } else if (/* This is a inherited field conflicting
* with a field name in some outer class. * with a field name in some outer class.
@ -1020,61 +1050,78 @@ public final class InvokeOperator extends Operator
while (ana.getParent() instanceof ClassAnalyzer while (ana.getParent() instanceof ClassAnalyzer
&& ana != scope) && ana != scope)
ana = (ClassAnalyzer) ana.getParent(); ana = (ClassAnalyzer) ana.getParent();
if (ana == scope) if (ana == scope) {
// For a simple outer class we can say this // For a simple outer class we can say this
writer.print("this."); writer.print("this");
else { } else {
// For a class that owns a method that owns // For a class that owns a method that owns
// us, we have to give the full class name // us, we have to give the full class name
thisOp.dumpExpression(writer, 950); thisOp.dumpExpression(writer, 950);
writer.print(".");
} }
writer.breakOp();
writer.print(".");
} }
} else { } else {
if (needsCast(0, paramTypes)){ if (needsCast(0, paramTypes)){
writer.print("(("); writer.print("(");
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(classType); writer.printType(classType);
writer.print(") "); writer.print(") ");
writer.breakOp();
subExpressions[0].dumpExpression(writer, 700); subExpressions[0].dumpExpression(writer, 700);
writer.endOp();
writer.print(")"); writer.print(")");
paramTypes[0] = classType; paramTypes[0] = classType;
} else } else
subExpressions[0].dumpExpression(writer, 950); subExpressions[0].dumpExpression(writer, 950);
writer.breakOp();
writer.print("."); writer.print(".");
} }
writer.print(methodName); writer.print(methodName);
} }
writer.endOp();
writer.breakOp();
writer.print("("); writer.print("(");
writer.startOp(writer.EXPL_PAREN, 0);
boolean first = true; boolean first = true;
int offset = skippedArgs; int offset = skippedArgs;
while (arg < length) { while (arg < length) {
if (!first) if (!first) {
writer.print(", "); writer.print(", ");
else writer.breakOp();
} else
first = false; first = false;
int priority = 0; int priority = 0;
if (needsCast(arg, paramTypes)) { if (needsCast(arg, paramTypes)) {
Type castType = methodType.getParameterTypes()[arg-offset]; Type castType = methodType.getParameterTypes()[arg-offset];
writer.startOp(writer.IMPL_PAREN, 1);
writer.print("("); writer.print("(");
writer.printType(castType); writer.printType(castType);
writer.print(") "); writer.print(") ");
writer.breakOp();
paramTypes[arg] = castType; paramTypes[arg] = castType;
priority = 700; priority = 700;
} }
subExpressions[arg++].dumpExpression(writer, priority); subExpressions[arg++].dumpExpression(writer, priority);
if (priority == 700)
writer.endOp();
} }
writer.endOp();
writer.print(")"); writer.print(")");
if (anonymousNew) { if (anonymousNew) {
/* If this was an anonymous constructor call, we must now /* If this was an anonymous constructor call, we must now
* dump the source code of the anonymous class. * dump the source code of the anonymous class.
*/ */
Object state = writer.saveOps();
writer.openBrace(); writer.openBrace();
writer.tab(); writer.tab();
clazzAna.dumpBlock(writer); clazzAna.dumpBlock(writer);
writer.untab(); writer.untab();
writer.closeBraceNoSpace(); writer.closeBraceNoSpace();
writer.restoreOps(state);
} }
} }

@ -112,6 +112,7 @@ public class StoreInstruction extends Operator
throws java.io.IOException throws java.io.IOException
{ {
subExpressions[0].dumpExpression(writer, 950); subExpressions[0].dumpExpression(writer, 950);
writer.breakOp();
writer.print(getOperatorString()); writer.print(getOperatorString());
subExpressions[1].dumpExpression(writer, 100); subExpressions[1].dumpExpression(writer, 100);
} }

@ -49,10 +49,14 @@ public class StringAddOperator extends Operator {
throws java.io.IOException { throws java.io.IOException {
if (!subExpressions[0].getType().isOfType(Type.tString) if (!subExpressions[0].getType().isOfType(Type.tString)
&& !subExpressions[1].getType().isOfType(Type.tString)) && !subExpressions[1].getType().isOfType(Type.tString)) {
writer.print("\"\" + "); writer.print("\"\"");
writer.breakOp();
writer.print(getOperatorString());
}
subExpressions[0].dumpExpression(writer, 610); subExpressions[0].dumpExpression(writer, 610);
writer.breakOp();
writer.print(getOperatorString()); writer.print(getOperatorString());
subExpressions[1].dumpExpression(writer, 611); subExpressions[1].dumpExpression(writer, 611);
} }

@ -123,7 +123,7 @@ public class ConditionalBlock extends InstructionContainer {
throws java.io.IOException throws java.io.IOException
{ {
writer.print("IF ("); writer.print("IF (");
instr.dumpExpression(writer); instr.dumpExpression(writer.EXPL_PAREN, writer);
writer.println(")"); writer.println(")");
writer.tab(); writer.tab();
trueBlock.dumpSource(writer); trueBlock.dumpSource(writer);

@ -165,7 +165,7 @@ public class IfThenElseBlock extends StructuredBlock {
{ {
boolean needBrace = thenBlock.needsBraces(); boolean needBrace = thenBlock.needsBraces();
writer.print("if ("); writer.print("if (");
cond.dumpExpression(writer); cond.dumpExpression(writer.EXPL_PAREN, writer);
writer.print(")"); writer.print(")");
if (needBrace) if (needBrace)
writer.openBrace(); writer.openBrace();

@ -140,15 +140,21 @@ public class InstructionBlock extends InstructionContainer {
StoreInstruction store = (StoreInstruction) instr; StoreInstruction store = (StoreInstruction) instr;
LocalInfo local = LocalInfo local =
((LocalStoreOperator) store.getLValue()).getLocalInfo(); ((LocalStoreOperator) store.getLValue()).getLocalInfo();
writer.startOp(writer.NO_PAREN, 0);
local.dumpDeclaration(writer); local.dumpDeclaration(writer);
writer.breakOp();
writer.print(" = "); writer.print(" = ");
store.getSubExpressions()[1].dumpExpression(writer); store.getSubExpressions()[1].dumpExpression(writer.IMPL_PAREN,
writer);
writer.endOp();
} else { } else {
if (instr.getType() != Type.tVoid)
writer.print("PUSH ");
try { 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) { } catch (RuntimeException ex) {
writer.print("(RUNTIME ERROR IN EXPRESSION)"); writer.print("(RUNTIME ERROR IN EXPRESSION)");
} }

@ -313,7 +313,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
writer.print("for (;;)"); writer.print("for (;;)");
else { else {
writer.print("while ("); writer.print("while (");
cond.dumpExpression(writer); cond.dumpExpression(writer.EXPL_PAREN, writer);
writer.print(")"); writer.print(")");
} }
break; break;
@ -322,21 +322,30 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
break; break;
case FOR: case FOR:
writer.print("for ("); writer.print("for (");
writer.startOp(writer.EXPL_PAREN, 0);
if (initInstr != null) { if (initInstr != null) {
if (isDeclaration) { if (isDeclaration) {
writer.printType(((LocalStoreOperator) StoreInstruction store = (StoreInstruction) initInstr;
((CombineableOperator) initInstr) LocalInfo local = ((LocalStoreOperator) store
.getLValue()) .getLValue()).getLocalInfo();
.getLocalInfo().getType().getHint()); writer.startOp(writer.NO_PAREN, 1);
writer.print(" "); local.dumpDeclaration(writer);
} writer.breakOp();
initInstr.dumpExpression(writer); writer.print(" = ");
} else store.getSubExpressions()[1].dumpExpression(writer, 100);
writer.endOp();
} else
initInstr.dumpExpression(writer.NO_PAREN, writer);
} else {
writer.print("/**/"); writer.print("/**/");
}
writer.print("; "); writer.print("; ");
cond.dumpExpression(writer); writer.breakOp();
cond.dumpExpression(writer.IMPL_PAREN, writer);
writer.print("; "); writer.print("; ");
incrInstr.dumpExpression(writer); writer.breakOp();
incrInstr.dumpExpression(writer.NO_PAREN, writer);
writer.endOp();
writer.print(")"); writer.print(")");
break; break;
} }
@ -351,13 +360,12 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
if (needBrace) if (needBrace)
writer.closeBraceContinue(); writer.closeBraceContinue();
writer.print("while ("); writer.print("while (");
cond.dumpExpression(writer); cond.dumpExpression(writer.EXPL_PAREN, writer);
writer.println(");"); writer.println(");");
} else if (needBrace) } else if (needBrace)
writer.closeBrace(); writer.closeBrace();
} }
boolean mayChangeJump = true; boolean mayChangeJump = true;
/** /**

@ -77,7 +77,7 @@ public class ReturnBlock extends InstructionContainer {
writer.print("return"); writer.print("return");
if (instr != null) { if (instr != null) {
writer.print(" "); writer.print(" ");
instr.dumpExpression(writer); instr.dumpExpression(writer.IMPL_PAREN, writer);
} }
writer.println(";"); writer.println(";");
} }

@ -195,7 +195,7 @@ implements BreakableBlock {
writer.tab(); writer.tab();
} }
writer.print("switch ("); writer.print("switch (");
instr.dumpExpression(writer); instr.dumpExpression(writer.EXPL_PAREN, writer);
writer.print(")"); writer.print(")");
writer.openBrace(); writer.openBrace();
for (int i=0; i < caseBlocks.length; i++) for (int i=0; i < caseBlocks.length; i++)

@ -89,7 +89,7 @@ public class SynchronizedBlock extends StructuredBlock {
writer.println("MISSING MONITORENTER"); writer.println("MISSING MONITORENTER");
writer.print("synchronized ("); writer.print("synchronized (");
if (object != null) if (object != null)
object.dumpExpression(writer); object.dumpExpression(writer.EXPL_PAREN, writer);
else else
writer.print(local.getName()); writer.print(local.getName());
writer.print(")"); writer.print(")");

@ -33,7 +33,7 @@ public class ThrowBlock extends ReturnBlock {
throws java.io.IOException throws java.io.IOException
{ {
writer.print("throw "); writer.print("throw ");
instr.dumpExpression(writer); instr.dumpExpression(writer.NO_PAREN, writer);
writer.println(";"); writer.println(";");
} }
} }

Loading…
Cancel
Save