001: /*
002: * Copyright 1994-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.tree;
027:
028: import sun.tools.java.*;
029: import sun.tools.asm.Assembler;
030: import java.io.PrintStream;
031: import java.util.Hashtable;
032:
033: /**
034: * WARNING: The contents of this source file are not part of any
035: * supported API. Code that depends on them does so at its own risk:
036: * they are subject to change or removal without notice.
037: */
038: public class ThisExpression extends Expression {
039: LocalMember field;
040: Expression implementation;
041: Expression outerArg;
042:
043: /**
044: * Constructor
045: */
046: public ThisExpression(long where) {
047: super (THIS, where, Type.tObject);
048: }
049:
050: protected ThisExpression(int op, long where) {
051: super (op, where, Type.tObject);
052: }
053:
054: public ThisExpression(long where, LocalMember field) {
055: super (THIS, where, Type.tObject);
056: this .field = field;
057: field.readcount++;
058: }
059:
060: public ThisExpression(long where, Context ctx) {
061: super (THIS, where, Type.tObject);
062: field = ctx.getLocalField(idThis);
063: field.readcount++;
064: }
065:
066: /**
067: * Constructor for "x.this()"
068: */
069: public ThisExpression(long where, Expression outerArg) {
070: this (where);
071: this .outerArg = outerArg;
072: }
073:
074: public Expression getImplementation() {
075: if (implementation != null)
076: return implementation;
077: return this ;
078: }
079:
080: /**
081: * From the 'this' in an expression of the form outer.this(...),
082: * or the 'super' in an expression of the form outer.super(...),
083: * return the "outer" expression, or null if there is none.
084: */
085: public Expression getOuterArg() {
086: return outerArg;
087: }
088:
089: /**
090: * Check expression
091: */
092: public Vset checkValue(Environment env, Context ctx, Vset vset,
093: Hashtable exp) {
094: if (ctx.field.isStatic()) {
095: env.error(where, "undef.var", opNames[op]);
096: type = Type.tError;
097: return vset;
098: }
099: if (field == null) {
100: field = ctx.getLocalField(idThis);
101: field.readcount++;
102: }
103: if (field.scopeNumber < ctx.frameNumber) {
104: // get a "this$C" copy via the current object
105: implementation = ctx.makeReference(env, field);
106: }
107: if (!vset.testVar(field.number)) {
108: env.error(where, "access.inst.before.super", opNames[op]);
109: }
110: if (field == null) {
111: type = ctx.field.getClassDeclaration().getType();
112: } else {
113: type = field.getType();
114: }
115: return vset;
116: }
117:
118: public boolean isNonNull() {
119: return true;
120: }
121:
122: // A 'ThisExpression' node can never appear on the LHS of an assignment in a correct
123: // program, but handle this case anyhow to provide a safe error recovery.
124:
125: public FieldUpdater getAssigner(Environment env, Context ctx) {
126: return null;
127: }
128:
129: public FieldUpdater getUpdater(Environment env, Context ctx) {
130: return null;
131: }
132:
133: /**
134: * Inline
135: */
136: public Expression inlineValue(Environment env, Context ctx) {
137: if (implementation != null)
138: return implementation.inlineValue(env, ctx);
139: if (field != null && field.isInlineable(env, false)) {
140: Expression e = (Expression) field.getValue(env);
141: //System.out.println("INLINE = "+ e + ", THIS");
142: if (e != null) {
143: e = e.copyInline(ctx);
144: e.type = type; // in case op==SUPER
145: return e;
146: }
147: }
148: return this ;
149: }
150:
151: /**
152: * Create a copy of the expression for method inlining
153: */
154: public Expression copyInline(Context ctx) {
155: if (implementation != null)
156: return implementation.copyInline(ctx);
157: ThisExpression e = (ThisExpression) clone();
158: if (field == null) {
159: // The expression is copied into the context of a method
160: e.field = ctx.getLocalField(idThis);
161: e.field.readcount++;
162: } else {
163: e.field = field.getCurrentInlineCopy(ctx);
164: }
165: if (outerArg != null) {
166: e.outerArg = outerArg.copyInline(ctx);
167: }
168: return e;
169: }
170:
171: /**
172: * Code
173: */
174: public void codeValue(Environment env, Context ctx, Assembler asm) {
175: asm.add(where, opc_aload, new Integer(field.number));
176: }
177:
178: /**
179: * Print
180: */
181: public void print(PrintStream out) {
182: if (outerArg != null) {
183: out.print("(outer=");
184: outerArg.print(out);
185: out.print(" ");
186: }
187: String pfx = (field == null) ? "" : field.getClassDefinition()
188: .getName().getFlatName().getName()
189: + ".";
190: pfx += opNames[op];
191: out.print(pfx + "#" + ((field != null) ? field.hashCode() : 0));
192: if (outerArg != null)
193: out.print(")");
194: }
195: }
|