anonymous class handling

handles the class.new Class syntax for inner classes


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@742 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent dd33ee137e
commit 833edb863c
  1. 102
      jode/jode/expr/ConstructorOperator.java

@ -19,25 +19,41 @@
package jode.expr; package jode.expr;
import jode.type.Type; import jode.type.Type;
import jode.type.NullType;
import jode.type.ClassInterfacesType;
import jode.type.MethodType; import jode.type.MethodType;
import jode.bytecode.ClassInfo;
import jode.bytecode.InnerClassInfo;
import jode.Decompiler;
import jode.decompiler.CodeAnalyzer;
import jode.decompiler.ClassAnalyzer;
import jode.decompiler.TabbedPrintWriter; import jode.decompiler.TabbedPrintWriter;
import jode.decompiler.Scope;
public class ConstructorOperator extends Operator public class ConstructorOperator extends Operator
implements MatchableOperator { implements MatchableOperator {
MethodType methodType; MethodType methodType;
Type classType; Type classType;
CodeAnalyzer codeAnalyzer;
public ConstructorOperator(Type type, MethodType methodType, ClassAnalyzer anonymousClass = null;
boolean isVoid) { boolean removedCheckNull = false;
super(isVoid ? Type.tVoid : type, 0);
this.classType = type; public ConstructorOperator(InvokeOperator invoke, boolean isVoid) {
this.methodType = methodType; super(isVoid ? Type.tVoid : invoke.getClassType(), 0);
this.classType = invoke.getClassType();
this.methodType = invoke.getMethodType();
this.codeAnalyzer = invoke.codeAnalyzer;
checkAnonymousClasses();
} }
public MethodType getMethodType() { public MethodType getMethodType() {
return methodType; return methodType;
} }
public CodeAnalyzer getCodeAnalyzer() {
return codeAnalyzer;
}
/** /**
* Checks if the value of the given expression can change, due to * Checks if the value of the given expression can change, due to
* side effects in this expression. If this returns false, the * side effects in this expression. If this returns false, the
@ -85,14 +101,84 @@ public class ConstructorOperator extends Operator
? EMPTYSTRING : null; ? EMPTYSTRING : null;
} }
public ClassInfo getClassInfo() {
if (classType instanceof ClassInterfacesType) {
return ((ClassInterfacesType) classType).getClassInfo();
}
return null;
}
public InnerClassInfo getOuterClassInfo() {
ClassInfo ci = getClassInfo();
if (ci != null && ci.getName().indexOf('$') >= 0) {
InnerClassInfo[] outers = ci.getOuterClasses();
if (outers != null)
return outers[0];
}
return null;
}
public void checkAnonymousClasses() {
if ((Decompiler.options & Decompiler.OPTION_ANON) == 0)
return;
InnerClassInfo outer = getOuterClassInfo();
if (outer != null && outer.outer == null) {
ClassInfo clazz = getClassInfo();
anonymousClass = codeAnalyzer.addAnonymousClass(clazz);
if (anonymousClass.getName() == null) {
if (clazz.getInterfaces().length > 0)
type = Type.tClass(clazz.getInterfaces()[0]);
else
type = Type.tClass(clazz.getSuperclass());
}
}
}
public void dumpExpression(TabbedPrintWriter writer, public void dumpExpression(TabbedPrintWriter writer,
Expression[] operands) Expression[] operands)
throws java.io.IOException { throws java.io.IOException {
int arg = 0;
if (anonymousClass != null) {
writer.print("new ");
anonymousClass.dumpSource(writer);
return;
}
InnerClassInfo outer = getOuterClassInfo();
if (outer != null && outer.name != null) {
Expression outExpr = operands[arg++];
if (!removedCheckNull && !(outExpr instanceof ThisOperator))
writer.print("MISSING CHECKNULL");
if (outExpr instanceof ThisOperator) {
Scope scope = writer.getScope
(((ThisOperator) outExpr).getClassInfo(),
Scope.CLASSSCOPE);
if (writer.conflicts(outer.name, scope, Scope.CLASSNAME)) {
outExpr.dumpExpression(writer, 950);
writer.print(".");
}
} else {
int minPriority = 950; /* field access */
if (outExpr.getType() instanceof NullType) {
writer.print("((");
writer.printType(classType);
writer.print(") ");
outExpr.dumpExpression(writer, 700);
writer.print(")");
} else
outExpr.dumpExpression(writer, 950);
writer.print(".");
}
}
writer.print("new "); writer.print("new ");
if (outer != null && outer.name != null)
writer.print(outer.name);
else
writer.printType(classType); writer.printType(classType);
writer.print("("); writer.print("(");
for (int i=0; i < methodType.getParameterTypes().length; i++) { for (int i = arg; i < methodType.getParameterTypes().length; i++) {
if (i>0) if (i>arg)
writer.print(", "); writer.print(", ");
operands[i].dumpExpression(writer, 0); operands[i].dumpExpression(writer, 0);
} }

Loading…
Cancel
Save