KickJava   Java API By Example, From Geeks To Geeks.

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


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
27 import org.aspectj.compiler.base.ast.*;
28 import org.aspectj.compiler.base.*;
29 import org.aspectj.compiler.crosscuts.joinpoints.*;
30
31
32 import java.util.*;
33
34 import org.aspectj.util.*;
35
36 /**
37  * @grammar cflow(pcd)
38  * @child Pcd pcd
39  * @property boolean includesRoot
40  */

41
42 public class CFlowPcd extends Pcd {
43     public String JavaDoc toShortString() {
44         return "cflow" + (includesRoot ? CFlowPlanner.NO_ROOT_NAME : "")
45                   + "(" + getPcd().toShortString() + ")";
46     }
47     
48     public void checkStatic() { showNonStaticError(); }
49     
50     public JpPlanner makePlanner(PlanData planData) {
51         findFlowState();
52         Map extraPlanners = planData.inAspect.getExtraPlanners();
53         if (!extraPlanners.containsKey(this)) {
54             extraPlanners.put(this,
55                               makeEntryPointInitializer(planData));
56         }
57
58         final CflowField field = getCflowField(planData.inAspect);
59         return new JpPlanner() {
60             public FuzzyBoolean fastMatch(JoinPoint jp) {
61                 return FuzzyBoolean.MAYBE;
62             }
63             public JpPlan makePlan(JoinPoint jp) {
64                 JpPlan plan = new JpPlan(jp);
65                 plan.test = field.testStackExpr();
66                 plan.addDependency(field);
67                 field.remapExprs(plan);
68                 return plan;
69             }
70         };
71     }
72     
73     private JpPlanner makeEntryPointInitializer(PlanData planData) {
74         findFlowState();
75
76         final JpPlanner planner = getPcd().makePlanner(planData);
77
78         final CflowField field = getCflowField(planData.inAspect);
79         return new WrappedJpPlanner(planner) {
80             public JpPlan makePlan(JoinPoint jp) {
81                 JpPlan plan = super.makePlan(jp);
82                 if (!plan.isPossible()) return plan;
83                 return new CFlowEntryPlan(plan, field); //CFlowPcd.this);
84
}
85         };
86     }
87     
88     //INTRO from ScopeWalker
89
public ASTObject postScope(ScopeWalker walker) {
90         if (walker.walkBodies()) {
91             findFlowState();
92             //getStackField();
93
}
94         return this;
95     }
96
97     List flowState = null;
98
99     void findFlowState() {
100         if (flowState != null) return;
101
102         flowState = new ArrayList();
103
104         new Walker(getCompiler()) {
105             public void postProcess(ASTObject node) {
106                 if (node instanceof VarTypeName) {
107                     VarTypeName varTypeName = (VarTypeName)node;
108                     if (varTypeName.getFormalDec() != null) {
109                         addFlowState(varTypeName);
110                     }
111                 }
112             }
113         }.process(getPcd());
114     }
115
116     void addFlowState(VarTypeName varTypeName) {
117         flowState.add(varTypeName);
118     }
119
120     Map cflowFields = new HashMap();
121     
122     public CflowField getCflowField(TypeDec inTypeDec) {
123         CflowField ret = (CflowField)cflowFields.get(inTypeDec);
124         if (ret == null) {
125             ret = new CflowField(inTypeDec);
126             cflowFields.put(inTypeDec, ret);
127         }
128         return ret;
129     }
130
131     private static int counter=0;
132     private static int ecounter = 0;
133
134     class CflowField implements CFlowPlanner {
135         private TypeDec declaringTypeDec = null;
136         private FieldDec stack;
137
138         public CflowField(TypeDec inTypeDec) {
139             this.declaringTypeDec = inTypeDec;
140         }
141
142         public boolean getIncludesRoot() {
143             return CFlowPcd.this.getIncludesRoot();
144         }
145
146         FieldDec getStackField() {
147             if (stack != null) return stack;
148             
149             final AST ast = getAST();
150             String JavaDoc name = "cflow$ajc" + counter++;
151             Type type = getTypeManager().getType("org.aspectj.runtime.internal", "CFlowStack");
152             
153             Modifiers modifiers =
154                 ast.makeModifiers(Modifiers.PUBLIC | Modifiers.STATIC | Modifiers.FINAL);
155             stack = ast.makeField(modifiers, type, name, ast.makeNew(type));
156             //stack.setSynthetic();
157

158             //System.out.println(typeDec +", " + typeDec.getBody());
159
declaringTypeDec.getBody().add(0, stack);
160             return stack;
161         }
162
163
164         Expr getStackVar() {
165             return getAST().makeGet(getStackField());
166         }
167
168         Expr testStackExpr() {
169             return getAST().makeCall(getStackVar(), "isValid");
170         }
171
172         Expr pushStackExpr(Expr expr) {
173             return getAST().makeCall(getStackVar(), "push", expr);
174         }
175         
176         Expr popStackExpr() {
177             return getAST().makeCall(getStackVar(), "pop");
178         }
179
180         Expr peekStackExpr() {
181             return getAST().makeCall(getStackVar(), "peekCFlow");
182         }
183
184         void remapExprs(JpPlan plan) {
185             int index = 0;
186             for (Iterator i = flowState.iterator(); i.hasNext(); ) {
187                 VarTypeName varTypeName = (VarTypeName)i.next();
188                 FormalDec formal = varTypeName.getFormalDec();
189                 
190                 Expr expr = makeFlowStateExpr(formal.getType(), index++);
191                 plan.bindExpr(varTypeName.getFormalDec(), expr);
192             }
193         }
194
195         // this is called by the CFlowAdviceDec for the "entry points"
196
public Stmts wrapPushPop(JpPlan plan, Stmts body) {
197             final AST ast = getAST();
198         
199             Expr newCFlowExpr = makeNewCFlowExpr(plan);
200
201             Expr test = plan.getDynamicTest();
202             if (test == null) {
203                 return ast.makeStmts(
204                                      ast.makeStmt(pushStackExpr(newCFlowExpr)),
205                                      ast.makeTryFinally(ast.makeBlock(body),
206                                                         ast.makeBlock(popStackExpr())));
207             } else {
208                 VarDec tmp = ast.makeFinalVar(getTypeManager().booleanType,
209                                               "ajc_enter_cflow_" + ecounter++, test);
210                 return ast.makeStmts(
211                                      tmp,
212                                      ast.makeIf(ast.makeVar(tmp),
213                                                 ast.makeStmt(pushStackExpr(newCFlowExpr))),
214                                      ast.makeTryFinally(ast.makeBlock(body),
215                                                         ast.makeBlock(ast.makeIf(ast.makeVar(tmp),
216                                                                                  ast.makeStmt(popStackExpr())))));
217             }
218         }
219
220         Exprs initializeFlowState(JpPlan plan) {
221             final AST ast = getAST();
222
223             int index = 0;
224             //List planExprs = plan.exprs;
225
Exprs stateExprs = ast.makeExprs();
226
227             for (Iterator i = flowState.iterator(); i.hasNext(); ) {
228                 VarTypeName varTypeName = (VarTypeName)i.next();
229                 FormalDec formal = varTypeName.getFormalDec();
230                 Expr expr = (Expr)plan.bindings.get(formal);
231                 if (expr == null) {
232                     varTypeName.showError("no binding for this variable in enclosing cflow");
233                 }
234
235                 //Expr expr = (Expr)planExprs.get(formal.getIndex());
236
expr = expr.getType().makeObject(expr);
237                 stateExprs.add(expr);
238             }
239
240             Exprs ret = ast.makeExprs();
241             if (stateExprs.size() != 0) {
242                 ret.add(ast.makeObjectArray(stateExprs));
243             } else {
244                 return null;
245             }
246             return ret;
247         }
248
249         Expr makeFlowStateExpr(Type desiredType, int index) {
250             Expr objectExpr =
251                 getAST().makeCall(peekStackExpr(), "get", getAST().makeLiteral(index));
252             return desiredType.fromObject(objectExpr);
253         }
254
255         public Expr makeNewCFlow(Exprs baseExprs) {
256             Type cflowType;
257             if (baseExprs == null) {
258                 baseExprs = getAST().makeExprs();
259                 cflowType = getTypeManager().getType("org.aspectj.runtime", "CFlow");
260             } else {
261                 cflowType = getTypeManager().getType("org.aspectj.runtime.internal", "CFlowPlusState");
262             }
263
264             return getAST().makeNew(cflowType, baseExprs);
265         }
266
267         public Expr makeNewCFlowExpr(JpPlan plan) {
268             return makeNewCFlow(initializeFlowState(plan));
269         }
270
271
272
273     }
274
275
276
277     
278     //-----------------------------------------------------------------------------------
279

280     //BEGIN: Generated from @child and @property
281
protected Pcd pcd;
282     public Pcd getPcd() { return pcd; }
283     public void setPcd(Pcd _pcd) {
284         if (_pcd != null) _pcd.setParent(this);
285         pcd = _pcd;
286     }
287     
288     protected boolean includesRoot;
289     public boolean getIncludesRoot() { return includesRoot; }
290     public void setIncludesRoot(boolean _includesRoot) { includesRoot = _includesRoot; }
291     
292     public CFlowPcd(SourceLocation location, Pcd _pcd, boolean _includesRoot) {
293         super(location);
294         setPcd(_pcd);
295         setIncludesRoot(_includesRoot);
296     }
297     protected CFlowPcd(SourceLocation source) {
298         super(source);
299     }
300     
301     public ASTObject copyWalk(CopyWalker walker) {
302         CFlowPcd ret = new CFlowPcd(getSourceLocation());
303         ret.preCopy(walker, this);
304         if (pcd != null) ret.setPcd( (Pcd)walker.process(pcd) );
305         ret.includesRoot = includesRoot;
306         return ret;
307     }
308     
309     public ASTObject getChildAt(int childIndex) {
310         switch(childIndex) {
311         case 0: return pcd;
312         default: return super.getChildAt(childIndex);
313         }
314     }
315      public String JavaDoc getChildNameAt(int childIndex) {
316         switch(childIndex) {
317         case 0: return "pcd";
318         default: return super.getChildNameAt(childIndex);
319         }
320     }
321      public void setChildAt(int childIndex, ASTObject child) {
322         switch(childIndex) {
323         case 0: setPcd((Pcd)child); return;
324         default: super.setChildAt(childIndex, child); return;
325         }
326     }
327      public int getChildCount() {
328         return 1;
329     }
330     
331     public String JavaDoc getDefaultDisplayName() {
332         return "CFlowPcd(includesRoot: "+includesRoot+")";
333     }
334     
335     //END: Generated from @child and @property
336
}
337
338
Popular Tags