KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > crosscuts > JoinPointCollector


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;
26
27 import org.aspectj.compiler.crosscuts.ast.*;
28 import org.aspectj.compiler.crosscuts.joinpoints.*;
29
30 import org.aspectj.compiler.base.ast.*;
31 import org.aspectj.compiler.base.*;
32 import org.aspectj.util.CollectionUtil;
33
34 import java.util.*;
35
36 /**************************************************************************
37  * Weave into a single TypeDec
38  */

39 public class JoinPointCollector extends CompilerObject {
40     TypeDec typeDec;
41     
42     public JoinPointCollector(TypeDec typeDec) {
43         super(typeDec.getCompiler());
44         this.typeDec = typeDec;
45     }
46     
47     public void collect() {
48         if (typeDec.isSynthetic()) return;
49         getCompiler().showMessage(" collecting join point shadows for " + typeDec.toShortString());
50         collectJoinPoints();
51         //System.out.println("wove: " + typeDec.unparse());
52
}
53     
54     /* Need to replicate this for synthetic callee-side call points *
55     void planSyntheticReceptionPoints() {
56         Collection inheritedMethods = typeDec.getType().getInheritedMethods();
57         
58         for (Iterator iter = inheritedMethods.iterator(); iter.hasNext(); ) {
59             Method method = (Method)iter.next();
60             if (method.isStatic()) continue;
61             
62             //XXX only make synthetic reception points when the parent
63             //XXX method isn't available to us
64             if (method.getMethodDec().fromSource()) continue;
65             
66             //XXX don't make synthetic reception points for final methods
67             if (method.getMethodDec().isFinal()) continue;
68             
69             planJoinPoint(new SyntheticReceptionPoint(getCompiler(),typeDec, method.getMethodDec()));
70         }
71     }
72     /**/

73     
74     void collectJoinPoints() {
75 // JoinPoint staticInitializerExecutionPoint =
76
// new StaticInitializerExecutionPoint(getCompiler(),typeDec);
77

78         //!!! interfaces don't have static initializers
79
if (!(typeDec instanceof InterfaceDec)) {
80             planInitializerExecution(typeDec.getSingleInitializerDec(true));
81         }
82         planInitializerExecution(typeDec.getSingleInitializerDec(false));
83         
84         //XXX this design depends on typeDec.getBody() not being modified during loop
85
Decs decs = typeDec.getBody();
86         //final int N = decs.size();
87
for (int i = 0; i < decs.size(); i++) {
88             Dec dec = decs.get(i);
89             //System.out.println("dec: " + dec.toShortString());
90

91             if (dec instanceof InitializerDec) {
92                 //System.out.println("planning body");
93
continue;
94             } else if (dec instanceof CodeDec) {
95                 planJoinPoints((CodeDec)dec);
96             } else if (dec instanceof TypeDec) {
97                 new JoinPointCollector((TypeDec)dec).collect();
98             } else if (dec instanceof FieldDec) {
99                 FieldDec field = (FieldDec)dec;
100                 // don't do anything with fields
101
// their initializers are handled by the initializer decs
102
} else {
103                 continue;
104             }
105         }
106     }
107
108
109     void planInitializerExecution(InitializerDec dec) {
110         JoinPoint jp;
111         if (dec.isStatic()) {
112             jp = new StaticInitializerExecutionJp(dec);
113         } else {
114             jp = new InstanceInitializerExecutionJp(dec);
115         }
116         planBodyJoinPoints(dec, jp);
117         planJoinPoint(jp);
118     }
119     
120     JoinPoint makeExecutionJoinPoint(CodeDec codeDec) {
121         //System.out.println(codeDec.toShortString() + ", " + codeDec.isAdvisable());
122
if (codeDec.isAbstract() || codeDec.getBody() == null) return null;
123         if (!codeDec.isLanguageVisible()) return null;
124         
125         //System.out.println(codeDec.toShortString());
126

127         if (codeDec instanceof MethodDec) {
128             return new MethodExecutionJp((MethodDec)codeDec);
129         } else if (codeDec instanceof ConstructorDec) {
130             return new ConstructorExecutionJp((ConstructorDec)codeDec);
131         } else if (codeDec instanceof AdviceDec) {
132             return new AdviceExecutionJp((AdviceDec)codeDec);
133         } else if (codeDec instanceof InitializerDec) {
134             // initializers are handled specially
135
return null;
136         } else {
137             throw new RuntimeException JavaDoc("unexpected code: " + codeDec.getClass().getName());
138         }
139     }
140     
141     CalleeSideCallJp planCalleeSideCallPoint(MethodDec methodDec) {
142         if (!methodDec.fromSource()) return null;
143         
144         //???
145
if (methodDec.isAbstract()) return null;
146         
147         CalleeSideCallJp point = (CalleeSideCallJp)getWorld().calleeSideCallPoints.get(methodDec);
148         if (point == null) {
149             point = new CalleeSideCallJp(methodDec.getDeclaringType().getTypeDec(), methodDec);
150             getWorld().calleeSideCallPoints.put(methodDec, point);
151         }
152         
153         return point;
154     }
155     
156     void planCallPoint(AnyCallExpr callExpr, JoinPoint enclosingJp) {
157         if (callExpr instanceof CallExpr) {
158             planBodyJoinPoint(new MethodCallJp((CallExpr)callExpr, enclosingJp));
159         } else {
160             planBodyJoinPoint(new ConstructorCallJp((NewInstanceExpr)callExpr, enclosingJp));
161         }
162     }
163     
164     void planJoinPoints(CodeDec codeDec) {
165         if (!codeDec.isLanguageVisible()) return;
166         
167         JoinPoint executionPoint = makeExecutionJoinPoint(codeDec);
168         
169         if (executionPoint != null) {
170             planBodyJoinPoints(codeDec.getBody(), executionPoint);
171             
172             //XXX order matters here because of implementation for enclosingExecutionPoint
173
planJoinPoint(executionPoint);
174         }
175         
176         if (codeDec instanceof ConstructorDec) {
177             planJoinPoint(new InitializationJp((ConstructorDec)codeDec));
178         }
179         
180         if (codeDec instanceof MethodDec) {
181             JoinPoint calleeCallPoint = planCalleeSideCallPoint((MethodDec)codeDec);
182             if (calleeCallPoint != null) typeDec.joinPoints2.add(calleeCallPoint);
183         }
184     }
185     
186     void planBodyJoinPoints(ASTObject node, JoinPoint executionPoint) {
187         //if (!anyBodyPoints) return;
188

189         new BodyPointPlanner(getCompiler(), executionPoint).process(node);
190     }
191     
192     void planJoinPoint(JoinPoint jp) {
193         typeDec.joinPoints2.add(jp);
194     }
195     
196     void planBodyJoinPoint(CodeBodyJp jp) {
197         typeDec.joinPoints1.add(jp);
198         if (jp.getEnclosingExecutionJoinPoint() instanceof AdviceExecutionJp) {
199             AdviceDec ad =
200                 (AdviceDec)jp.getEnclosingExecutionJoinPoint().getTargetDec();
201             if (ad instanceof AroundAdviceDec) {
202                 ((AroundAdviceDec)ad).joinPoints1.add(jp);
203             }
204         }
205     }
206     
207
208     
209     class BodyPointPlanner extends Walker {
210         JoinPoint enclosingExecutionJoinPoint;
211         
212         public BodyPointPlanner(JavaCompiler compiler, JoinPoint enclosingExecutionJoinPoint) {
213             super(compiler);
214             this.enclosingExecutionJoinPoint = enclosingExecutionJoinPoint;
215         }
216         
217         public boolean preProcess(ASTObject node) {
218             if (node instanceof ConstructorCallExpr) {
219                 if (!(enclosingExecutionJoinPoint instanceof PreInitializationJp)) {
220                     JoinPoint preInitPoint =
221                         new PreInitializationJp((ConstructorDec)node.getEnclosingCodeDec());
222                     planJoinPoint(preInitPoint);
223                     new BodyPointPlanner(this.getCompiler(), preInitPoint).process(node);
224                     return false;
225                 } else {
226                     return true;
227                 }
228             }
229             
230             //XXX don't capture new array operations
231
if (node instanceof AnyCallExpr && !(node instanceof NewArrayExpr)) {
232                 AnyCallExpr callExpr = (AnyCallExpr)node;
233                 
234                 Expr expr = callExpr.getExpr();
235                 if (callExpr instanceof CallExpr && ((CallExpr)callExpr).getIsSuper()) {
236                     // super calls don't count as "calls" joinpoints
237
// but we have to give them very special handling regarding
238
// callee-side call joinpoints
239
//????maybeFixSuperCall((CallExpr)callExpr);
240
return true;
241                 }
242                 
243                 //make sure we don't count proceed as a call
244
if (expr instanceof ProceedExpr) {
245                     return true;
246                 }
247                 
248                 planCallPoint(callExpr, enclosingExecutionJoinPoint);
249             } else if (node instanceof CatchClause) {
250                 CatchClause catchClause = (CatchClause)node;
251                 planBodyJoinPoint(new ExceptionHandlerJp(catchClause, enclosingExecutionJoinPoint));
252             } else if (node instanceof TypeDec) {
253                 new JoinPointCollector((TypeDec)node).collect();
254                 return false;
255             } else if (node instanceof FieldAccessExpr) {
256                 FieldAccessExpr fieldAccessExpr = (FieldAccessExpr)node;
257                 if (fieldAccessExpr.isLhs()) {
258                     BangExpr bangExpr = (BangExpr)node.getParent();
259                     
260                     if (bangExpr instanceof BasicAssignExpr) {
261                         addSetPoint((AssignExpr) bangExpr);
262                     } else {
263                         SyntheticGetSet synExpr = new SyntheticGetSet(this.getCompiler(), bangExpr);
264                         addSetPoint(fieldAccessExpr, synExpr);
265                         addGetPoint(fieldAccessExpr, synExpr);
266                     }
267                 } else {
268                     addGetPoint(fieldAccessExpr);
269                 }
270             }
271             
272             return true;
273         }
274         
275         void addGetPoint(final FieldAccessExpr fieldAccessExpr) {
276             FieldGetJp point = new FieldGetJp(
277                 new FieldGetJp.FieldGetExprPromise() {
278                     public FieldAccessExpr getFieldAccessExpr() { return fieldAccessExpr; }
279                     
280                     public FieldDec getFieldDec() { return getFieldAccessExpr().getFieldDec(); }
281                     public Expr getSourceExpr() { return fieldAccessExpr; }
282                     public Type getTargetType() { return getFieldAccessExpr().getTargetType(); }
283                     public ASTObject getSourceLocation() { return fieldAccessExpr; }
284                 },
285                 enclosingExecutionJoinPoint);
286             planBodyJoinPoint(point);
287         }
288         
289         FieldSetJp.FieldSetExprPromise makeFieldSetExprPromise(
290               final FieldAccessExpr fieldAccessExpr,
291               final SyntheticGetSet synGetSet, final boolean useBang)
292         {
293             return new FieldSetJp.FieldSetExprPromise() {
294                     public AssignExpr getAssignExpr() { synGetSet.makeConcrete(); return synGetSet.makeSetExpr(); }
295                     public FieldAccessExpr getFieldAccessExpr() {
296                         synGetSet.makeConcrete(); return synGetSet.makeGetExpr(); }
297                     
298                     public FieldDec getFieldDec() { return fieldAccessExpr.getFieldDec(); }
299                     public Expr getSourceExpr() {
300                         if (useBang) return synGetSet.getBangExpr();
301                         else return fieldAccessExpr;
302                     }
303                     public Type getTargetType() { return fieldAccessExpr.getTargetType(); }
304                     public ASTObject getSourceLocation() { return fieldAccessExpr; }
305                 };
306         }
307         
308         void addGetPoint(FieldAccessExpr fieldAccessExpr, SyntheticGetSet synGetSet) {
309             planBodyJoinPoint(new FieldGetJp(
310                 makeFieldSetExprPromise(fieldAccessExpr, synGetSet, false),
311                 enclosingExecutionJoinPoint));
312         }
313         
314         void addSetPoint(FieldAccessExpr fieldAccessExpr, SyntheticGetSet synGetSet) {
315             //FieldAccessExpr fieldAccessExpr = (FieldAccessExpr)assignExpr.getLhs();
316
planBodyJoinPoint(new FieldSetJp(
317                         makeFieldSetExprPromise(fieldAccessExpr, synGetSet, true),
318                         enclosingExecutionJoinPoint));
319         }
320         void addSetPoint(final AssignExpr assignExpr) {
321             FieldSetJp point = new FieldSetJp(
322                 new FieldSetJp.FieldSetExprPromise() {
323                     public AssignExpr getAssignExpr() { return assignExpr; }
324                     public FieldAccessExpr getFieldAccessExpr() {
325                         return (FieldAccessExpr)assignExpr.getLhs(); }
326                     
327                     public FieldDec getFieldDec() { return getFieldAccessExpr().getFieldDec(); }
328                     public Expr getSourceExpr() { return assignExpr; }
329                     public Type getTargetType() { return getFieldAccessExpr().getTargetType(); }
330                     public ASTObject getSourceLocation() { return assignExpr; }
331                 },
332                 enclosingExecutionJoinPoint);
333             
334             planBodyJoinPoint(point);
335         }
336     }
337 }
338
339
Popular Tags