KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > crosscuts > ast > NamePcd


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.crosscuts.ast;
26 import org.aspectj.compiler.base.ast.*;
27 import org.aspectj.compiler.base.cst.*;
28 import org.aspectj.compiler.crosscuts.joinpoints.*;
29 import org.aspectj.compiler.crosscuts.*;
30
31 import org.aspectj.compiler.base.JavaCompiler;
32
33 import java.util.*;
34
35 /**
36  * @grammar (parentName.)?id(formals)
37  * @child TypeD parentName
38  * @property String id
39  * @child FormalsPattern formals
40  * @property PointcutSO pointcut
41  */

42 public class NamePcd extends Pcd {
43     /** 1.2 substitute for Collections.EMPTY_MAP */
44     private static final Map EMPTY_MAP
45         = Collections.unmodifiableMap(new TreeMap());
46
47     public String JavaDoc toShortString() {
48         String JavaDoc ret = id + formals.toShortString();
49         if (parentName != null) {
50             ret = parentName.toShortString() + '.' + ret;
51         }
52         return ret;
53     }
54     
55     public void checkStatic() {
56         //XXX needs to include a pointer back to the static context it is being used in
57
getPointcut().getPcd().checkStatic();
58     }
59     
60     //XXX helper method will go away
61
public PointcutDec getPointcutDec() {
62         return getPointcut().getPointcutDec();
63     }
64     
65     /**
66      * This is a different form of name binding than in this, target and args
67      */

68     public boolean allowsNameBinding() { return true; }
69
70     public JpPlanner makePlanner(PlanData planData) {
71         if (planData.isPlanning(this)) {
72             showError("recursive pointcut reference not allowed");
73             return JpPlanner.NO_PLANNER;
74         }
75         
76         PointcutSO innerPointcut = concretizePointcut(planData.getNameBindingType());
77         if (innerPointcut.isAbstract()) {
78             planData.getPlanMaker().showError("references an abstract pointcut -- see below");
79             innerPointcut.getCorrespondingDec().showError("can't use abstract pointcut where concrete is required");
80         }
81         
82         final JpPlanner planner =
83                 innerPointcut.getPcd().makePlanner(planData.makeInner(this));
84         final Map remapFormals = makeFormalsRemap(innerPointcut);
85         
86         //??? it would be nice to do the actual remapping of FormalDecs at Planner
87
//??? creation time, not during the actual makePlan call
88
return new WrappedJpPlanner(planner) {
89             public JpPlan makePlan(JoinPoint jp) {
90                 JpPlan plan = super.makePlan(jp);
91                 if (plan == JpPlan.NEVER_PLAN ||
92                     plan == JpPlan.NO_PLAN) {
93                         return plan;
94                 }
95                 plan.moveBindings(remapFormals);
96                 return plan;
97             }
98         };
99     }
100     
101     Map makeFormalsRemap(PointcutSO pointcut) {
102         GenTypeNames params = getFormals().getNames();
103         Formals decFormals = pointcut.getFormals();
104         
105         final int N = params.size();
106         if (decFormals.size() != N) {
107             getFormals().showError("arguments don't match pointcut signature: " +
108                         pointcut.getFormals().toShortString());
109             return NamePcd.EMPTY_MAP;
110         }
111         
112         Map remap = new HashMap();
113         for (int i = 0; i < N; i++) {
114             FormalDec formal = decFormals.get(i);
115             GenTypeName param = params.get(i);
116             
117             //???
118
if (param.matchesInstance(formal.getType()).maybeFalse()) {
119                 param.showError("doesn't match " + formal.getType().getString());
120                 break;
121             }
122             
123             if (param instanceof VarTypeName) {
124                 FormalDec paramFormal = ((VarTypeName)param).getFormalDec();
125                 remap.put(formal, paramFormal);
126             }
127         }
128         return remap;
129     }
130
131     //INTRO from ScopeWalker
132
public ASTObject postScope(ScopeWalker walker) {
133         if (!walker.walkBodies()) return this;
134         if (pointcut != null) return this;
135         bindPointcut();
136         return super.postScope(walker);
137     }
138     
139     private PointcutSO findPointcut() {
140         if (isStaticReference()) {
141             PointcutSO ret = parentName.getType().getPointcut(id, this, true);
142             if (ret.isAbstract()) {
143                 this.showError("can't reference abstract pointcut using static qualified name: " +
144                     ret.toShortString());
145             }
146             return ret;
147         } else {
148             Type inType = getLexicalType();
149             PointcutSO ret = inType.getPointcut(id, this, false);
150             if (ret != null) return ret;
151             
152             // if my immediate type doesn't containt a matching pointcut, then
153
// walk up through enclosing types to see if any of them contain
154
// a matching declaration for this pointcut name
155
while (ret == null) {
156                 inType = inType.getDeclaringType();
157                 if (inType == null || inType == getTypeManager().TYPE_NOT_FOUND) {
158                     showError("named pointcut not found: " + toShortString());
159                     return ret;
160                 }
161                 ret = inType.getPointcut(id, this, false);
162             }
163             
164             // if I'm in an enclosing aspect, then this is a static reference
165
// make it explicitly one
166
setParentName(inType.makeTypeD());
167             if (ret.isAbstract()) {
168                 this.showError("can't reference abstract pointcut using static qualified name: " +
169                 ret.toShortString());
170             }
171             
172             return ret;
173         }
174     }
175     
176     private boolean isStaticReference() { return parentName != null; }
177         
178     private void bindPointcut() {
179         pointcut = findPointcut();
180         ((AspectJCompiler)getCompiler()).getCorrespondences().
181                 addPointsTo(findNonPcd(getParent()), pointcut.getPointcutDec());
182     }
183
184     private ASTObject findNonPcd(ASTObject node) {
185         if (!(node instanceof Pcd)) return node;
186         return findNonPcd(node.getParent());
187     }
188
189
190
191     public PointcutSO concretizePointcut(Type inType) {
192         // fast fail to avoid generate duplicate error messages
193
if (pointcut == null) return null;
194         
195         if (inType == null || isStaticReference()) return pointcut;
196
197         PointcutSO ret = pointcut;
198         
199         //XXX i don't like the structure of this loop
200
//ClassDec inTypeDec = inAspect;
201
while (inType != ret.getDeclaringType()) {
202             if (!ret.getModifiers().isPrivate() && ret.isAccessible(inType.getTypeDec().getBody())) {
203                 ret = inType.getPointcut(id, inType.getTypeDec().getBody(), true);
204                 break;
205             }
206             inType = inType.getTypeDec().getSuperClassType();
207         }
208
209         return ret;
210     }
211     
212     //BEGIN: Generated from @child and @property
213
protected TypeD parentName;
214     public TypeD getParentName() { return parentName; }
215     public void setParentName(TypeD _parentName) {
216         if (_parentName != null) _parentName.setParent(this);
217         parentName = _parentName;
218     }
219     
220     protected String JavaDoc id;
221     public String JavaDoc getId() { return id; }
222     public void setId(String JavaDoc _id) { id = _id; }
223     
224     protected FormalsPattern formals;
225     public FormalsPattern getFormals() { return formals; }
226     public void setFormals(FormalsPattern _formals) {
227         if (_formals != null) _formals.setParent(this);
228         formals = _formals;
229     }
230     
231     protected PointcutSO pointcut;
232     public PointcutSO getPointcut() { return pointcut; }
233     public void setPointcut(PointcutSO _pointcut) { pointcut = _pointcut; }
234     
235     public NamePcd(SourceLocation location, TypeD _parentName, String JavaDoc _id, FormalsPattern _formals, PointcutSO _pointcut) {
236         super(location);
237         setParentName(_parentName);
238         setId(_id);
239         setFormals(_formals);
240         setPointcut(_pointcut);
241     }
242     protected NamePcd(SourceLocation source) {
243         super(source);
244     }
245     
246     public ASTObject copyWalk(CopyWalker walker) {
247         NamePcd ret = new NamePcd(getSourceLocation());
248         ret.preCopy(walker, this);
249         if (parentName != null) ret.setParentName( (TypeD)walker.process(parentName) );
250         ret.id = id;
251         if (formals != null) ret.setFormals( (FormalsPattern)walker.process(formals) );
252         ret.pointcut = pointcut;
253         return ret;
254     }
255     
256     public ASTObject getChildAt(int childIndex) {
257         switch(childIndex) {
258         case 0: return parentName;
259         case 1: return formals;
260         default: return super.getChildAt(childIndex);
261         }
262     }
263      public String JavaDoc getChildNameAt(int childIndex) {
264         switch(childIndex) {
265         case 0: return "parentName";
266         case 1: return "formals";
267         default: return super.getChildNameAt(childIndex);
268         }
269     }
270      public void setChildAt(int childIndex, ASTObject child) {
271         switch(childIndex) {
272         case 0: setParentName((TypeD)child); return;
273         case 1: setFormals((FormalsPattern)child); return;
274         default: super.setChildAt(childIndex, child); return;
275         }
276     }
277      public int getChildCount() {
278         return 2;
279     }
280     
281     public String JavaDoc getDefaultDisplayName() {
282         return "NamePcd(id: "+id+", "+"pointcut: "+pointcut+")";
283     }
284     
285     //END: Generated from @child and @property
286
}
287
288
Popular Tags