KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > ast > Expr


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.ast;
26
27 import org.aspectj.compiler.base.*;
28
29 import org.aspectj.compiler.base.JavaCompiler;
30 import org.aspectj.compiler.base.cst.*;
31
32 import org.aspectj.compiler.base.bcg.CodeBuilder;
33 import org.aspectj.compiler.base.bcg.Label;
34
35 /**
36   * @grammar ...
37   */

38 public abstract class Expr extends ASTObject {
39     /** is this an expression in a super or this constructor call?
40      */

41     public boolean isInConstructorCallExpr() {
42         ASTObject e = this;
43         while (true) {
44             if (e instanceof ConstructorCallExpr) return true;
45             else if (e instanceof Expr) e = e.getParent();
46             else return false;
47         }
48     }
49     
50     /** is this expression zero or null? */
51     public boolean isConstantZero() { return false; }
52
53     /** is this expression the boolean literal value true? */
54     public boolean isConstantTrue() { return false; }
55
56     /** is this expression the boolean literal value false? */
57     public boolean isConstantFalse() { return false; }
58
59     /** Normally this is a type consideration, but this is overridden
60         by {@link IntLiteralExpr} to handle JLS 5.2's requirement that
61         some int literals are assignable to byte, short, and char
62         variables. */

63     public boolean isAssignableTo(Type type) {
64         return type.isAssignableFrom(getType());
65     }
66
67     /** Method invocation conversion, JLS 5.3, is the same as
68         assignment conversion without the numeric narrowing
69         conversion. So all this does is delegate to the purely
70         type-based {@link Type#isAssignableFrom} method.
71     */

72     public final boolean isMethodConvertableTo(Type type) {
73         return type.isAssignableFrom(getType());
74     }
75
76     public boolean isLegalStmt() {
77         return false;
78     }
79
80     public ASTObject postCopy(CopyWalker walker, ASTObject oldObject) {
81         if (this.type == null) {
82             this.type = ((Expr)oldObject).type;
83         }
84         return super.postCopy(walker, oldObject);
85     }
86
87     //XXX total hack to avoid understanding inners too much
88
protected Expr makeQualifiedThis(Type declaringType) {
89         if (getLexicalType() != null && getLexicalType().isInnerType()) {
90             return getAST().makeQualifiedThis(declaringType);
91         } else {
92             return getAST().makeThis(declaringType);
93         }
94     }
95
96     public boolean isInExprStmt() {
97         ASTObject parent = this.getParent();
98         if (parent instanceof ExprStmt) return true;
99         if (parent instanceof Exprs) {
100             ASTObject grandparent = parent.getParent();
101             return (grandparent instanceof ForStmt ? true : false);
102         }
103         return false;
104     }
105
106     public void checkSpec() {
107         if (type == null) type = discoverType();
108     }
109
110     public void assertType(Type type) {
111         if (!(type.isAssignableFrom(getType()))) {
112             showTypeError(getType(), type);
113         }
114     }
115
116     protected Type type;
117     public Type getType() {
118         if (type == null) type = discoverType();
119           if (type == null) {
120               //this.showError("my type is null");
121
// System.out.println("My type is null: ");
122
// this.display(2);
123
}
124         return type;
125     }
126
127     //XXX used when?
128
public void setType(Type type) {
129         this.type = type;
130     }
131
132     public void showOperatorTypeError(String JavaDoc op, Type a, Type b) {
133         if (a.isMissing() || b.isMissing()) return;
134         showError("operator " + op + " cannot be applied to " + a.getString() + "," + b.getString());
135     }
136     
137
138     public void showOperatorTypeError(String JavaDoc op, Type a) {
139         if (a.isMissing()) return;
140         showError("operator " + op + " cannot be applied to " + a.getString());
141     }
142
143     /**
144      * When called for the first time will return an expression that may
145      * involve computation and state changes.
146      *
147      * When called on an Expr returned from this method, it is guaranteed
148      * that no further computation will occur.
149      *
150      * For Exprs that are already references, this is copied identity.
151      *
152      * For others, this will return a ReferenceExpr.
153      *
154      */

155     public Expr makeReference() {
156         return new ReferenceExpr(getSourceLocation(), this);
157     }
158
159     /**
160      * Can this expression be copied without changing the semantics of the
161      * program.
162      */

163     public boolean canBeCopied() {
164         return false;
165     }
166     
167     /**
168      * Is this expression ultimately a literal expression.
169      *
170      * The only difference between this and canBeCopied is that
171      * 'this' is NOT ultimatelyLiteral, and that a cast is only copiable
172      * if its expression is ultimatelyLiteral.
173      */

174     public boolean isUltimatelyLiteral() {
175         return false;
176     }
177
178
179     abstract protected Type discoverType();
180
181 // public ASTObject finishCopy(ASTObject newObject) {
182
// if (newObject instanceof Expr) {
183
// ((Expr)newObject).type = this.type;
184
// }
185
// return super.finishCopy(newObject);
186
// }
187

188     public void cleanup() {
189         type = null;
190         super.cleanup();
191     }
192
193     // ------------------------------
194
// Intro from ByteCodeCleanupPass
195

196     // we don't need to clean up expressions, so don't traverse them.
197
public void walkCleanup(ByteCodeCleanupPass w) {
198         return;
199     }
200
201     // ------------------------------
202
// bcg
203

204     /** Leaves the value of this expression on the stack. May self-call
205      {@link #cgTest(CodeBuilder, Label, Label)}. */

206     protected void cgValue(CodeBuilder cb) {
207         Label trueLab = cb.genLabel();
208         Label falseLab = cb.genLabel();
209         Label endLab = cb.genLabel();
210         cgTest(cb, trueLab, falseLab);
211         cb.emitLabel(trueLab);
212         cb.emitIntConstant(1);
213         cb.emitJump(endLab);
214         cb.emitLabel(falseLab);
215         cb.popStack(1);
216         cb.emitIntConstant(0);
217         cb.emitLabel(endLab);
218     }
219
220     /** Leaves the value of this expression on the stack and casts the
221         value to castTo. May self-call {@link #cgValue(CodeBuilder)}. */

222     protected void cgValue(CodeBuilder cb, Type castTo) {
223         cgValue(cb);
224         getType().emitCast(cb, castTo);
225     }
226
227     /** Evaluates the expression in a context where its value is
228         unnecessary (i.e., from {@link ExprStmt}, or in a {@link
229         FieldAccessExpr} when the field is static but there is an
230         expression there nonetheless). May self-call {@link
231         #cgValue(CodeBuilder)}. */

232     protected void cgEffect(CodeBuilder cb) {
233         cgValue(cb);
234         getType().emitPop(cb);
235     }
236
237     /** Evaluates the expression in a context where the top of the
238         stack contains a {@link StringBuffer} object. The value of
239         this expression is then appended into the StringBuffer. This
240         is used in evaluating the String + operator. May self-call
241         {@link #cgValue(CodeBuilder)}. */

242     protected void cgBuffer(CodeBuilder cb) {
243         cgValue(cb);
244         NameType stringBufferType = getTypeManager().getStringBufferType();
245         Type ty = getType();
246         if (ty instanceof ByteType || ty instanceof ShortType) {
247             ty = getTypeManager().intType;
248         } else if (ty.isString()) {
249         } else if (ty instanceof RefType) {
250             ty = getTypeManager().getObjectType();
251         }
252         cb.emitINVOKEVIRTUAL(stringBufferType, "append",
253                              "(" + ty.getDescriptor() + ")Ljava/lang/StringBuffer;",
254                              - ty.getSlotCount());
255     }
256
257     /** Evaluates the expression in a context where its value will
258         only be used to branch (from {@link IfStmt}, {@link
259         TriTestExpr}, {@link WhileStmt}, {@link DoStmt}, and {@link
260         ForStmt}). The expression, of course, will have boolean type.
261         By default, this evaluates the expression to the stack and
262         then emits an EQ/NE branch bytecode, but many expressions such
263         as tests in {@link BinopExpr} will be able to do much better.
264         May self-call {@link #cgValue(CodeBuilder)}. */

265     protected void cgTest(CodeBuilder cb, Label tdest, Label fdest) {
266         cgValue(cb);
267         cb.emitIFNE(tdest, fdest);
268     }
269
270     // ------------------------------
271
// Intro: FrameLocPass
272

273     // We don't assign frame locations here
274
public void walkFrameLoc(FrameLocPass walker) {
275     }
276
277     //BEGIN: Generated from @child and @property
278

279     public Expr(SourceLocation location) {
280         super(location);
281
282     }
283
284
285     public String JavaDoc getDefaultDisplayName() {
286         return "Expr()";
287     }
288
289     //END: Generated from @child and @property
290
}
291
Popular Tags