|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.tools.tree; |
|
|
|
import sun.tools.java.*; |
|
import sun.tools.asm.Assembler; |
|
import java.io.PrintStream; |
|
import java.util.Hashtable; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public |
|
class ThisExpression extends Expression { |
|
LocalMember field; |
|
Expression implementation; |
|
Expression outerArg; |
|
|
|
|
|
|
|
*/ |
|
public ThisExpression(long where) { |
|
super(THIS, where, Type.tObject); |
|
} |
|
protected ThisExpression(int op, long where) { |
|
super(op, where, Type.tObject); |
|
} |
|
public ThisExpression(long where, LocalMember field) { |
|
super(THIS, where, Type.tObject); |
|
this.field = field; |
|
field.readcount++; |
|
} |
|
public ThisExpression(long where, Context ctx) { |
|
super(THIS, where, Type.tObject); |
|
field = ctx.getLocalField(idThis); |
|
field.readcount++; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ThisExpression(long where, Expression outerArg) { |
|
this(where); |
|
this.outerArg = outerArg; |
|
} |
|
|
|
public Expression getImplementation() { |
|
if (implementation != null) |
|
return implementation; |
|
return this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Expression getOuterArg() { |
|
return outerArg; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public Vset checkValue(Environment env, Context ctx, Vset vset, Hashtable exp) { |
|
if (ctx.field.isStatic()) { |
|
env.error(where, "undef.var", opNames[op]); |
|
type = Type.tError; |
|
return vset; |
|
} |
|
if (field == null) { |
|
field = ctx.getLocalField(idThis); |
|
field.readcount++; |
|
} |
|
if (field.scopeNumber < ctx.frameNumber) { |
|
|
|
implementation = ctx.makeReference(env, field); |
|
} |
|
if (!vset.testVar(field.number)) { |
|
env.error(where, "access.inst.before.super", opNames[op]); |
|
} |
|
if (field == null) { |
|
type = ctx.field.getClassDeclaration().getType(); |
|
} else { |
|
type = field.getType(); |
|
} |
|
return vset; |
|
} |
|
|
|
public boolean isNonNull() { |
|
return true; |
|
} |
|
|
|
// A 'ThisExpression' node can never appear on the LHS of an assignment in a correct |
|
// program, but handle this case anyhow to provide a safe error recovery. |
|
|
|
public FieldUpdater getAssigner(Environment env, Context ctx) { |
|
return null; |
|
} |
|
|
|
public FieldUpdater getUpdater(Environment env, Context ctx) { |
|
return null; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public Expression inlineValue(Environment env, Context ctx) { |
|
if (implementation != null) |
|
return implementation.inlineValue(env, ctx); |
|
if (field != null && field.isInlineable(env, false)) { |
|
Expression e = (Expression)field.getValue(env); |
|
|
|
if (e != null) { |
|
e = e.copyInline(ctx); |
|
e.type = type; |
|
return e; |
|
} |
|
} |
|
return this; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public Expression copyInline(Context ctx) { |
|
if (implementation != null) |
|
return implementation.copyInline(ctx); |
|
ThisExpression e = (ThisExpression)clone(); |
|
if (field == null) { |
|
|
|
e.field = ctx.getLocalField(idThis); |
|
e.field.readcount++; |
|
} else { |
|
e.field = field.getCurrentInlineCopy(ctx); |
|
} |
|
if (outerArg != null) { |
|
e.outerArg = outerArg.copyInline(ctx); |
|
} |
|
return e; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void codeValue(Environment env, Context ctx, Assembler asm) { |
|
asm.add(where, opc_aload, new Integer(field.number)); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void print(PrintStream out) { |
|
if (outerArg != null) { |
|
out.print("(outer="); |
|
outerArg.print(out); |
|
out.print(" "); |
|
} |
|
String pfx = (field == null) ? "" |
|
: field.getClassDefinition().getName().getFlatName().getName()+"."; |
|
pfx += opNames[op]; |
|
out.print(pfx + "#" + ((field != null) ? field.hashCode() : 0)); |
|
if (outerArg != null) |
|
out.print(")"); |
|
} |
|
} |