Pascal style.

Better gnu style.
Some bug fixes (see Changelog).


git-svn-id: https://svn.code.sf.net/p/jode/code/branches/branch_1_1@1292 379699f6-c40d-0410-875b-85095c16579e
branch_1_1
hoenicke 24 years ago
parent 816bca302d
commit cb12d3ead2
  1. 53
      jode/ChangeLog
  2. 2
      jode/THANKS
  3. 9
      jode/jode/decompiler/ClassAnalyzer.java.in
  4. 2
      jode/jode/decompiler/Decompiler.java
  5. 5
      jode/jode/decompiler/FieldAnalyzer.java.in
  6. 2
      jode/jode/decompiler/Main.java
  7. 7
      jode/jode/decompiler/MethodAnalyzer.java.in
  8. 11
      jode/jode/decompiler/Options.java
  9. 71
      jode/jode/decompiler/TabbedPrintWriter.java
  10. 28
      jode/jode/expr/InvokeOperator.java.in
  11. 11
      jode/jode/expr/PopOperator.java
  12. 3
      jode/jode/expr/UnaryOperator.java
  13. 42
      jode/jode/jvm/SyntheticAnalyzer.java.in
  14. 11
      jode/jode/type/NullType.java

@ -0,0 +1,53 @@
Tue Jan 30 15:35:19 2001 Jochen Hoenicke <jochen@gnu.org>
* jode/decompiler/TabbedPrintWriter.java: Better gnu style handling:
(openBraceClass) (closeBraceClass)
(openBraceNoIndent) (closeBraceNoIndent): new functions.
(closeBraceNoSpace): Removed.
* jode/decompiler/Options.java (GNU_SPACING): new constant.
(GNU_STYLE): changed to include GNU_SPACING.
* jode/decompiler/ClassAnalyzer.java.in (dumpSource): Use
open/closeBraceClass.
* jode/decompiler/MethodAnalyzer.java.in (dumpSource): Use
open/closeBraceNoIndent. Insert a space for GNU_SPACING.
* jode/decompiler/InvokeOperator.java.in (dumpExpression): Insert
a space for GNU_SPACING, use open/closeBraceClass for inner
classes.
* jode/decompiler/UnaryOperator.java (dumpExpression): Insert
a space for GNU_SPACING.
Tue Jan 30 15:28:10 2001 Jochen Hoenicke <jochen@gnu.org>
Added pascal style from Rolf Howarth <rolf@squarebox.co.uk>
* jode/decompiler/Options.java (PASCAL_STYLE): new constant.
(BRACE_FLUSH_LEFT): dito.
* jode/decompiler/Decompiler.java (setOption): detect pascal option.
* jode/decompiler/Main.java (main): dito.
* jode/decompiler/TabbedPrintWriter.java (openBrace,
openBraceContinue, closeBrace, closeBraceNoSpace,
closeBraceContinue): handle flush left.
Tue Jan 30 00:28:10 2001 Jochen Hoenicke <jochen@gnu.org>
* jode/type/NullType.java (intersection): Removed, since the
version in ReferenceType is more correct. Before
tNull.isOfType(tRange(X,tNull)) returned false, which lead to
incorrect behaviour in InvokeOperator.needsCast.
* jode/decompiler/FieldAnalyzer.java.in (dumpSource): Removed the
"= null" hack for final fields; it was not correct, since the
field could be initialized in a constructor.
* jode/decompiler/TabbedPrintWriter.java (BreakPoint.endOp):
Simplified the code, copy options always from child.
* jode/jvm/SyntheticAnalyzer.java.in (unifyParam): new field.
(checkConstructorAccess): Allow the special Parameter, whose
purpose is to distinguish the wrapper from the real constructor
and give him a "$" in the type signature, to appear at every
position. It doesn't appear at position 1 for inner classes.
Store the position in unifyParam.
* jode/expr/InvokeOperator.java (isGetClass): Allow the method to
be declared inside an outer class: We simply check if we can get
the method analyzer.
(simplify): handle unifyParam.
* jode/expr/PopOperator.java (getBreakPenalty): return penalty of
inner expression. (dumpExpression): Call dumpExpression of
subexpression immediately without priority.

@ -1 +1,3 @@
Rolf Howarth <rolf@squarebox.co.uk> for pascal indentaton style.
Martin Schmitz <m.schmitz@e-sign.com> for finding many bugs in the obfuscator.
zzzeek <classic@io.com>

@ -564,15 +564,12 @@ public class ClassAnalyzer
}
writer.println();
writer.openBrace();
writer.openBraceClass();
writer.tab();
dumpBlock(writer, pl, done, scale);
writer.untab();
if (parent instanceof MethodAnalyzer) {
/* This is a method scope class */
writer.closeBraceNoSpace();
} else
writer.closeBrace();
writer.closeBraceClass();
writer.println();
clazz.dropInfo(clazz.KNOWNATTRIBS | clazz.UNKNOWNATTRIBS);
}

@ -103,6 +103,8 @@ public class Decompiler {
Options.outputStyle = Options.GNU_STYLE;
else if (value.equals("sun"))
Options.outputStyle = Options.SUN_STYLE;
else if (value.equals("pascal"))
Options.outputStyle = Options.PASCAL_STYLE;
else
throw new IllegalArgumentException("Invalid style "+value);
return;

@ -187,11 +187,6 @@ public class FieldAnalyzer implements Analyzer {
writer.breakOp();
writer.print(" = ");
constant.dumpExpression(writer.IMPL_PAREN, writer);
} else if ((modifiers & (Modifier.STATIC | Modifier.FINAL))
== (Modifier.STATIC | Modifier.FINAL)) {
/* Static final fields must always be initialized */
writer.breakOp();
writer.print(" = null");
}
writer.endOp();
writer.println(";");

@ -258,6 +258,8 @@ public class Main extends Options {
outputStyle = SUN_STYLE;
else if ("gnu".startsWith(arg))
outputStyle = GNU_STYLE;
else if ("pascal".startsWith(arg))
outputStyle = Options.PASCAL_STYLE;
else {
GlobalOptions.err.println
("jode.decompiler.Main: Unknown style `"+arg+"'.");

@ -27,6 +27,7 @@ import jode.bytecode.Handler;
import jode.bytecode.Instruction;
import jode.bytecode.LocalVariableInfo;
import jode.jvm.SyntheticAnalyzer;
import jode.decompiler.Options;
import jode.type.*;
import jode.expr.Expression;
import jode.expr.ConstOperator;
@ -866,6 +867,8 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
writer.print(" " + methodName);
}
writer.breakOp();
if ((Options.outputStyle & Options.GNU_SPACING) != 0)
writer.print(" ");
writer.print("(");
writer.startOp(writer.EXPL_PAREN, 0);
int offset = skipParams + (isStatic() ? 0 : 1);
@ -895,11 +898,11 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
}
writer.endOp();
if (code != null) {
writer.openBrace();
writer.openBraceNoIndent();
writer.tab();
methodHeader.dumpSource(writer);
writer.untab();
writer.closeBrace();
writer.closeBraceNoIndent();
} else
writer.println(";");
writer.popScope();

@ -22,10 +22,13 @@ import jode.bytecode.ClassInfo;
import jode.bytecode.InnerClassInfo;
public class Options {
public static final int TAB_SIZE_MASK = 0x0f;
public static final int BRACE_AT_EOL = 0x10;
public static final int SUN_STYLE = 0x14;
public static final int GNU_STYLE = 0x02;
public static final int TAB_SIZE_MASK = 0x0f;
public static final int BRACE_AT_EOL = 0x10;
public static final int BRACE_FLUSH_LEFT = 0x20;
public static final int GNU_SPACING = 0x40;
public static final int SUN_STYLE = 0x14;
public static final int GNU_STYLE = 0x42;
public static final int PASCAL_STYLE = 0x24;
public static final int OPTION_LVT = 0x0001;
public static final int OPTION_INNER = 0x0002;

@ -120,17 +120,15 @@ public class TabbedPrintWriter {
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;
}
/* There is no breakpoint in this op, replace this with
* our child, if possible.
*/
BreakPoint child = (BreakPoint) childBPs.elementAt(0);
options = child.options;
startPos = child.startPos;
endPos = child.endPos;
breakPenalty = child.breakPenalty;
childBPs = child.childBPs;
}
}
@ -746,12 +744,38 @@ public class TabbedPrintWriter {
} else {
if (currentLine.length() > 0)
println();
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
tab();
println("{");
}
}
public void openBraceClass() {
if (currentLine.length() > 0) {
if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
print(" ");
else
println();
}
println("{");
}
/**
* Print a opening brace with the current indentation style.
* Called at the end the line of a method declaration.
*/
public void openBraceNoIndent() {
if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0) {
print(currentLine.length() > 0 ? " {" : "{");
println();
} else {
if (currentLine.length() > 0)
println();
println("{");
}
}
/**
* Print a opening brace with the current indentation style.
* Called at the end of the line of the instance that opens the
@ -763,7 +787,8 @@ public class TabbedPrintWriter {
else {
if (currentLine.length() > 0)
println();
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
tab();
println("{");
}
@ -774,19 +799,14 @@ public class TabbedPrintWriter {
print("} ");
else {
println("}");
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
untab();
}
}
public void closeBraceNoSpace() {
if ((Options.outputStyle & Options.BRACE_AT_EOL) != 0)
print("}");
else {
println("}");
if (currentIndent > 0)
untab();
}
public void closeBraceClass() {
print("}");
}
public void closeBrace() {
@ -794,11 +814,16 @@ public class TabbedPrintWriter {
println("}");
else {
println("}");
if (currentIndent > 0)
if ((Options.outputStyle & Options.BRACE_FLUSH_LEFT) == 0
&& currentIndent > 0)
untab();
}
}
public void closeBraceNoIndent() {
println("}");
}
public void flush() {
pw.flush();
}

@ -398,12 +398,12 @@ public final class InvokeOperator extends Operator
* @return true if this is the magic class$ method, false otherwise.
*/
public boolean isGetClass() {
if (isThis()) {
SyntheticAnalyzer synth = getMethodAnalyzer().getSynthetic();
if (synth != null && synth.getKind() == SyntheticAnalyzer.GETCLASS)
return true;
}
return false;
MethodAnalyzer mana = getMethodAnalyzer();
if (mana == null)
return false;
SyntheticAnalyzer synth = getMethodAnalyzer().getSynthetic();
return (synth != null
&& synth.getKind() == SyntheticAnalyzer.GETCLASS);
}
class Environment extends SimpleRuntimeEnvironment {
@ -572,6 +572,7 @@ public final class InvokeOperator extends Operator
if (getMethodAnalyzer() != null) {
SyntheticAnalyzer synth = getMethodAnalyzer().getSynthetic();
if (synth != null) {
int unifyParam = synth.getUnifyParam();
Expression op = null;
switch (synth.getKind()) {
case SyntheticAnalyzer.ACCESSGETFIELD:
@ -601,9 +602,9 @@ public final class InvokeOperator extends Operator
synth.getReference());
break;
case SyntheticAnalyzer.ACCESSCONSTRUCTOR:
if (subExpressions[1] instanceof ConstOperator
if (subExpressions[unifyParam] instanceof ConstOperator
&& ((ConstOperator)
subExpressions[1]).getValue() == null) {
subExpressions[unifyParam]).getValue() == null) {
op = new InvokeOperator(methodAnalyzer, CONSTRUCTOR,
synth.getReference());
}
@ -613,7 +614,7 @@ public final class InvokeOperator extends Operator
if (op != null) {
if (subExpressions != null) {
for (int i=subExpressions.length; i-- > 0; ) {
if (i == 1 && synth.getKind()
if (i == unifyParam && synth.getKind()
== SyntheticAnalyzer.ACCESSCONSTRUCTOR)
// skip the null param.
continue;
@ -675,9 +676,10 @@ public final class InvokeOperator extends Operator
}
for (int p = offset; p < paramTypes.length; p++) {
if (!paramTypes[p]
.isOfType(Type.tSubType(otherParamTypes[p-offset])))
.isOfType(Type.tSubType(otherParamTypes[p-offset]))){
/* No conflict here */
continue next_method;
}
}
/* There is a conflict that can be resolved by a cast. */
return true;
@ -1103,6 +1105,8 @@ public final class InvokeOperator extends Operator
writer.endOp();
writer.breakOp();
if ((Options.outputStyle & Options.GNU_SPACING) != 0)
writer.print(" ");
writer.print("(");
writer.startOp(writer.EXPL_PAREN, 0);
boolean first = true;
@ -1136,11 +1140,11 @@ public final class InvokeOperator extends Operator
* dump the source code of the anonymous class.
*/
Object state = writer.saveOps();
writer.openBrace();
writer.openBraceClass();
writer.tab();
clazzAna.dumpBlock(writer);
writer.untab();
writer.closeBraceNoSpace();
writer.closeBraceClass();
writer.restoreOps(state);
}
}

@ -41,8 +41,17 @@ public class PopOperator extends Operator {
public void updateType() {
}
public int getBreakPenalty() {
if (subExpressions[0] instanceof Operator)
return ((Operator) subExpressions[0]).getBreakPenalty();
return 0;
}
public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException {
subExpressions[0].dumpExpression(writer, 0);
/* Don't give a priority; we can't allow parens around
* a statement.
*/
subExpressions[0].dumpExpression(writer);
}
}

@ -19,6 +19,7 @@
package jode.expr;
import jode.type.Type;
import jode.decompiler.Options;
import jode.decompiler.TabbedPrintWriter;
public class UnaryOperator extends Operator {
@ -57,6 +58,8 @@ public class UnaryOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException {
writer.print(getOperatorString());
if ((Options.outputStyle & Options.GNU_SPACING) != 0)
writer.print(" ");
subExpressions[0].dumpExpression(writer, 700);
}
}

@ -27,6 +27,7 @@ import jode.bytecode.Instruction;
import jode.bytecode.MethodInfo;
import jode.bytecode.Opcodes;
import jode.bytecode.Reference;
import jode.bytecode.TypeSignature;
import jode.type.Type;
import jode.type.MethodType;
@ -48,6 +49,7 @@ public class SyntheticAnalyzer implements Opcodes {
int kind = UNKNOWN;
Reference reference;
MethodInfo method;
int unifyParam = -1;
public SyntheticAnalyzer(MethodInfo method, boolean checkName) {
this.method = method;
@ -72,6 +74,14 @@ public class SyntheticAnalyzer implements Opcodes {
return reference;
}
/**
* Gets the index of the dummy parameter for an ACCESSCONSTRUCTOR.
* Normally the 1 but for inner classes it may be 2.
*/
public int getUnifyParam() {
return unifyParam;
}
private static final int[] getClassOpcodes = {
opc_aload, opc_invokestatic, opc_areturn,
opc_astore, opc_new, opc_dup, opc_aload,
@ -325,17 +335,23 @@ public class SyntheticAnalyzer implements Opcodes {
return false;
Iterator iter = bytecode.getInstructions().iterator();
Instruction instr = (Instruction) iter.next();
if (instr.getOpcode() != opc_aload || instr.getLocalSlot() != 0)
return false;
instr = (Instruction) iter.next();
// slot begins with 2. Slot 1 contains a dummy value, that
// is used so that the constructor has a different type signature.
int params = 0, slot = 2;
Instruction instr = (Instruction) iter.next();
int params = 0, slot = 0;
while (instr.getOpcode() >= opc_iload
&& instr.getOpcode() <= opc_aload
&& instr.getLocalSlot() == slot) {
&& instr.getOpcode() <= opc_aload) {
if (instr.getLocalSlot() > slot
&& unifyParam == -1 && params > 0
&& TypeSignature.getParameterTypes(method.getType())
[params - 1].charAt(0) == 'L') {
unifyParam = params;
params++;
slot++;
}
if (instr.getLocalSlot() != slot)
return false;
params++;
slot += (instr.getOpcode() == opc_lload
|| instr.getOpcode() == opc_dload) ? 2 : 1;
@ -352,13 +368,17 @@ public class SyntheticAnalyzer implements Opcodes {
MethodType refType = Type.tMethod(ref.getType());
if ((refMethod.getModifiers() & modifierMask) != Modifier.PRIVATE
|| !refMethod.getName().equals("<init>")
|| refType.getParameterTypes().length != params)
|| unifyParam == -1
|| refType.getParameterTypes().length != params - 2)
return false;
instr = (Instruction) iter.next();
if (instr.getOpcode() != opc_return)
return false;
/* For valid bytecode the types matches automatically */
/* We don't check if types matches. No problem since we only
* need to make sure, this constructor doesn't do anything
* more than relay to the real one.
*/
reference = ref;
kind = ACCESSCONSTRUCTOR;
return true;

@ -71,15 +71,4 @@ public class NullType extends ReferenceType {
public String toString() {
return "tNull";
}
/**
* Intersect this type with another type and return the new type.
* @param type the other type.
* @return the intersection, or tError, if a type conflict happens.
*/
public Type intersection(Type type) {
if (type == this)
return type;
return tError;
}
}

Loading…
Cancel
Save