KickJava   Java API By Example, From Geeks To Geeks.

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


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 import org.aspectj.compiler.crosscuts.AccessFixer;
29
30 import org.aspectj.compiler.base.bcg.CodeBuilder;
31 import org.aspectj.compiler.base.bcg.Label;
32
33 /**
34   * @grammar expr.name;
35   * @child Expr expr
36   * @property Field field
37   * @property boolean isSuper
38   */

39 public class FieldAccessExpr extends AssignableExpr implements SOLink {
40     public FieldDec getFieldDec() { return (FieldDec)field.getCorrespondingDec(); }
41
42     protected Type discoverType() {
43         return field.getFieldType();
44     }
45
46     // ------------------------------
47
// INTRO from FlowCheckerPass
48

49     public void walkFlow(FlowCheckerPass w) {
50         Expr e = getExpr();
51         FieldDec dec = getFieldDec();
52         if (e != null) w.process(e);
53         if (dec.isFinal()
54                 && isBare()
55                 && w.isCurrent(dec)
56                 && ! w.getVars().isDefinitelyAssigned(dec)) {
57             showError("Field " + getId() + " might not have a value");
58         }
59     }
60
61     public boolean isBare() {
62         Expr e = getExpr();
63         if (e == null) return true;
64         if (getField().isStatic()) {
65             return e instanceof TypeExpr && e.isSynthetic();
66         } else {
67             return e instanceof ThisExpr
68                 || ((e instanceof QualifiedThisExpr) && e.isSynthetic());
69         }
70     }
71
72     // ------------------------------
73
// INTRO from InnerInfoPass -- should have a more generic name
74

75     public void postInnerInfo(InnerInfoPass w) {
76         if (expr == null /* || expr.isSynthetic() */) {
77             w.checkStaticAccess(this, field);
78         }
79         if (expr == null) {
80             setExpr(getAST().makePrimary(getField(), w.currentType()));
81         }
82     }
83
84     /**
85      * Section 6.6.2.1 from JLSv2
86      * E.Id requires that E is subtype of S
87      */

88     public boolean hasLegalProtectedAccess(Type fromType) {
89         //this.display(0);
90
if (expr == null || getIsSuper()) return true;
91         return expr.getType().isSubtypeOf(fromType);
92     }
93
94
95     public void checkSpec() {
96         if (field == null) return;
97
98         if (field.getModifiers().isProtected() && !field.isAccessible(this)) {
99             showError(field.toShortString() + " has protected access");
100         }
101
102         if (expr instanceof TypeExpr && !field.isStatic()) {
103             showError("non-static field " + field.toShortString() +
104                         " cannot be accessed through a static reference");
105         }
106     }
107
108     // ------------------------------
109
// Intro: ForwardReferenceChecker
110

111     public void walkForwardReference(ForwardReferenceChecker w) {
112         super.walkForwardReference(w);
113         if (isLhs() && (getParent() instanceof BasicAssignExpr))
114             return;
115         if (getExpr() != null && ! getExpr().isSynthetic()) return;
116         //showWarning("synthetic expr");
117
w.checkReference(this);
118     }
119
120
121     // ------------------------------
122
// INTRO from AssignmentCheckerPass (defined in AspectJCompiler)
123

124     public ASTObject postAssignmentCheck(AssignmentCheckerPass walker) {
125         if (isLhs()) return this;
126         Field field = getField();
127         FieldDec fieldDec = getFieldDec();
128         fieldDec.ensureFolded(walker);
129         Expr initExpr = fieldDec.getInitializer();
130
131         if (fieldDec.isConstant() && isLegalConstantPrimary(getExpr())) {
132             return
133                 fieldDec.getType().foldCast((LiteralExpr)initExpr).setSource(this);
134         } else {
135             return this;
136         }
137     }
138
139     private boolean isLegalConstantPrimary(Expr expr) {
140         if (expr == null) return true;
141
142         if (expr instanceof ParenExpr) {
143             return isLegalConstantPrimary(((ParenExpr)expr).getExpr());
144         }
145         if (expr instanceof TypeExpr) {
146             return true;
147         }
148         // ignore generated ThisExprs for purposes of folding
149
if (expr.isSynthetic() || !expr.fromSource()) {
150             return (expr instanceof ThisExpr);
151         }
152
153         return false;
154     }
155
156     //INTRO from AccessFixer
157
public ASTObject fixAccessPost(AccessFixer fixer) {
158         if (isLhs()) return this; // will be handled by the assign expr I'm in
159

160         Field field = getField();
161         if (field == null) return this; //XXX should be an error
162
//TypeDec fromTypeDec = getBytecodeTypeDec(); //fixer.fromTypeDec;
163
//getCompiler().showMessage(" isAccessible? " + field.toShortString());
164
if (field.isAccessible(this, true)) return this;
165
166         getCompiler().showMessage(" fixing privileged get: " + field.toShortString());
167
168         Method method = field.getBackdoorGetterMethod();
169         if (!fixer.apply) return this;
170
171         return getAST().makeCall(method, getExpr()).setSource(this);
172     }
173
174     public FieldAccessExpr(SourceLocation source, Type type, String JavaDoc name) {
175         this(source, null, type.getField(name, null, true), false);
176     }
177
178     public FieldAccessExpr(SourceLocation source, Expr expr, String JavaDoc name) {
179         this(source, expr, expr.getType().getField(name, expr, true), false);
180     }
181
182     public String JavaDoc getId() { return getField().getId(); }
183
184     //INTRO from MovingWalker
185
public ASTObject postMove(MovingWalker walker) {
186         return walker.moveLinkExpr(this);
187     }
188
189     //INTRO from ASTFixerPass
190
public ASTObject postFixAST(ASTFixerPass fixer) {
191         // handle introduced statics on interfaces
192
setExpr(field.updateTargetExpr(getExpr()));
193
194         if (!isLhs() && getField().getDeclaringType().isInterface() && !getField().isStatic()) {
195             return getAST().makeCall(getField().getBackdoorGetterMethod(), getExpr());
196         } else {
197             return this;
198         }
199     }
200
201     //SOLink interface
202
public SemanticObject getTarget() {
203         return getField();
204     }
205
206     public void setTarget(SemanticObject newTarget) {
207         setField((Field)newTarget);
208     }
209
210     public Type getTargetType() {
211         Type declaringType = getField().getDeclaringType();
212         if (declaringType.isInterface() && ! getOptions().strict) {
213             // dealing with buggy sun jdk 1.2.2 vm
214
return declaringType;
215         }
216         if (expr != null)
217             declaringType = expr.getType();
218         return declaringType;
219     }
220
221     public void unparse(CodeWriter writer) {
222         writer.write(expr);
223         writer.write('.');
224         writer.write(getField().getBytecodeId());
225     }
226
227     // ------------------------------
228
//INTRO from InnerAccessFixer
229

230     public ASTObject postInnerAccess(InnerAccessFixer w) {
231         if (isLhs()) return this;
232
233         Expr q = getExpr();
234         FieldDec dec = getFieldDec();
235         if (w.isAccessible(dec, q)) return this;
236
237         final AST ast = getAST();
238         Type qType = q.getType();
239         MethodDec newMethodDec = w.getAccessMethod(qType, dec, "x", this);
240         Exprs newArgs = ast.makeExprs();
241         Expr newExpr = w.makeOutsidePrimary(dec.isStatic(), newArgs, q);
242         return ast.makeCall(newMethodDec, newExpr, newArgs);
243     }
244
245     public MethodDec buildAccessMethod(InnerAccessFixer w) {
246         final AST ast = getAST();
247         Expr q = getExpr();
248         Type qType = q.getType();
249         FieldDec dec = getFieldDec();
250         Type fieldType = dec.getType();
251
252         Formals newFormals = ast.makeFormals();
253         Expr newExpr = w.makeInsidePrimary(dec.isStatic(), newFormals, qType);
254
255         return
256             w.makeAccessMethod(fieldType,
257                                newFormals,
258                                ast.makeGet(newExpr, dec));
259     }
260
261     // ------------------------------
262
// bcg
263

264     protected void cgLvalue(CodeBuilder cb) {
265         if (field.isStatic() || field.isConstant()) expr.cgEffect(cb);
266         else expr.cgValue(cb);
267     }
268     protected void cgLtoRvalue(CodeBuilder cb) {
269         if (expr.getType() instanceof ArrayType) {
270             cb.emitARRAYLENGTH();
271         } else {
272             NameType qualifyingType = (NameType) getTargetType();
273             String JavaDoc name = field.getBytecodeId();
274             String JavaDoc descriptor = field.getDescriptor();
275             int delta = getType().getSlotCount();
276             if (field.isConstant()) {
277                 field.getFieldDec().getInitializer().cgValue(cb);
278             } else if (field.isStatic()) {
279                 cb.emitGETSTATIC(qualifyingType, name, descriptor, delta);
280             } else {
281                 cb.emitGETFIELD(qualifyingType, name, descriptor, delta - 1);
282             }
283         }
284     }
285     protected void cgAssignment(CodeBuilder cb) {
286         NameType qualifyingType = (NameType) getTargetType();
287         String JavaDoc name = field.getBytecodeId();
288         String JavaDoc descriptor = field.getDescriptor();
289         int delta = getType().getSlotCount();
290         if (field.isStatic()) {
291             cb.emitPUTSTATIC(qualifyingType, name, descriptor, - delta);
292         } else {
293             cb.emitPUTFIELD(qualifyingType, name, descriptor, - delta - 1);
294         }
295     }
296     protected void cgDupLvalue(CodeBuilder cb) {
297         if (! field.isStatic()) cb.emitDUP();
298     }
299     protected void cgDupRvalue(CodeBuilder cb) {
300         if (field.isStatic()) getType().emitDup(cb);
301         else getType().emitDupX1(cb);
302     }
303
304     //BEGIN: Generated from @child and @property
305
protected Expr expr;
306     public Expr getExpr() { return expr; }
307     public void setExpr(Expr _expr) {
308         if (_expr != null) _expr.setParent(this);
309         expr = _expr;
310     }
311
312     protected Field field;
313     public Field getField() { return field; }
314     public void setField(Field _field) { field = _field; }
315
316     protected boolean isSuper;
317     public boolean getIsSuper() { return isSuper; }
318     public void setIsSuper(boolean _isSuper) { isSuper = _isSuper; }
319
320     public FieldAccessExpr(SourceLocation location, Expr _expr, Field _field, boolean _isSuper) {
321         super(location);
322         setExpr(_expr);
323         setField(_field);
324         setIsSuper(_isSuper);
325     }
326     protected FieldAccessExpr(SourceLocation source) {
327         super(source);
328     }
329
330     public ASTObject copyWalk(CopyWalker walker) {
331         FieldAccessExpr ret = new FieldAccessExpr(getSourceLocation());
332         ret.preCopy(walker, this);
333         if (expr != null) ret.setExpr( (Expr)walker.process(expr) );
334         ret.field = field;
335         ret.isSuper = isSuper;
336         return ret;
337     }
338
339     public ASTObject getChildAt(int childIndex) {
340         switch(childIndex) {
341         case 0: return expr;
342         default: return super.getChildAt(childIndex);
343         }
344     }
345      public String JavaDoc getChildNameAt(int childIndex) {
346         switch(childIndex) {
347         case 0: return "expr";
348         default: return super.getChildNameAt(childIndex);
349         }
350     }
351      public void setChildAt(int childIndex, ASTObject child) {
352         switch(childIndex) {
353         case 0: setExpr((Expr)child); return;
354         default: super.setChildAt(childIndex, child); return;
355         }
356     }
357      public int getChildCount() {
358         return 1;
359     }
360
361     public String JavaDoc getDefaultDisplayName() {
362         return "FieldAccessExpr(field: "+field+", "+"isSuper: "+isSuper+")";
363     }
364
365     //END: Generated from @child and @property
366
}
367
Popular Tags