]> source.dussan.org Git - aspectj.git/blob
edc686c1fc0531c91fce6dde2be807916fba5790
[aspectj.git] /
1 /* *******************************************************************
2  * Copyright (c) 2004 IBM Corporation.
3  * All rights reserved.
4  * This program and the accompanying materials are made available
5  * under the terms of the Eclipse Public License v 2.0
6  * which accompanies this distribution and is available at
7  * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
8  *
9  * ******************************************************************/
10 package org.aspectj.weaver.internal.tools;
11
12 import java.lang.reflect.Constructor;
13 import java.lang.reflect.Member;
14
15 import org.aspectj.weaver.ResolvedMember;
16 import org.aspectj.weaver.ResolvedType;
17 import org.aspectj.weaver.Shadow;
18 import org.aspectj.weaver.World;
19 import org.aspectj.weaver.ast.Literal;
20 import org.aspectj.weaver.ast.Test;
21 import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
22 import org.aspectj.weaver.patterns.AnnotationPointcut;
23 import org.aspectj.weaver.patterns.ArgsAnnotationPointcut;
24 import org.aspectj.weaver.patterns.ArgsPointcut;
25 import org.aspectj.weaver.patterns.CflowPointcut;
26 import org.aspectj.weaver.patterns.ExposedState;
27 import org.aspectj.weaver.patterns.IfPointcut;
28 import org.aspectj.weaver.patterns.NotAnnotationTypePattern;
29 import org.aspectj.weaver.patterns.NotPointcut;
30 import org.aspectj.weaver.patterns.Pointcut;
31 import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut;
32 import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
33 import org.aspectj.weaver.patterns.WithinAnnotationPointcut;
34 import org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut;
35 import org.aspectj.weaver.reflect.ReflectionFastMatchInfo;
36 import org.aspectj.weaver.reflect.StandardShadow;
37 import org.aspectj.weaver.reflect.StandardShadowMatchImpl;
38 import org.aspectj.weaver.tools.DefaultMatchingContext;
39 import org.aspectj.weaver.tools.MatchingContext;
40 import org.aspectj.weaver.tools.PointcutParameter;
41 import org.aspectj.weaver.tools.ShadowMatch;
42 import org.aspectj.weaver.tools.StandardPointcutExpression;
43
44 /**
45  * Map from weaver.tools interface to internal Pointcut implementation...
46  */
47 public class StandardPointcutExpressionImpl implements StandardPointcutExpression {
48
49         private World world;
50         private Pointcut pointcut;
51         private String expression;
52         private PointcutParameter[] parameters;
53         private MatchingContext matchContext = new DefaultMatchingContext();
54
55         public StandardPointcutExpressionImpl(Pointcut pointcut, String expression, PointcutParameter[] params, World inWorld) {
56                 this.pointcut = pointcut;
57                 this.expression = expression;
58                 this.world = inWorld;
59                 this.parameters = params;
60                 if (this.parameters == null) {
61                         this.parameters = new PointcutParameter[0];
62                 }
63         }
64
65         public Pointcut getUnderlyingPointcut() {
66                 return this.pointcut;
67         }
68
69         /*
70          * (non-Javadoc)
71          *
72          * @see org.aspectj.weaver.tools.PointcutExpression#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
73          */
74         public void setMatchingContext(MatchingContext aMatchContext) {
75                 this.matchContext = aMatchContext;
76         }
77
78         public boolean couldMatchJoinPointsInType(Class aClass) {
79                 ResolvedType matchType = world.resolve(aClass.getName());
80                 ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world);
81                 return pointcut.fastMatch(info).maybeTrue();
82         }
83
84         public boolean mayNeedDynamicTest() {
85                 HasPossibleDynamicContentVisitor visitor = new HasPossibleDynamicContentVisitor();
86                 pointcut.traverse(visitor, null);
87                 return visitor.hasDynamicContent();
88         }
89
90         private ExposedState getExposedState() {
91                 return new ExposedState(parameters.length);
92         }
93
94         // public ShadowMatch matchesMethodExecution(Method aMethod) {
95         // return matchesExecution(aMethod);
96         // }
97
98         public ShadowMatch matchesMethodExecution(ResolvedMember aMethod) {
99                 return matchesExecution(aMethod);
100         }
101
102         public ShadowMatch matchesConstructorExecution(Constructor aConstructor) {
103                 return null;
104                 // return matchesExecution(aConstructor);
105         }
106
107         // private ShadowMatch matchesExecution(Member aMember) {
108         // Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember, this.matchContext);
109         // ShadowMatchImpl sm = getShadowMatch(s);
110         // sm.setSubject(aMember);
111         // sm.setWithinCode(null);
112         // sm.setWithinType(aMember.getDeclaringClass());
113         // return sm;
114         // }
115
116         private ShadowMatch matchesExecution(ResolvedMember aMember) {
117                 Shadow s = StandardShadow.makeExecutionShadow(world, aMember, this.matchContext);
118                 StandardShadowMatchImpl sm = getShadowMatch(s);
119                 sm.setSubject(aMember);
120                 sm.setWithinCode(null);
121                 sm.setWithinType((ResolvedType) aMember.getDeclaringType());
122                 return sm;
123         }
124
125         // public ShadowMatch matchesStaticInitialization(Class aClass) {
126         // Shadow s = ReflectionShadow.makeStaticInitializationShadow(world, aClass, this.matchContext);
127         // StandardShadowMatchImpl sm = getShadowMatch(s);
128         // sm.setSubject(null);
129         // sm.setWithinCode(null);
130         // sm.setWithinType(aClass);
131         // return sm;
132         // }
133
134         public ShadowMatch matchesStaticInitialization(ResolvedType aType) {
135                 Shadow s = StandardShadow.makeStaticInitializationShadow(world, aType, this.matchContext);
136                 StandardShadowMatchImpl sm = getShadowMatch(s);
137                 sm.setSubject(null);
138                 sm.setWithinCode(null);
139                 sm.setWithinType(aType);
140                 return sm;
141         }
142
143         // public ShadowMatch matchesAdviceExecution(Method aMethod) {
144         // Shadow s = ReflectionShadow.makeAdviceExecutionShadow(world, aMethod, this.matchContext);
145         // StandardShadowMatchImpl sm = getShadowMatch(s);
146         // sm.setSubject(aMethod);
147         // sm.setWithinCode(null);
148         // sm.setWithinType(aMethod.getDeclaringClass());
149         // return sm;
150         // }
151         //
152         // public ShadowMatch matchesInitialization(Constructor aConstructor) {
153         // Shadow s = ReflectionShadow.makeInitializationShadow(world, aConstructor, this.matchContext);
154         // StandardShadowMatchImpl sm = getShadowMatch(s);
155         // sm.setSubject(aConstructor);
156         // sm.setWithinCode(null);
157         // sm.setWithinType(aConstructor.getDeclaringClass());
158         // return sm;
159         // }
160         //
161         // public ShadowMatch matchesPreInitialization(Constructor aConstructor) {
162         // Shadow s = ReflectionShadow.makePreInitializationShadow(world, aConstructor, this.matchContext);
163         // StandardShadowMatchImpl sm = getShadowMatch(s);
164         // sm.setSubject(aConstructor);
165         // sm.setWithinCode(null);
166         // sm.setWithinType(aConstructor.getDeclaringClass());
167         // return sm;
168         // }
169         //
170         public ShadowMatch matchesMethodCall(ResolvedMember aMethod, ResolvedMember withinCode) {
171                 Shadow s = StandardShadow.makeCallShadow(world, aMethod, withinCode, this.matchContext);
172                 StandardShadowMatchImpl sm = getShadowMatch(s);
173                 sm.setSubject(aMethod);
174                 sm.setWithinCode(withinCode);
175                 sm.setWithinType((ResolvedType) withinCode.getDeclaringType());
176                 return sm;
177         }
178
179         //
180         // public ShadowMatch matchesMethodCall(Method aMethod, Class callerType) {
181         // Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, callerType, this.matchContext);
182         // ShadowMatchImpl sm = getShadowMatch(s);
183         // sm.setSubject(aMethod);
184         // sm.setWithinCode(null);
185         // sm.setWithinType(callerType);
186         // return sm;
187         // }
188         //
189         // public ShadowMatch matchesConstructorCall(Constructor aConstructor, Class callerType) {
190         // Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, callerType, this.matchContext);
191         // ShadowMatchImpl sm = getShadowMatch(s);
192         // sm.setSubject(aConstructor);
193         // sm.setWithinCode(null);
194         // sm.setWithinType(callerType);
195         // return sm;
196         // }
197         //
198         // public ShadowMatch matchesConstructorCall(Constructor aConstructor, Member withinCode) {
199         // Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, withinCode, this.matchContext);
200         // ShadowMatchImpl sm = getShadowMatch(s);
201         // sm.setSubject(aConstructor);
202         // sm.setWithinCode(withinCode);
203         // sm.setWithinType(withinCode.getDeclaringClass());
204         // return sm;
205         // }
206         //
207         // public ShadowMatch matchesHandler(Class exceptionType, Class handlingType) {
208         // Shadow s = ReflectionShadow.makeHandlerShadow(world, exceptionType, handlingType, this.matchContext);
209         // ShadowMatchImpl sm = getShadowMatch(s);
210         // sm.setSubject(null);
211         // sm.setWithinCode(null);
212         // sm.setWithinType(handlingType);
213         // return sm;
214         // }
215         //
216         // public ShadowMatch matchesHandler(Class exceptionType, Member withinCode) {
217         // Shadow s = ReflectionShadow.makeHandlerShadow(world, exceptionType, withinCode, this.matchContext);
218         // ShadowMatchImpl sm = getShadowMatch(s);
219         // sm.setSubject(null);
220         // sm.setWithinCode(withinCode);
221         // sm.setWithinType(withinCode.getDeclaringClass());
222         // return sm;
223         // }
224         //
225         // public ShadowMatch matchesFieldGet(Field aField, Class withinType) {
226         // Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinType, this.matchContext);
227         // ShadowMatchImpl sm = getShadowMatch(s);
228         // sm.setSubject(aField);
229         // sm.setWithinCode(null);
230         // sm.setWithinType(withinType);
231         // return sm;
232         // }
233         //
234         // public ShadowMatch matchesFieldGet(Field aField, Member withinCode) {
235         // Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinCode, this.matchContext);
236         // ShadowMatchImpl sm = getShadowMatch(s);
237         // sm.setSubject(aField);
238         // sm.setWithinCode(withinCode);
239         // sm.setWithinType(withinCode.getDeclaringClass());
240         // return sm;
241         // }
242         //
243         // public ShadowMatch matchesFieldSet(Field aField, Class withinType) {
244         // Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinType, this.matchContext);
245         // ShadowMatchImpl sm = getShadowMatch(s);
246         // sm.setSubject(aField);
247         // sm.setWithinCode(null);
248         // sm.setWithinType(withinType);
249         // return sm;
250         // }
251         //
252         // public ShadowMatch matchesFieldSet(Field aField, Member withinCode) {
253         // Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinCode, this.matchContext);
254         // StandardShadowMatchImpl sm = getShadowMatch(s);
255         // sm.setSubject(aField);
256         // sm.setWithinCode(withinCode);
257         // sm.setWithinType(withinCode.getDeclaringClass());
258         // return sm;
259         // }
260
261         private StandardShadowMatchImpl getShadowMatch(Shadow forShadow) {
262                 org.aspectj.util.FuzzyBoolean match = pointcut.match(forShadow);
263                 Test residueTest = Literal.TRUE;
264                 ExposedState state = getExposedState();
265                 if (match.maybeTrue()) {
266                         residueTest = pointcut.findResidue(forShadow, state);
267                 }
268                 StandardShadowMatchImpl sm = new StandardShadowMatchImpl(match, residueTest, state, parameters);
269                 sm.setMatchingContext(this.matchContext);
270                 return sm;
271         }
272
273         /*
274          * (non-Javadoc)
275          *
276          * @see org.aspectj.weaver.tools.PointcutExpression#getPointcutExpression()
277          */
278         public String getPointcutExpression() {
279                 return expression;
280         }
281
282         private static class HasPossibleDynamicContentVisitor extends AbstractPatternNodeVisitor {
283                 private boolean hasDynamicContent = false;
284
285                 public boolean hasDynamicContent() {
286                         return hasDynamicContent;
287                 }
288
289                 @Override
290                 public Object visit(WithinAnnotationPointcut node, Object data) {
291                         hasDynamicContent = true;
292                         return null;
293                 }
294
295                 @Override
296                 public Object visit(WithinCodeAnnotationPointcut node, Object data) {
297                         hasDynamicContent = true;
298                         return null;
299                 }
300
301                 @Override
302                 public Object visit(AnnotationPointcut node, Object data) {
303                         hasDynamicContent = true;
304                         return null;
305                 }
306
307                 @Override
308                 public Object visit(ArgsAnnotationPointcut node, Object data) {
309                         hasDynamicContent = true;
310                         return null;
311                 }
312
313                 @Override
314                 public Object visit(ArgsPointcut node, Object data) {
315                         hasDynamicContent = true;
316                         return null;
317                 }
318
319                 @Override
320                 public Object visit(CflowPointcut node, Object data) {
321                         hasDynamicContent = true;
322                         return null;
323                 }
324
325                 @Override
326                 public Object visit(IfPointcut node, Object data) {
327                         hasDynamicContent = true;
328                         return null;
329                 }
330
331                 @Override
332                 public Object visit(NotAnnotationTypePattern node, Object data) {
333                         return node.getNegatedPattern().accept(this, data);
334                 }
335
336                 @Override
337                 public Object visit(NotPointcut node, Object data) {
338                         return node.getNegatedPointcut().accept(this, data);
339                 }
340
341                 @Override
342                 public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
343                         hasDynamicContent = true;
344                         return null;
345                 }
346
347                 @Override
348                 public Object visit(ThisOrTargetPointcut node, Object data) {
349                         hasDynamicContent = true;
350                         return null;
351                 }
352
353         }
354
355         public static class Handler implements Member {
356
357                 private Class decClass;
358                 private Class exType;
359
360                 public Handler(Class decClass, Class exType) {
361                         this.decClass = decClass;
362                         this.exType = exType;
363                 }
364
365                 public int getModifiers() {
366                         return 0;
367                 }
368
369                 public Class getDeclaringClass() {
370                         return decClass;
371                 }
372
373                 public String getName() {
374                         return null;
375                 }
376
377                 public Class getHandledExceptionType() {
378                         return exType;
379                 }
380
381                 public boolean isSynthetic() {
382                         return false;
383                 }
384         }
385 }