KickJava   Java API By Example, From Geeks To Geeks.

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


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 package org.aspectj.compiler.crosscuts.ast;
25
26 import org.aspectj.compiler.base.ast.*;
27 import org.aspectj.compiler.base.*;
28 import org.aspectj.compiler.crosscuts.joinpoints.*;
29
30 import java.util.*;
31 import org.aspectj.util.*;
32
33 /**
34  * @grammar per[this|target](pointcut)
35  * @child Pcd pcd
36  * @property boolean onThis
37  */

38
39 public class PerThisOrTarget extends PerClause {
40     public String JavaDoc toShortString() {
41         return "per" + (onThis ? "this" : "target") +
42                 "(" + getPcd().toShortString() + ")";
43     }
44     
45     private Set onTypes = new HashSet();
46     
47     public JpPlanner makeInnerPlanner(PlanData planData) {
48         return new JpPlanner() {
49             public FuzzyBoolean fastMatch(JoinPoint jp) {
50                 //??? might want to include a better filter test here as an optimization
51
return FuzzyBoolean.MAYBE;
52             }
53             public JpPlan makePlan(JoinPoint jp) {
54                 Expr onExpr = makeOnExpr(jp);
55                 if (onExpr == null) return JpPlan.NO_PLAN;
56                 
57                 JpPlan plan = new JpPlan(jp);
58                 plan.test = getHasAspectExpr(makeOnExpr(jp));
59                 plan.setInstanceExpr(getAspectOfExpr(makeOnExpr(jp)));
60                 return plan;
61             }
62         };
63     }
64     
65     public JpPlanner makeInitializerPlanner(PlanData planData) {
66         return new WrappedJpPlanner(getPcd().makePlanner(planData)) {
67                 public JpPlan makePlan(JoinPoint jp) {
68                     Expr onExpr = makeOnExpr(jp);
69                     if (onExpr == null) return JpPlan.NO_PLAN;
70                     // don't plan on me or my supers
71
if (getAspectType().isSubtypeOf(onExpr.getType())) {
72                         getPcd().showWarning("will not match containing aspect (compiler limitation)");
73                         return JpPlan.NO_PLAN;
74                     }
75                     
76                     JpPlan plan = super.makePlan(jp);
77                     
78                     if (plan.isPossible()) {
79                         addHasAspectType(onExpr.getType(), jp);
80                     }
81                     return new InitializerPlan(plan);
82                 }
83             };
84     }
85     
86     private class InitializerPlan extends JpPlan {
87         JpPlan innerPlan;
88         
89         public InitializerPlan(JpPlan innerPlan) {
90             super(innerPlan.joinPoint);
91             this.innerPlan = innerPlan;
92         }
93         
94         public int getPreSortOrder() { return EACHOBJECT; }
95         
96         public String JavaDoc toString() {
97             return "perobject" + super.toString();
98         }
99         
100         public void wrapJoinPoint(JoinPoint jp) {
101             jp.setStmts(this.wrapCheckAndSet(jp, jp.getStmts()));
102         }
103         
104         public Stmts wrapCheckAndSet(JoinPoint jp, Stmts stmts) {
105             return PerThisOrTarget.this.wrapCheckAndSet(innerPlan, jp, stmts);
106         }
107     }
108     
109     void addHasAspectType(Type toType, JoinPoint jp) {
110         if (onTypes.contains(toType)) return;
111         if (toType == getHasAspectInterfaceType()) return;
112         onTypes.add(toType);
113         if (!toType.getTypeDec().fromSource()) {
114             //??? should there be a compiler error or warning here
115
return;
116         }
117         toType.getTypeDec().addSuperInterfaceType(getHasAspectInterfaceType());
118         toType.addDirectSuperType(getHasAspectInterfaceType());
119     }
120     
121
122         /*
123     public void plan(TypeDec typeDec, int phase) {
124         //??? is this too early
125         if (phase != TypeDecPlanner.SIGNATURE) return;
126         
127         JoinPoint jp = ???;
128         
129         if (getPcd().matches(jp)) {
130             
131         }
132         
133         if (!getTargets().matches(typeDec.getType())) return;
134
135         final int N = typeDs.size();
136         for (int i = 0; i < N; i++) {
137             TypeD name = typeDs.get(i);
138             getCompiler().showMessage(" introducing " + name.toShortString() +
139                     " on " + typeDec.toShortString());
140
141             addSuperType(typeDec.getType(), name.getType());
142         }
143         ((AspectJCompiler)getCompiler()).getCorrespondences().addPointsTo(this, typeDec);
144     }
145     private Set plannedTypes = new HashSet();
146     
147     void planType(Type type) {
148         if (plannedTypes.contains(type)) return;
149         plannedTypes.add(type);
150         if (type.isInterface()) return;
151         
152         //???
153         if (type.has
154     }
155     */

156     
157
158     public Expr makeOnExpr(JoinPoint point) {
159         if (onThis) return point.makeThisExpr();
160         else return point.makeTargetExpr();
161     }
162     
163     /**
164      * <code>
165      * public static interface HasAspect {
166      * private transient AspectType _aspect;
167      * private synchronized void bind() {
168      * if (_aspect != null) return;
169      * _aspect = new AspectType();
170      * }
171      *
172      * private AspectType getAspect() {
173      * return _aspect;
174      * }
175      * }
176      * </code>
177      */

178     private InterfaceDec hasAspectInterface;
179     private MethodDec hasAspectBindMethod;
180     private MethodDec hasAspectGetMethod;
181     
182     public Type getHasAspectInterfaceType() {
183         return getHasAspectInterface().getType();
184     }
185     
186     public InterfaceDec getHasAspectInterface() {
187         if (hasAspectInterface != null) return hasAspectInterface;
188         hasAspectInterface = makeHasAspectInterface();
189         return hasAspectInterface;
190     }
191     
192     String JavaDoc makeName(String JavaDoc base) {
193         return getAST().makeGeneratedName(getAspectType().getString() + "_" + base);
194     }
195     
196     int getFieldModifiers() {
197         if (getOptions().XserializableAspects) {
198             if (getAspectType().isSubtypeOf(getTypeManager().getSerializableType())) {
199                 return Modifiers.PRIVATE;
200             }
201         }
202         return Modifiers.PRIVATE | Modifiers.TRANSIENT;
203     }
204
205     InterfaceDec makeHasAspectInterface() {
206         final AST ast = getAST();
207         
208         hasAspectInterface = ast.makeInterface(
209             ast.makeModifiers(Modifiers.PUBLIC), "AJC_HasAspect", ast.makeTypeDs());
210         hasAspectInterface.setEnclosingTypeDec(getAspectDec());
211         getAspectDec().addToBody(hasAspectInterface);
212         
213         //System.out.println("package: " + hasAspectInterface.getPackageName());
214

215         FieldDec aspectField = ast.makeField(
216             ast.makeModifiers(getFieldModifiers()), getAspectType(), makeName("_aspect"));
217         hasAspectInterface.getBody().add(aspectField);
218         
219         hasAspectBindMethod = ast.makeMethod(
220             ast.makeModifiers(Modifiers.PRIVATE|Modifiers.SYNCHRONIZED),
221             getTypeManager().voidType, makeName("bind"),
222             ast.makeFormals(),
223             ast.makeBlock(
224                 ast.makeIf(
225                         ast.makeNonNullTest(ast.makeGet(aspectField.getField())),
226                         ast.makeReturn()),
227                 ast.makeSet(aspectField.getField(), ast.makeNew(getAspectType()))));
228         hasAspectInterface.getBody().add(hasAspectBindMethod);
229                 
230         hasAspectGetMethod = ast.makeMethod(
231             ast.makeModifiers(Modifiers.PRIVATE), getAspectType(), makeName("getAspect"),
232             ast.makeFormals(),
233             ast.makeBlock(
234                 ast.makeReturn(ast.makeGet(aspectField.getField()))));
235         hasAspectInterface.getBody().add(hasAspectGetMethod);
236         
237         return hasAspectInterface;
238     }
239
240     /** <code>
241      * public static void bind$ajc(Object obj) {
242      * if (!(obj instanceof HasAspect)) return; //XXX this seems deadly
243      * ((HasAspect)obj).bind();
244      * }
245      *
246      * public static boolean hasAspect(Object obj) {
247      * if (!(obj instanceof HasAspect)) return false;
248      * return ((HasAspect)obj).getAspect() != null;
249      * }
250      *
251      * public static AspectType aspectOf(Object obj) {
252      * AspectType _aspect = null;
253      * if (obj instanceof HasAspect) {
254      * _aspect = ((HasAspect)obj).getAspect();
255      * }
256      * if (_aspect == null) {
257      * throw new org.aspectj.lang.NoAspectBoundException();
258      * }
259      * return _aspect;
260      * }
261      *
262      * </code>
263      */

264     private MethodDec bindMethod;
265     MethodDec getBindMethod() {
266         if (bindMethod != null) return bindMethod;
267
268         final AST ast = getAST();
269         
270         FormalDec objFormal = ast.makeFormal(getTypeManager().getObjectType(), "obj");
271         bindMethod = ast.makeMethod(
272             ast.makeModifiers(Modifiers.STATIC|Modifiers.PUBLIC|Modifiers.SYNCHRONIZED),
273             getTypeManager().voidType, "bind$ajc", ast.makeFormals(objFormal),
274             ast.makeBlock(
275               ast.makeIf(
276                 ast.makeNotInstanceofTest(ast.makeVar(objFormal),
277                                           getHasAspectInterfaceType()),
278                 ast.makeReturn()),
279               ast.makeCall(hasAspectBindMethod,
280                 ast.makeCast(getHasAspectInterfaceType(), ast.makeVar(objFormal)))));
281         getAspectDec().addToBody(bindMethod);
282         return bindMethod;
283     }
284     
285     protected MethodDec makeHasAspectMethod() {
286         final AST ast = getAST();
287         FormalDec objFormal = ast.makeFormal(getTypeManager().getObjectType(), "obj");
288         
289         BlockStmt body = ast.makeBlock(
290             ast.makeIf(
291               ast.makeNotInstanceofTest(ast.makeVar(objFormal), getHasAspectInterfaceType()),
292               ast.makeReturn(ast.makeLiteral(false))),
293             ast.makeReturn(ast.makeNonNullTest(ast.makeCall(hasAspectGetMethod,
294                 ast.makeCast(getHasAspectInterfaceType(), ast.makeVar(objFormal))))));
295         return makeHasAspectMethod(ast.makeFormals(objFormal), body);
296     }
297
298     protected MethodDec makeAspectOfMethod() {
299         getHasAspectInterfaceType();
300         
301         final AST ast = getAST();
302         VarDec aspDec = ast.makeVarDec(getAspectType(), "asp", ast.makeNull());
303         FormalDec objFormal = ast.makeFormal(getTypeManager().getObjectType(), "obj");
304         
305         BlockStmt body = ast.makeBlock(
306             aspDec,
307             ast.makeIf(
308               ast.makeInstanceof(ast.makeVar(objFormal), getHasAspectInterfaceType()),
309               ast.makeBlock(
310                 ast.makeSet(aspDec, ast.makeCall(hasAspectGetMethod,
311                   ast.makeCast(getHasAspectInterfaceType(), ast.makeVar(objFormal)))))),
312             ast.makeIf(
313               ast.makeNullTest(ast.makeVar(aspDec)),
314               ast.makeBlock(
315                 ast.makeThrow(ast.makeNew(
316                     getTypeManager().getType("org.aspectj.lang", "NoAspectBoundException"))))),
317             ast.makeReturn(ast.makeVar(aspDec)));
318
319         return makeAspectOfMethod(ast.makeFormals(objFormal), body);
320     }
321     
322     Expr bindExpr(Expr onExpr) {
323         return getAST().makeStaticCall(getBindMethod(), onExpr);
324     }
325     
326     Expr getHasAspectExpr(Expr onExpr) {
327         final AST ast = getAST();
328         return ast.makeStaticCall(hasAspectMethod, onExpr);
329     }
330     
331     Expr getAspectOfExpr(Expr onExpr) {
332         final AST ast = getAST();
333         return ast.makeParen(ast.forceCast(
334                 getAspectType(), ast.makeStaticCall(aspectOfMethod, onExpr)));
335     }
336
337     /***********************************************************************************/
338
339     // this is called by the EachObjectPlan for the "entry points"
340
public Stmts wrapCheckAndSet(JpPlan plan, JoinPoint jp, Stmts body) {
341         final AST ast = getAST();
342         Expr onExpr = makeOnExpr(jp);
343         if (onExpr == null) return body;
344         
345         Stmt stmt = ast.makeStmt(bindExpr(onExpr));
346         stmt = plan.wrapDynamicTest(ast.makeBlock(stmt));
347         
348         body.add(0, stmt);
349         return body;
350     }
351     
352     //BEGIN: Generated from @child and @property
353
protected Pcd pcd;
354     public Pcd getPcd() { return pcd; }
355     public void setPcd(Pcd _pcd) {
356         if (_pcd != null) _pcd.setParent(this);
357         pcd = _pcd;
358     }
359     
360     protected boolean onThis;
361     public boolean getOnThis() { return onThis; }
362     public void setOnThis(boolean _onThis) { onThis = _onThis; }
363     
364     public PerThisOrTarget(SourceLocation location, Pcd _pcd, boolean _onThis) {
365         super(location);
366         setPcd(_pcd);
367         setOnThis(_onThis);
368     }
369     protected PerThisOrTarget(SourceLocation source) {
370         super(source);
371     }
372     
373     public ASTObject copyWalk(CopyWalker walker) {
374         PerThisOrTarget ret = new PerThisOrTarget(getSourceLocation());
375         ret.preCopy(walker, this);
376         if (pcd != null) ret.setPcd( (Pcd)walker.process(pcd) );
377         ret.onThis = onThis;
378         return ret;
379     }
380     
381     public ASTObject getChildAt(int childIndex) {
382         switch(childIndex) {
383         case 0: return pcd;
384         default: return super.getChildAt(childIndex);
385         }
386     }
387      public String JavaDoc getChildNameAt(int childIndex) {
388         switch(childIndex) {
389         case 0: return "pcd";
390         default: return super.getChildNameAt(childIndex);
391         }
392     }
393      public void setChildAt(int childIndex, ASTObject child) {
394         switch(childIndex) {
395         case 0: setPcd((Pcd)child); return;
396         default: super.setChildAt(childIndex, child); return;
397         }
398     }
399      public int getChildCount() {
400         return 1;
401     }
402     
403     public String JavaDoc getDefaultDisplayName() {
404         return "PerThisOrTarget(onThis: "+onThis+")";
405     }
406     
407     //END: Generated from @child and @property
408
}
409
410
Popular Tags