KickJava   Java API By Example, From Geeks To Geeks.

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


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.base.cst.*;
29
30
31 import java.io.StringWriter JavaDoc;
32 import org.aspectj.util.JavaStrings;
33
34 import org.aspectj.compiler.base.bcg.ClassfileBuilder;
35
36 /**
37   * @grammar ...
38   * @##child Modifiers modifiers
39   *
40   */

41 public abstract class Dec extends Stmt {
42     protected SemanticObject semanticObject;
43
44     public SemanticObject getCorrespondingSemanticObject() {
45         if (semanticObject == null) semanticObject = makeCorrespondingSemanticObject();
46         return semanticObject;
47     }
48
49     //XXX should be abstract
50
public SemanticObject makeCorrespondingSemanticObject() { return null; }
51
52     protected final BlockScope makeBlockScope(ScopeWalker walker) {
53         Scope parent = walker.getScope();
54         if (!walker.useJavaScopes() && fromLexicalScope != null) {
55             return new CrosscuttingBlockScope(getCompiler(),
56                 fromLexicalScope, getDeclaringType());
57         }
58         return new BlockScope(getCompiler(), null);
59     }
60
61     public void requireStmt() {
62         this.showError("statement required, but declaration found");
63     }
64
65     private boolean isDeprecated;
66
67     public boolean isDeprecated() {
68         return isDeprecated;
69     }
70
71     public void setDeprecated(boolean isDeprecated) {
72         this.isDeprecated = isDeprecated;
73     }
74
75     public boolean inStaticContext() {
76         //System.out.println("static? " + toShortString() + " == " + isStatic());
77
return isStatic();
78     }
79
80     private boolean explicitlyLanguageVisible = false;
81
82     public boolean isLanguageVisible() {
83         return !isSynthetic() || explicitlyLanguageVisible;
84     }
85
86     public void setLanguageVisible() {
87         explicitlyLanguageVisible = true;
88     }
89     
90     
91     private boolean explicitlyNonSynthetic = false;
92
93     public boolean isSynthetic() {
94         if (explicitlyNonSynthetic) return false;
95         else return super.isSynthetic();
96     }
97
98     public void setExplicitlyNonSynthetic() {
99         explicitlyNonSynthetic = true;
100     }
101
102     protected String JavaDoc addIntroducedFromType(String JavaDoc s) {
103         if (!isIntroduced()) return s;
104         return s + " from " + getLexicalType().toShortString();
105     }
106
107     public boolean isIntroduced() {
108         // this is a good working definition of an introduction
109
return getLexicalType() != getDeclaringType();
110     }
111
112     public Dec owner = null;
113
114
115     private Type declaringType = null;
116     private Type lexicalType = null;
117
118     private Scope fromLexicalScope = null;
119     public void setFromLexicalScope(Scope fromScope) {
120         fromLexicalScope = fromScope;
121     }
122
123     public void setAllEnclosingTypes(Type type) {
124         setDeclaringType(type);
125         setLexicalType(type);
126     }
127
128     public void setDeclaringType(Type type) { declaringType = type; }
129
130     public Type getDeclaringType() {
131         if (declaringType == null) declaringType = lookupDeclaringType();
132         return declaringType;
133     }
134
135     public void setLexicalType(Type type) { lexicalType = type; }
136
137     public Type getLexicalType() {
138         if (lexicalType == null) lexicalType = lookupLexicalType();
139         return lexicalType;
140     }
141
142     public Type getOutermostLexicalType() {
143         if (lexicalType == null) return super.getOutermostLexicalType();
144         return lexicalType.getTypeDec().getOutermostLexicalType();
145     }
146
147     protected Type lookupDeclaringType() {
148         //System.out.println(getParent());
149
if (getParent() == null) {
150             this.showError("no parent: "); // + this);
151
return null;
152         }
153
154         if (getParent().getParent() instanceof TypeDec) {
155             return ((TypeDec)getParent().getParent()).getType();
156         } else {
157             return super.getDeclaringType();
158         }
159     }
160
161     protected Type lookupLexicalType() {
162         //System.out.println(getParent());
163
if (getParent() == null) {
164             //this.showError("no parent: "); // + this);
165
return null;
166         }
167
168         if (getParent().getParent() instanceof TypeDec) {
169             return ((TypeDec)getParent().getParent()).getType();
170         } else {
171             return super.getLexicalType();
172         }
173     }
174
175     // ------------------------------
176
// Intro: ForwardReferenceChecker
177

178     public void walkForwardReference(ForwardReferenceChecker w) {
179         this.walk(w.createBodyChecker());
180     }
181
182     //INTRO from CopyWalker
183
public ASTObject postCopy(CopyWalker walker, ASTObject oldObject) {
184         this.declaringType = null; //walker.moveType(((Dec)oldObject).declaringType);
185
// System.out.println("moveType: "
186
// + walker.moveType(((Dec)oldObject).declaringType));
187
this.lexicalType = null; //walker.moveType(((Dec)oldObject).lexicalType);
188
this.explicitlyLanguageVisible = ((Dec)oldObject).explicitlyLanguageVisible;
189         this.explicitlyNonSynthetic = ((Dec)oldObject).explicitlyNonSynthetic;
190
191
192         //??? how do we handle copying of SO's???
193
walker.addMapping(((Dec)oldObject).getCorrespondingSemanticObject(),
194                                 getCorrespondingSemanticObject());
195         return super.postCopy(walker, oldObject);
196     }
197
198     public void preCopy(CopyWalker walker, ASTObject oldObject) {
199         walker.addMapping(oldObject, this);
200         walker.addMapping(((Dec)oldObject).getCorrespondingSemanticObject(),
201                                 getCorrespondingSemanticObject());
202     }
203     //INTRO from MovingWalker ???
204
public void preMove(MovingWalker walker) {
205         walker.addMapping(this, this);
206         walker.addMapping(getCorrespondingSemanticObject(),
207                                 getCorrespondingSemanticObject());
208     }
209
210     // delegate all of these to modifiers
211
public boolean isPublic() {
212         return getModifiers().isPublic();
213     }
214     public boolean isFinal() {
215         return getModifiers().isFinal();
216     }
217     public boolean isPrivate() {
218         return getModifiers().isPrivate();
219     }
220     public boolean isProtected() {
221         return getModifiers().isProtected();
222     }
223     public boolean isStatic() {
224         return getModifiers().isStatic();
225     }
226     public boolean isAbstract() {
227         return getModifiers().isAbstract();
228     }
229
230     public abstract Modifiers getModifiers();
231
232     public boolean forcePublic = false;
233     public void forcePublic() {
234         if (!isPublic()) forcePublic = true;
235     }
236
237     public boolean isMoreAccessibleThan(Dec other) {
238         return getModifiers().isMoreAccessibleThan(other.getModifiers());
239     }
240
241
242     public boolean isMoreSpecificThan(Dec other) {
243         // require that T1 is method convertable to T2
244
Type type1 = this.getDeclaringType();
245         Type type2 = other.getDeclaringType();
246         return type1.isMethodConvertableTo(type2);
247     }
248
249
250     public boolean isApplicable(Exprs parameters) {
251         return true;
252     }
253
254     public boolean isAlmostApplicable(Exprs params) { return true; }
255
256
257     boolean hasPrivilegedAccess(ASTObject fromWhere) {
258         //XXX needs to be cleaned up over time
259
if (fromWhere == null) return true;
260
261         Type fromType = fromWhere.getLexicalType();
262         while (fromType != null) {
263             TypeDec td = fromType.getTypeDec();
264             if (td == null) return false;
265             if (td.getModifiers().isPrivileged()) return true;
266             fromType = td.getLexicalType();
267         }
268         return false;
269     }
270
271     public boolean isAccessible(ASTObject fromWhere) {
272         return isAccessible(fromWhere, false);
273     }
274
275     public boolean isAccessible(ASTObject fromWhere, boolean inBytecode) {
276 // if (fromWhere instanceof TypeDec) {
277
// fromWhere.showError("checking access from type dec");
278
// }
279
if (isPublic()) return true;
280
281         if (!inBytecode && hasPrivilegedAccess(fromWhere)) return true;
282
283         Type toType;
284         Type fromType;
285         if (inBytecode) {
286             toType = getBytecodeType();
287             if (fromWhere.getBytecodeTypeDec() == null) fromType = null;
288             else fromType = fromWhere.getBytecodeTypeDec().getType();
289         } else {
290             toType = getLexicalType();
291             fromType = fromWhere.getLexicalType();
292         }
293
294 // fromWhere.showWarning(toShortString() + ": " +
295
// toType + " -> " + fromType);
296

297         // special case for import statements
298
if (fromType == null) {
299             //System.out.println(toShortString() + ", " + toType + ", " + fromWhere);
300
if (isPrivate()) {
301                 return false;
302             } else {
303                 return samePackage(fromType, toType, fromWhere);
304             }
305         }
306
307         if (isPrivate()) {
308             if (inBytecode) {
309                 return toType.getOutermostBytecodeType() == fromType.getOutermostBytecodeType();
310             } else {
311                 // */
312
if (fromType == null || toType == null) return false;
313             return fromType.getOutermostLexicalType()
314                 == toType.getOutermostLexicalType();
315             // /*
316
}
317             // */
318
} else if (isProtected()) {
319             if (samePackage(fromType, toType, fromWhere)) return true;
320             if (fromType == null || toType == null) return false;
321 // System.out.println(" subtype? " + fromType.isSubtypeOf(toType));
322
while (true) {
323                 if (fromType.isSubtypeOf(toType)) break;
324                 //XXXif (inBytecode) fromType = fromType.getTypeDec().getBytecodeType();
325
fromType = fromType.getTypeDec().getLexicalType();
326                 if (fromType== null) return false;
327             }
328
329             // special rules from JLSv2 6.6.2 only for instance fields and methods
330
// and constructors
331
if (isStatic()) return true;
332             if (this instanceof TypeDec) return true;
333
334             return fromWhere.hasLegalProtectedAccess(fromType);
335         } else { // package private
336
return samePackage(fromType, toType, fromWhere);
337         }
338     }
339
340     public boolean samePackage(Type fromType, Type thisType, ASTObject fromWhere) {
341         String JavaDoc p1, p2;
342         if (thisType == null) {
343             p1 = getCompilationUnit().getPackageName();
344         } else {
345             p1 = thisType.getPackageName();
346         }
347         if (fromType == null) {
348             p2 = fromWhere.getCompilationUnit().getPackageName();
349         } else {
350             p2 = fromType.getPackageName();
351         }
352         return nameMatches(p1, p2);
353     }
354
355     static boolean nameMatches(String JavaDoc p1, String JavaDoc p2) {
356         //System.err.println(toShortString() + ", " + p1 + "::" + p2);
357
if (p1 == null) return p2 == null;
358         else return p1.equals(p2);
359     }
360
361
362     public boolean isInherited(Type inType) {
363         if (isPrivate()) return this.isIntroduced();
364         
365         if (this.isIntroduced()) return true;
366         
367         if (this.isAccessible(inType.getTypeDec().getBody())) return true;
368         
369         if (!(this instanceof TypeDec) && this.isAbstract()) {
370             inType.getTypeDec().showError("The member '" + toShortString() +
371                 "' has default access and hence is not inherited and can not be made concrete");
372         }
373         
374         return false;
375     }
376
377     public boolean conflictsWith(Dec otherDec) {
378         if (!getId().equals(otherDec.getId())) return false;
379
380         if (!this.isAccessible(otherDec) && !otherDec.isAccessible(this)) return false;
381         if (this.getDeclaringType() == otherDec.getDeclaringType()) return true;
382         return false;
383     }
384
385     public boolean checkOverride(Type inType, Dec otherDec) { return false; }
386
387     public boolean dominates(Dec otherDec) {
388         if (this == otherDec) return false;
389
390         if (getDeclaringType() != otherDec.getDeclaringType()) return false;
391
392         if (isIntroduced() && otherDec.isIntroduced()) {
393             return getLexicalType().dominates(otherDec.getLexicalType());
394         }
395         return false;
396     }
397
398
399 // public boolean canOverride(Dec otherDec) {
400
// if (this == otherDec) return true;
401

402 // if (this.getDeclaringType().isSubtypeOf(otherDec.getDeclaringType())) return true;
403

404 // if (isIntroduced() && otherDec.isIntroduced()) {
405
// return (getLexicalType().dominates(otherDec.getLexicalType()));
406
// }
407

408 // return false;
409
// }
410

411     public String JavaDoc getSignatureString() {
412         //StringWriter stringBuf = new StringWriter();
413
CodeWriter writer = new CodeWriter(getCompiler());
414         writer.setOnlySignatures(true);
415         writer.write(this);
416
417         return writer.getString();
418     }
419
420     //XXX should be abstract
421
public abstract String JavaDoc getKind();
422
423     private String JavaDoc bytecodeId = null;
424     public String JavaDoc getBytecodeId() {
425         if (bytecodeId == null) return getId();
426         return bytecodeId;
427     }
428
429     public void setBytecodeId(String JavaDoc id) {
430         bytecodeId = id;
431     }
432
433     //XXX should be abstract
434
public void setId(String JavaDoc id) {}
435
436     //!!! remove
437
public String JavaDoc getName() {
438         return getId();
439     }
440
441     //!!! should be abstract
442
public abstract String JavaDoc getId();
443     public abstract String JavaDoc toShortString();
444
445     public void writeNames(CodeWriter writer, String JavaDoc label, TypeDs names) {
446         if (names == null || names.size() == 0) return;
447
448         writer.requiredSpace();
449         writer.writeKeyword(label);
450         writer.requiredSpace();
451         writer.write(names);
452     }
453
454     public void writeModifiers(CodeWriter writer) {
455         if (getModifiers() == null) return;
456
457         if (forcePublic) {
458             Modifiers mods = (Modifiers)getModifiers().copy();
459             mods.setPublic(true);
460             writer.write(mods);
461         } else {
462             writer.write(getModifiers());
463         }
464     }
465
466     public void cleanup() {
467         super.cleanup();
468     }
469
470     //XXX don't belong here
471
public String JavaDoc getDescriptor() { return null; }
472     public int getStackDelta() { return 0; }
473
474     // ------------------------------
475
// bcg
476

477     /** This method takes care of generating code for Member decs. At
478         this point in the compilation, we should only have two kinds
479         of Member decs, {@link FieldDec} and {@link CodeDec}.
480         Moreover, {@link FieldDec}s should not have initializers
481         unless they're constants. This method throws an error if it
482         is ever invoked: {@link FieldDec} and {@link CodeDec} override it.
483     */

484     protected void cgMember(ClassfileBuilder maker) {
485         //throw new RuntimeException("Invalid dec " + this);
486
}
487
488     //BEGIN: Generated from @child and @property
489

490     public Dec(SourceLocation location) {
491         super(location);
492
493     }
494
495
496     public String JavaDoc getDefaultDisplayName() {
497         return "Dec()";
498     }
499
500     //END: Generated from @child and @property
501
}
502
Popular Tags