|
|
@ -20,9 +20,15 @@ |
|
|
|
package jode.expr; |
|
|
|
package jode.expr; |
|
|
|
import jode.type.Type; |
|
|
|
import jode.type.Type; |
|
|
|
import jode.type.NullType; |
|
|
|
import jode.type.NullType; |
|
|
|
|
|
|
|
import jode.type.ClassInterfacesType; |
|
|
|
|
|
|
|
import jode.bytecode.ClassInfo; |
|
|
|
import jode.bytecode.Reference; |
|
|
|
import jode.bytecode.Reference; |
|
|
|
import jode.decompiler.CodeAnalyzer; |
|
|
|
import jode.decompiler.CodeAnalyzer; |
|
|
|
|
|
|
|
import jode.decompiler.ClassAnalyzer; |
|
|
|
|
|
|
|
import jode.decompiler.MethodAnalyzer; |
|
|
|
|
|
|
|
import jode.decompiler.FieldAnalyzer; |
|
|
|
import jode.decompiler.TabbedPrintWriter; |
|
|
|
import jode.decompiler.TabbedPrintWriter; |
|
|
|
|
|
|
|
import jode.decompiler.Scope; |
|
|
|
|
|
|
|
|
|
|
|
public class GetFieldOperator extends Operator { |
|
|
|
public class GetFieldOperator extends Operator { |
|
|
|
boolean staticFlag; |
|
|
|
boolean staticFlag; |
|
|
@ -63,14 +69,59 @@ public class GetFieldOperator extends Operator { |
|
|
|
needCast = types[0].getHint().equals(Type.tNull); |
|
|
|
needCast = types[0].getHint().equals(Type.tNull); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Checks, whether this is a call of a method from this class or an |
|
|
|
|
|
|
|
* outer instance. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public boolean isOuter() { |
|
|
|
|
|
|
|
if (classType instanceof ClassInterfacesType) { |
|
|
|
|
|
|
|
ClassInfo clazz = ((ClassInterfacesType) classType).getClassInfo(); |
|
|
|
|
|
|
|
ClassAnalyzer ana = codeAnalyzer.getClassAnalyzer(); |
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
|
|
if (clazz == ana.getClazz()) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
if (ana.getParent() instanceof MethodAnalyzer) |
|
|
|
|
|
|
|
ana = ((MethodAnalyzer) ana.getParent()) |
|
|
|
|
|
|
|
.getClassAnalyzer(); |
|
|
|
|
|
|
|
else if (ana.getParent() instanceof ClassAnalyzer) |
|
|
|
|
|
|
|
ana = (ClassAnalyzer) ana.getParent(); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public ClassInfo getClassInfo() { |
|
|
|
|
|
|
|
if (classType instanceof ClassInterfacesType) |
|
|
|
|
|
|
|
return ((ClassInterfacesType) classType).getClassInfo(); |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public FieldAnalyzer getFieldAnalyzer() { |
|
|
|
|
|
|
|
ClassInfo clazz = getClassInfo(); |
|
|
|
|
|
|
|
if (clazz != null) { |
|
|
|
|
|
|
|
ClassAnalyzer ana = codeAnalyzer.getClassAnalyzer(); |
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
|
|
|
if (clazz == ana.getClazz()) { |
|
|
|
|
|
|
|
return ana.getField(ref.getName(), |
|
|
|
|
|
|
|
Type.tType(ref.getType())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ana.getParent() instanceof MethodAnalyzer) |
|
|
|
|
|
|
|
ana = ((MethodAnalyzer) ana.getParent()) |
|
|
|
|
|
|
|
.getClassAnalyzer(); |
|
|
|
|
|
|
|
else if (ana.getParent() instanceof ClassAnalyzer) |
|
|
|
|
|
|
|
ana = (ClassAnalyzer) ana.getParent(); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void dumpExpression(TabbedPrintWriter writer, Expression[] operands) |
|
|
|
public void dumpExpression(TabbedPrintWriter writer, Expression[] operands) |
|
|
|
throws java.io.IOException { |
|
|
|
throws java.io.IOException { |
|
|
|
boolean opIsThis = |
|
|
|
boolean opIsThis = !staticFlag && operands[0] instanceof ThisOperator; |
|
|
|
(!staticFlag |
|
|
|
|
|
|
|
&& operands[0] instanceof LocalLoadOperator |
|
|
|
|
|
|
|
&& (((LocalLoadOperator) operands[0]).getLocalInfo() |
|
|
|
|
|
|
|
.equals(codeAnalyzer.getParamInfo(0))) |
|
|
|
|
|
|
|
&& !codeAnalyzer.getMethod().isStatic()); |
|
|
|
|
|
|
|
String fieldName = ref.getName(); |
|
|
|
String fieldName = ref.getName(); |
|
|
|
if (staticFlag) { |
|
|
|
if (staticFlag) { |
|
|
|
if (!classType.equals(Type.tClass(codeAnalyzer.getClazz())) |
|
|
|
if (!classType.equals(Type.tClass(codeAnalyzer.getClazz())) |
|
|
@ -87,7 +138,23 @@ public class GetFieldOperator extends Operator { |
|
|
|
writer.print(")."); |
|
|
|
writer.print(")."); |
|
|
|
writer.print(fieldName); |
|
|
|
writer.print(fieldName); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (!opIsThis || codeAnalyzer.findLocal(fieldName) != null) { |
|
|
|
if (opIsThis) { |
|
|
|
|
|
|
|
ThisOperator thisOp = (ThisOperator) operands[0]; |
|
|
|
|
|
|
|
Scope scope = writer.getScope(thisOp.getClassInfo(), |
|
|
|
|
|
|
|
Scope.CLASSSCOPE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (scope == null) |
|
|
|
|
|
|
|
writer.println("UNKNOWN "); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (scope == null || writer.conflicts(fieldName, scope, |
|
|
|
|
|
|
|
Scope.FIELDNAME)) { |
|
|
|
|
|
|
|
thisOp.dumpExpression(writer, 950); |
|
|
|
|
|
|
|
writer.print("."); |
|
|
|
|
|
|
|
} else if (writer.conflicts(fieldName, scope, |
|
|
|
|
|
|
|
Scope.AMBIGUOUSNAME)) { |
|
|
|
|
|
|
|
writer.print("this."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
operands[0].dumpExpression(writer, 950); |
|
|
|
operands[0].dumpExpression(writer, 950); |
|
|
|
writer.print("."); |
|
|
|
writer.print("."); |
|
|
|
} |
|
|
|
} |
|
|
@ -95,6 +162,15 @@ public class GetFieldOperator extends Operator { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Expression simplifyThis(Expression[] subs) { |
|
|
|
|
|
|
|
if (!staticFlag && subs[0] instanceof ThisOperator) { |
|
|
|
|
|
|
|
Expression constant = getFieldAnalyzer().getConstant(); |
|
|
|
|
|
|
|
if (constant instanceof ThisOperator) |
|
|
|
|
|
|
|
return constant; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean equals(Object o) { |
|
|
|
public boolean equals(Object o) { |
|
|
|
return o instanceof GetFieldOperator |
|
|
|
return o instanceof GetFieldOperator |
|
|
|
&& ((GetFieldOperator)o).ref.equals(ref); |
|
|
|
&& ((GetFieldOperator)o).ref.equals(ref); |
|
|
|