]> source.dussan.org Git - aspectj.git/commitdiff
split weaving/matching: pointcut matching tests
authoraclement <aclement>
Wed, 10 Dec 2008 05:00:55 +0000 (05:00 +0000)
committeraclement <aclement>
Wed, 10 Dec 2008 05:00:55 +0000 (05:00 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/StandardPointcutExpressionImpl.java [new file with mode: 0644]
org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java
org.aspectj.matcher/src/org/aspectj/weaver/reflect/StandardShadow.java [new file with mode: 0644]
org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutExpression.java [new file with mode: 0644]
org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutParser.java [new file with mode: 0644]
org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/CommonPointcutExpressionTests.java [new file with mode: 0644]
org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/ReflectionWorldPointcutExpressionTests.java [new file with mode: 0644]
org.aspectj.matcher/testsrc/org/aspectj/weaver/MatcherModuleTests.java

diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/StandardPointcutExpressionImpl.java b/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/StandardPointcutExpressionImpl.java
new file mode 100644 (file)
index 0000000..2459366
--- /dev/null
@@ -0,0 +1,374 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * ******************************************************************/
+package org.aspectj.weaver.internal.tools;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.ast.Literal;
+import org.aspectj.weaver.ast.Test;
+import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
+import org.aspectj.weaver.patterns.AnnotationPointcut;
+import org.aspectj.weaver.patterns.ArgsAnnotationPointcut;
+import org.aspectj.weaver.patterns.ArgsPointcut;
+import org.aspectj.weaver.patterns.CflowPointcut;
+import org.aspectj.weaver.patterns.ExposedState;
+import org.aspectj.weaver.patterns.IfPointcut;
+import org.aspectj.weaver.patterns.NotAnnotationTypePattern;
+import org.aspectj.weaver.patterns.NotPointcut;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut;
+import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
+import org.aspectj.weaver.patterns.WithinAnnotationPointcut;
+import org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut;
+import org.aspectj.weaver.reflect.ReflectionFastMatchInfo;
+import org.aspectj.weaver.reflect.ReflectionShadow;
+import org.aspectj.weaver.reflect.ShadowMatchImpl;
+import org.aspectj.weaver.reflect.StandardShadow;
+import org.aspectj.weaver.tools.DefaultMatchingContext;
+import org.aspectj.weaver.tools.MatchingContext;
+import org.aspectj.weaver.tools.PointcutParameter;
+import org.aspectj.weaver.tools.ShadowMatch;
+import org.aspectj.weaver.tools.StandardPointcutExpression;
+
+/**
+ * Map from weaver.tools interface to internal Pointcut implementation...
+ */
+public class StandardPointcutExpressionImpl implements StandardPointcutExpression {
+
+       private World world;
+       private Pointcut pointcut;
+       private String expression;
+       private PointcutParameter[] parameters;
+       private MatchingContext matchContext = new DefaultMatchingContext();
+
+       public StandardPointcutExpressionImpl(Pointcut pointcut, String expression, PointcutParameter[] params, World inWorld) {
+               this.pointcut = pointcut;
+               this.expression = expression;
+               this.world = inWorld;
+               this.parameters = params;
+               if (this.parameters == null)
+                       this.parameters = new PointcutParameter[0];
+       }
+
+       public Pointcut getUnderlyingPointcut() {
+               return this.pointcut;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.tools.PointcutExpression#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
+        */
+       public void setMatchingContext(MatchingContext aMatchContext) {
+               this.matchContext = aMatchContext;
+       }
+
+       public boolean couldMatchJoinPointsInType(Class aClass) {
+               ResolvedType matchType = world.resolve(aClass.getName());
+               ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext);
+               return pointcut.fastMatch(info).maybeTrue();
+       }
+
+       public boolean mayNeedDynamicTest() {
+               HasPossibleDynamicContentVisitor visitor = new HasPossibleDynamicContentVisitor();
+               pointcut.traverse(visitor, null);
+               return visitor.hasDynamicContent();
+       }
+
+       private ExposedState getExposedState() {
+               return new ExposedState(parameters.length);
+       }
+
+       public ShadowMatch matchesMethodExecution(Method aMethod) {
+               return matchesExecution(aMethod);
+       }
+
+       public ShadowMatch matchesMethodExecution(ResolvedMember aMethod) {
+               return matchesExecution(aMethod);
+       }
+
+       public ShadowMatch matchesConstructorExecution(Constructor aConstructor) {
+               return matchesExecution(aConstructor);
+       }
+
+       private ShadowMatch matchesExecution(Member aMember) {
+               Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aMember);
+               sm.setWithinCode(null);
+               sm.setWithinType(aMember.getDeclaringClass());
+               return sm;
+       }
+
+       private ShadowMatch matchesExecution(ResolvedMember aMember) {
+               Shadow s = StandardShadow.makeExecutionShadow(world, aMember, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               // sm.setSubject(aMember);
+               // sm.setWithinCode(null);
+               // sm.setWithinType(aMember.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesStaticInitialization(Class aClass) {
+               Shadow s = ReflectionShadow.makeStaticInitializationShadow(world, aClass, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(null);
+               sm.setWithinCode(null);
+               sm.setWithinType(aClass);
+               return sm;
+       }
+
+       public ShadowMatch matchesStaticInitialization(ResolvedType type) {
+               Shadow s = StandardShadow.makeStaticInitializationShadow(world, type, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(null);
+               sm.setWithinCode(null);
+               // sm.setWithinType(aClass);
+               return sm;
+       }
+
+       public ShadowMatch matchesAdviceExecution(Method aMethod) {
+               Shadow s = ReflectionShadow.makeAdviceExecutionShadow(world, aMethod, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aMethod);
+               sm.setWithinCode(null);
+               sm.setWithinType(aMethod.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesInitialization(Constructor aConstructor) {
+               Shadow s = ReflectionShadow.makeInitializationShadow(world, aConstructor, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aConstructor);
+               sm.setWithinCode(null);
+               sm.setWithinType(aConstructor.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesPreInitialization(Constructor aConstructor) {
+               Shadow s = ReflectionShadow.makePreInitializationShadow(world, aConstructor, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aConstructor);
+               sm.setWithinCode(null);
+               sm.setWithinType(aConstructor.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesMethodCall(Method aMethod, Member withinCode) {
+               Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, withinCode, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aMethod);
+               sm.setWithinCode(withinCode);
+               sm.setWithinType(withinCode.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesMethodCall(Method aMethod, Class callerType) {
+               Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, callerType, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aMethod);
+               sm.setWithinCode(null);
+               sm.setWithinType(callerType);
+               return sm;
+       }
+
+       public ShadowMatch matchesConstructorCall(Constructor aConstructor, Class callerType) {
+               Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, callerType, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aConstructor);
+               sm.setWithinCode(null);
+               sm.setWithinType(callerType);
+               return sm;
+       }
+
+       public ShadowMatch matchesConstructorCall(Constructor aConstructor, Member withinCode) {
+               Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, withinCode, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aConstructor);
+               sm.setWithinCode(withinCode);
+               sm.setWithinType(withinCode.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesHandler(Class exceptionType, Class handlingType) {
+               Shadow s = ReflectionShadow.makeHandlerShadow(world, exceptionType, handlingType, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(null);
+               sm.setWithinCode(null);
+               sm.setWithinType(handlingType);
+               return sm;
+       }
+
+       public ShadowMatch matchesHandler(Class exceptionType, Member withinCode) {
+               Shadow s = ReflectionShadow.makeHandlerShadow(world, exceptionType, withinCode, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(null);
+               sm.setWithinCode(withinCode);
+               sm.setWithinType(withinCode.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesFieldGet(Field aField, Class withinType) {
+               Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinType, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aField);
+               sm.setWithinCode(null);
+               sm.setWithinType(withinType);
+               return sm;
+       }
+
+       public ShadowMatch matchesFieldGet(Field aField, Member withinCode) {
+               Shadow s = ReflectionShadow.makeFieldGetShadow(world, aField, withinCode, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aField);
+               sm.setWithinCode(withinCode);
+               sm.setWithinType(withinCode.getDeclaringClass());
+               return sm;
+       }
+
+       public ShadowMatch matchesFieldSet(Field aField, Class withinType) {
+               Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinType, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aField);
+               sm.setWithinCode(null);
+               sm.setWithinType(withinType);
+               return sm;
+       }
+
+       public ShadowMatch matchesFieldSet(Field aField, Member withinCode) {
+               Shadow s = ReflectionShadow.makeFieldSetShadow(world, aField, withinCode, this.matchContext);
+               ShadowMatchImpl sm = getShadowMatch(s);
+               sm.setSubject(aField);
+               sm.setWithinCode(withinCode);
+               sm.setWithinType(withinCode.getDeclaringClass());
+               return sm;
+       }
+
+       private ShadowMatchImpl getShadowMatch(Shadow forShadow) {
+               org.aspectj.util.FuzzyBoolean match = pointcut.match(forShadow);
+               Test residueTest = Literal.TRUE;
+               ExposedState state = getExposedState();
+               if (match.maybeTrue()) {
+                       residueTest = pointcut.findResidue(forShadow, state);
+               }
+               ShadowMatchImpl sm = new ShadowMatchImpl(match, residueTest, state, parameters);
+               sm.setMatchingContext(this.matchContext);
+               return sm;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.tools.PointcutExpression#getPointcutExpression()
+        */
+       public String getPointcutExpression() {
+               return expression;
+       }
+
+       private static class HasPossibleDynamicContentVisitor extends AbstractPatternNodeVisitor {
+               private boolean hasDynamicContent = false;
+
+               public boolean hasDynamicContent() {
+                       return hasDynamicContent;
+               }
+
+               public Object visit(WithinAnnotationPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(WithinCodeAnnotationPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(AnnotationPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(ArgsAnnotationPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(ArgsPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(CflowPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(IfPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(NotAnnotationTypePattern node, Object data) {
+                       return node.getNegatedPattern().accept(this, data);
+               }
+
+               public Object visit(NotPointcut node, Object data) {
+                       return node.getNegatedPointcut().accept(this, data);
+               }
+
+               public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+               public Object visit(ThisOrTargetPointcut node, Object data) {
+                       hasDynamicContent = true;
+                       return null;
+               }
+
+       }
+
+       public static class Handler implements Member {
+
+               private Class decClass;
+               private Class exType;
+
+               public Handler(Class decClass, Class exType) {
+                       this.decClass = decClass;
+                       this.exType = exType;
+               }
+
+               public int getModifiers() {
+                       return 0;
+               }
+
+               public Class getDeclaringClass() {
+                       return decClass;
+               }
+
+               public String getName() {
+                       return null;
+               }
+
+               public Class getHandledExceptionType() {
+                       return exType;
+               }
+
+               public boolean isSynthetic() {
+                       return false;
+               }
+       }
+}
index 75929e7a100a7665e450099a7570eaaa1ad6456f..4c714b90cd55f23d0c6450670614ac049b2ff94a 100644 (file)
@@ -27,8 +27,8 @@ import org.aspectj.weaver.Member;
 import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
 import org.aspectj.weaver.internal.tools.PointcutDesignatorHandlerBasedPointcut;
-import org.aspectj.weaver.reflect.ReflectionWorld;
 import org.aspectj.weaver.tools.ContextBasedMatcher;
 import org.aspectj.weaver.tools.PointcutDesignatorHandler;
 
@@ -43,7 +43,7 @@ public class PatternParser {
 
        /** extension handlers used in weaver tools API only */
        private Set pointcutDesignatorHandlers = Collections.EMPTY_SET;
-       private ReflectionWorld world;
+       private World world;
 
        /**
         * Constructor for PatternParser.
@@ -55,7 +55,7 @@ public class PatternParser {
        }
 
        /** only used by weaver tools API */
-       public void setPointcutDesignatorHandlers(Set handlers, ReflectionWorld world) {
+       public void setPointcutDesignatorHandlers(Set handlers, World world) {
                this.pointcutDesignatorHandlers = handlers;
                this.world = world;
        }
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/reflect/StandardShadow.java b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/StandardShadow.java
new file mode 100644 (file)
index 0000000..8e741b6
--- /dev/null
@@ -0,0 +1,414 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *   Adrian Colyer                     Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.Member;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedMemberImpl;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.tools.MatchingContext;
+
+/**
+ * @author colyer
+ * 
+ */
+public class StandardShadow extends Shadow {
+
+       private final World world;
+       private final ResolvedType enclosingType;
+       private final ResolvedMember enclosingMember;
+       private final MatchingContext matchContext;
+       private Var thisVar = null;
+       private Var targetVar = null;
+       private Var[] argsVars = null;
+       private Var atThisVar = null;
+       private Var atTargetVar = null;
+       private Map atArgsVars = new HashMap();
+       private Map withinAnnotationVar = new HashMap();
+       private Map withinCodeAnnotationVar = new HashMap();
+       private Map annotationVar = new HashMap();
+       private AnnotationFinder annotationFinder;
+
+       public static Shadow makeExecutionShadow(World inWorld, java.lang.reflect.Member forMethod, MatchingContext withContext) {
+               Kind kind = (forMethod instanceof Method) ? Shadow.MethodExecution : Shadow.ConstructorExecution;
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forMethod, inWorld);
+               ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, signature, null, enclosingType, null, withContext);
+       }
+
+       public static Shadow makeExecutionShadow(World inWorld, ResolvedMember forMethod, MatchingContext withContext) {
+               Kind kind = forMethod.getName().equals("<init>") ? Shadow.ConstructorExecution : Shadow.MethodExecution;
+               // Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forMethod, inWorld);
+               // ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, forMethod, null, (ResolvedType) forMethod.getDeclaringType(), null, withContext);
+       }
+
+       public static Shadow makeAdviceExecutionShadow(World inWorld, java.lang.reflect.Method forMethod, MatchingContext withContext) {
+               Kind kind = Shadow.AdviceExecution;
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedAdviceMember(forMethod, inWorld);
+               ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, signature, null, enclosingType, null, withContext);
+       }
+
+       public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, java.lang.reflect.Member withinCode,
+                       MatchingContext withContext) {
+               Shadow enclosingShadow = makeExecutionShadow(inWorld, withinCode, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(aMember, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               Kind kind = aMember instanceof Method ? Shadow.MethodCall : Shadow.ConstructorCall;
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, Class thisClass,
+                       MatchingContext withContext) {
+               Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, thisClass, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(aMember, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(thisClass, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               Kind kind = aMember instanceof Method ? Shadow.MethodCall : Shadow.ConstructorCall;
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeStaticInitializationShadow(World inWorld, Class forType, MatchingContext withContext) {
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(forType, inWorld);
+               ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
+               Kind kind = Shadow.StaticInitialization;
+               return new StandardShadow(inWorld, kind, signature, null, enclosingType, null, withContext);
+       }
+
+       public static Shadow makeStaticInitializationShadow(World inWorld, ResolvedType forType, MatchingContext withContext) {
+               ResolvedMember[] members = forType.getDeclaredMethods();
+               int clinit = -1;
+               for (int i = 0; i < members.length && clinit == -1; i++) {
+                       System.out.println(members[i]);
+                       if (members[i].getName().equals("<clinit>")) {
+                               clinit = i;
+                       }
+               }
+               // Member signature = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(forType, inWorld);
+               Kind kind = Shadow.StaticInitialization;
+               if (clinit == -1) {
+                       Member clinitMember = new ResolvedMemberImpl(org.aspectj.weaver.Member.STATIC_INITIALIZATION, forType, Modifier.STATIC,
+                                       ResolvedType.VOID, "<clinit>", new UnresolvedType[0], new UnresolvedType[0]);
+                       return new StandardShadow(inWorld, kind, clinitMember, null, forType, null, withContext);
+               } else {
+                       return new StandardShadow(inWorld, kind, members[clinit], null, forType, null, withContext);
+               }
+       }
+
+       public static Shadow makePreInitializationShadow(World inWorld, Constructor forConstructor, MatchingContext withContext) {
+               Kind kind = Shadow.PreInitialization;
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld);
+               ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, signature, null, enclosingType, null, withContext);
+       }
+
+       public static Shadow makeInitializationShadow(World inWorld, Constructor forConstructor, MatchingContext withContext) {
+               Kind kind = Shadow.Initialization;
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld);
+               ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, signature, null, enclosingType, null, withContext);
+       }
+
+       public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, Class withinType, MatchingContext withContext) {
+               Kind kind = Shadow.ExceptionHandler;
+               Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, withinType, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinType, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(withinType, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, java.lang.reflect.Member withinCode,
+                       MatchingContext withContext) {
+               Kind kind = Shadow.ExceptionHandler;
+               Shadow enclosingShadow = makeExecutionShadow(inWorld, withinCode, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinCode
+                               .getDeclaringClass(), inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeFieldGetShadow(World inWorld, Field forField, Class callerType, MatchingContext withContext) {
+               Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               Kind kind = Shadow.FieldGet;
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeFieldGetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember,
+                       MatchingContext withContext) {
+               Shadow enclosingShadow = makeExecutionShadow(inWorld, inMember, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               Kind kind = Shadow.FieldGet;
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeFieldSetShadow(World inWorld, Field forField, Class callerType, MatchingContext withContext) {
+               Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               Kind kind = Shadow.FieldSet;
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public static Shadow makeFieldSetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember,
+                       MatchingContext withContext) {
+               Shadow enclosingShadow = makeExecutionShadow(inWorld, inMember, withContext);
+               Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld);
+               ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld);
+               ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld);
+               Kind kind = Shadow.FieldSet;
+               return new StandardShadow(inWorld, kind, signature, enclosingShadow, enclosingType, enclosingMember, withContext);
+       }
+
+       public StandardShadow(World world, Kind kind, Member signature, Shadow enclosingShadow, ResolvedType enclosingType,
+                       ResolvedMember enclosingMember, MatchingContext withContext) {
+               super(kind, signature, enclosingShadow);
+               this.world = world;
+               this.enclosingType = enclosingType;
+               this.enclosingMember = enclosingMember;
+               this.matchContext = withContext;
+               if (world instanceof IReflectionWorld) {
+                       this.annotationFinder = ((IReflectionWorld) world).getAnnotationFinder();
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getIWorld()
+        */
+       public World getIWorld() {
+               return world;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getThisVar()
+        */
+       public Var getThisVar() {
+               if (thisVar == null && hasThis()) {
+                       thisVar = ReflectionVar.createThisVar(getThisType().resolve(world), this.annotationFinder);
+               }
+               return thisVar;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getTargetVar()
+        */
+       public Var getTargetVar() {
+               if (targetVar == null && hasTarget()) {
+                       targetVar = ReflectionVar.createTargetVar(getThisType().resolve(world), this.annotationFinder);
+               }
+               return targetVar;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getEnclosingType()
+        */
+       public UnresolvedType getEnclosingType() {
+               return this.enclosingType;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getArgVar(int)
+        */
+       public Var getArgVar(int i) {
+               if (argsVars == null) {
+                       this.argsVars = new Var[this.getArgCount()];
+                       for (int j = 0; j < this.argsVars.length; j++) {
+                               this.argsVars[j] = ReflectionVar.createArgsVar(getArgType(j).resolve(world), j, this.annotationFinder);
+                       }
+               }
+               if (i < argsVars.length) {
+                       return argsVars[i];
+               } else {
+                       return null;
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getThisJoinPointVar()
+        */
+       public Var getThisJoinPointVar() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getThisJoinPointStaticPartVar()
+        */
+       public Var getThisJoinPointStaticPartVar() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getThisEnclosingJoinPointStaticPartVar()
+        */
+       public Var getThisEnclosingJoinPointStaticPartVar() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getKindedAnnotationVar(org.aspectj.weaver.UnresolvedType)
+        */
+       public Var getKindedAnnotationVar(UnresolvedType forAnnotationType) {
+               ResolvedType annType = forAnnotationType.resolve(world);
+               if (annotationVar.get(annType) == null) {
+                       Var v = ReflectionVar.createAtAnnotationVar(annType, this.annotationFinder);
+                       annotationVar.put(annType, v);
+               }
+               return (Var) annotationVar.get(annType);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getWithinAnnotationVar(org.aspectj.weaver.UnresolvedType)
+        */
+       public Var getWithinAnnotationVar(UnresolvedType forAnnotationType) {
+               ResolvedType annType = forAnnotationType.resolve(world);
+               if (withinAnnotationVar.get(annType) == null) {
+                       Var v = ReflectionVar.createWithinAnnotationVar(annType, this.annotationFinder);
+                       withinAnnotationVar.put(annType, v);
+               }
+               return (Var) withinAnnotationVar.get(annType);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getWithinCodeAnnotationVar(org.aspectj.weaver.UnresolvedType)
+        */
+       public Var getWithinCodeAnnotationVar(UnresolvedType forAnnotationType) {
+               ResolvedType annType = forAnnotationType.resolve(world);
+               if (withinCodeAnnotationVar.get(annType) == null) {
+                       Var v = ReflectionVar.createWithinCodeAnnotationVar(annType, this.annotationFinder);
+                       withinCodeAnnotationVar.put(annType, v);
+               }
+               return (Var) withinCodeAnnotationVar.get(annType);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getThisAnnotationVar(org.aspectj.weaver.UnresolvedType)
+        */
+       public Var getThisAnnotationVar(UnresolvedType forAnnotationType) {
+               if (atThisVar == null) {
+                       atThisVar = ReflectionVar.createThisAnnotationVar(forAnnotationType.resolve(world), this.annotationFinder);
+               }
+               return atThisVar;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getTargetAnnotationVar(org.aspectj.weaver.UnresolvedType)
+        */
+       public Var getTargetAnnotationVar(UnresolvedType forAnnotationType) {
+               if (atTargetVar == null) {
+                       atTargetVar = ReflectionVar.createTargetAnnotationVar(forAnnotationType.resolve(world), this.annotationFinder);
+               }
+               return atTargetVar;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getArgAnnotationVar(int, org.aspectj.weaver.UnresolvedType)
+        */
+       public Var getArgAnnotationVar(int i, UnresolvedType forAnnotationType) {
+               ResolvedType annType = forAnnotationType.resolve(world);
+               if (atArgsVars.get(annType) == null) {
+                       Var[] vars = new Var[getArgCount()];
+                       atArgsVars.put(annType, vars);
+               }
+               Var[] vars = (Var[]) atArgsVars.get(annType);
+               if (i > (vars.length - 1))
+                       return null;
+               if (vars[i] == null) {
+                       vars[i] = ReflectionVar.createArgsAnnotationVar(annType, i, this.annotationFinder);
+               }
+               return vars[i];
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getEnclosingCodeSignature()
+        */
+       public Member getEnclosingCodeSignature() {
+               // XXX this code is copied from BcelShadow with one minor change...
+               if (getKind().isEnclosingKind()) {
+                       return getSignature();
+               } else if (getKind() == Shadow.PreInitialization) {
+                       // PreInit doesn't enclose code but its signature
+                       // is correctly the signature of the ctor.
+                       return getSignature();
+               } else if (enclosingShadow == null) {
+                       return this.enclosingMember;
+               } else {
+                       return enclosingShadow.getSignature();
+               }
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.aspectj.weaver.Shadow#getSourceLocation()
+        */
+       public ISourceLocation getSourceLocation() {
+               return null;
+       }
+
+       public MatchingContext getMatchingContext() {
+               return this.matchContext;
+       }
+}
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutExpression.java b/org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutExpression.java
new file mode 100644 (file)
index 0000000..3d55349
--- /dev/null
@@ -0,0 +1,233 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation.
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * ******************************************************************/
+
+package org.aspectj.weaver.tools;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedType;
+
+/**
+ * Represents an AspectJ pointcut expression and provides convenience methods to determine whether or not the pointcut matches join
+ * points specified in terms of the java.lang.reflect interfaces.
+ */
+public interface StandardPointcutExpression {
+
+       /**
+        * Set the matching context to be used for subsequent calls to match.
+        * 
+        * @see MatchingContext
+        */
+       void setMatchingContext(MatchingContext aMatchContext);
+
+       /**
+        * Determine whether or not this pointcut could ever match a join point in the given class.
+        * 
+        * @param aClass the candidate class
+        * @return true iff this pointcut <i>may</i> match a join point within(aClass), and false otherwise
+        */
+       boolean couldMatchJoinPointsInType(Class aClass);
+
+       /**
+        * Returns true iff this pointcut contains any expression that might necessitate a dynamic test at some join point (e.g. args)
+        */
+       boolean mayNeedDynamicTest();
+
+       /**
+        * Determine whether or not this pointcut matches the execution of a given method.
+        * 
+        * @param aMethod the method being executed
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing the
+        *         execution of the method.
+        */
+       ShadowMatch matchesMethodExecution(Method aMethod);
+
+       /**
+        * Determine whether or not this pointcut matches the execution of a given method.
+        * 
+        * @param aMethod the method being executed
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing the
+        *         execution of the method.
+        */
+       ShadowMatch matchesMethodExecution(ResolvedMember aMethod);
+
+       /**
+        * Determine whether or not this pointcut matches the execution of a given constructor.
+        * 
+        * @param aConstructor the constructor being executed
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing the
+        *         execution of the constructor.
+        */
+       ShadowMatch matchesConstructorExecution(Constructor aConstructor);
+
+       /**
+        * Determine whether or not this pointcut matches the static initialization of the given class.
+        * 
+        * @param aClass the class being statically initialized
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matchs join points representing the static
+        *         initialization of the given type
+        */
+       ShadowMatch matchesStaticInitialization(Class aClass);
+
+       /**
+        * Determine whether or not this pointcut matches the static initialization of the given class.
+        * 
+        * @param aClass the class being statically initialized
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matchs join points representing the static
+        *         initialization of the given type
+        */
+       ShadowMatch matchesStaticInitialization(ResolvedType type);
+
+       /**
+        * Determine whether or not this pointcut matches the execution of a given piece of advice.
+        * 
+        * @param anAdviceMethod a method representing the advice being executed
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing the
+        *         execution of the advice.
+        */
+       ShadowMatch matchesAdviceExecution(Method anAdviceMethod);
+
+       /**
+        * Determine whether or not this pointcut matches the initialization of an object initiated by a call to the given constructor.
+        * 
+        * @param aConstructor the constructor initiating the initialization
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing
+        *         initialization via the given constructor.
+        */
+       ShadowMatch matchesInitialization(Constructor aConstructor);
+
+       /**
+        * Determine whether or not this pointcut matches the pre-initialization of an object initiated by a call to the given
+        * constructor.
+        * 
+        * @param aConstructor the constructor initiating the initialization
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing
+        *         pre-initialization via the given constructor.
+        */
+       ShadowMatch matchesPreInitialization(Constructor aConstructor);
+
+       /**
+        * Determine whether or not this pointcut matches a method call to the given method, made during the execution of the given
+        * method or constructor.
+        * 
+        * @param aMethod the method being called
+        * @param withinCode the Method or Constructor from within which the call is made
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing a call to
+        *         this method during the execution of the given member.
+        */
+       ShadowMatch matchesMethodCall(Method aMethod, Member withinCode);
+
+       /**
+        * Determine whether or not this pointcut matches a method call to the given method, made outside of the scope of any method or
+        * constructor, but within the callerType (for example, during static initialization of the type).
+        * 
+        * @param aMethod the method being called
+        * @param callerType the declared type of the caller
+        * @param receiverType the declared type of the recipient of the call
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing a call to
+        *         this method during the execution of the given member.
+        */
+       ShadowMatch matchesMethodCall(Method aMethod, Class callerType);
+
+       /**
+        * Determine whether or not this pointcut matches a method call to the given constructor, made during the execution of the given
+        * method or constructor.
+        * 
+        * @param aConstructor the constructor being called
+        * @param withinCode the Method or Constructor from within which the call is made
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing a call to
+        *         this constructor during the execution of the given member.
+        */
+       ShadowMatch matchesConstructorCall(Constructor aConstructor, Member withinCode);
+
+       /**
+        * Determine whether or not this pointcut matches a method call to the given constructor, made outside of the scope of any
+        * method or constructor, but within the callerType.
+        * 
+        * @param aConstructor the cosstructor being called
+        * @param callerType the declared type of the caller
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing a call to
+        *         this constructor during the execution of the given member.
+        */
+       ShadowMatch matchesConstructorCall(Constructor aConstructor, Class callerType);
+
+       /**
+        * Determine whether or not this pointcut matches the execution of a given exception handler within the given method or
+        * constructor
+        * 
+        * @param exceptionType the static type of the exception being handled
+        * @param withinCode the method or constructor in which the catch block is declared
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing the
+        *         handling of the given exception
+        */
+       ShadowMatch matchesHandler(Class exceptionType, Member withinCode);
+
+       /**
+        * Determine whether or not this pointcut matches the execution of a given exception handler outside of the scope of any method
+        * or constructor, but within the handling type.
+        * 
+        * @param exceptionType the static type of the exception being handled
+        * @param handlingType the type in which the handler block is executing
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches join points representing the
+        *         handling of the given exception
+        */
+       ShadowMatch matchesHandler(Class exceptionType, Class handlingType);
+
+       /**
+        * Determine whether or not this pointcut matches a set of the given field from within the given method or constructor.
+        * 
+        * @param aField the field being updated
+        * @param withinCode the Method or Constructor owning the call site
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches field set join points for the given
+        *         field and call site.
+        */
+       ShadowMatch matchesFieldSet(Field aField, Member withinCode);
+
+       /**
+        * Determine whether or not this pointcut matches a set of the given field outside of the scope of any method or constructor,
+        * but within the given type (for example, during static initialization).
+        * 
+        * @param aField the field being updated
+        * @param withinType the type owning the call site
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches field set join points for the given
+        *         field and call site.
+        */
+       ShadowMatch matchesFieldSet(Field aField, Class withinType);
+
+       /**
+        * Determine whether or not this pointcut matches a get of the given field from within the given method or constructor.
+        * 
+        * @param aField the field being updated
+        * @param withinCode the Method or Constructor owning the call site
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches field get join points for the given
+        *         field and call site.
+        */
+       ShadowMatch matchesFieldGet(Field aField, Member withinCode);
+
+       /**
+        * Determine whether or not this pointcut matches a get of the given field outside of the scope of any method or constructor,
+        * but within the given type (for example, during static initialization).
+        * 
+        * @param aField the field being accessed
+        * @param withinType the type owning the call site
+        * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never matches field get join points for the given
+        *         field and call site.
+        */
+       ShadowMatch matchesFieldGet(Field aField, Class withinType);
+
+       /**
+        * Return a string representation of this pointcut expression.
+        */
+       String getPointcutExpression();
+}
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutParser.java b/org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutParser.java
new file mode 100644 (file)
index 0000000..eee063f
--- /dev/null
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.weaver.tools;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.SourceLocation;
+import org.aspectj.weaver.BindingScope;
+import org.aspectj.weaver.IHasPosition;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.internal.tools.StandardPointcutExpressionImpl;
+import org.aspectj.weaver.internal.tools.TypePatternMatcherImpl;
+import org.aspectj.weaver.patterns.AndPointcut;
+import org.aspectj.weaver.patterns.CflowPointcut;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.IScope;
+import org.aspectj.weaver.patterns.KindedPointcut;
+import org.aspectj.weaver.patterns.NotPointcut;
+import org.aspectj.weaver.patterns.OrPointcut;
+import org.aspectj.weaver.patterns.ParserException;
+import org.aspectj.weaver.patterns.PatternParser;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.SimpleScope;
+import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut;
+import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
+import org.aspectj.weaver.patterns.TypePattern;
+import org.aspectj.weaver.reflect.PointcutParameterImpl;
+import org.aspectj.weaver.reflect.ReflectionWorld;
+
+/**
+ * A PointcutParser can be used to build PointcutExpressions for a user-defined subset of AspectJ's pointcut language
+ */
+public class StandardPointcutParser {
+
+       private World world;
+       private final Set supportedPrimitives;
+       private final Set pointcutDesignators = new HashSet();
+
+       /**
+        * @return a Set containing every PointcutPrimitive except if, cflow, and cflowbelow (useful for passing to PointcutParser
+        *         constructor).
+        */
+       public static Set getAllSupportedPointcutPrimitives() {
+               Set primitives = new HashSet();
+               primitives.add(PointcutPrimitive.ADVICE_EXECUTION);
+               primitives.add(PointcutPrimitive.ARGS);
+               primitives.add(PointcutPrimitive.CALL);
+               primitives.add(PointcutPrimitive.EXECUTION);
+               primitives.add(PointcutPrimitive.GET);
+               primitives.add(PointcutPrimitive.HANDLER);
+               primitives.add(PointcutPrimitive.INITIALIZATION);
+               primitives.add(PointcutPrimitive.PRE_INITIALIZATION);
+               primitives.add(PointcutPrimitive.SET);
+               primitives.add(PointcutPrimitive.STATIC_INITIALIZATION);
+               primitives.add(PointcutPrimitive.TARGET);
+               primitives.add(PointcutPrimitive.THIS);
+               primitives.add(PointcutPrimitive.WITHIN);
+               primitives.add(PointcutPrimitive.WITHIN_CODE);
+               primitives.add(PointcutPrimitive.AT_ANNOTATION);
+               primitives.add(PointcutPrimitive.AT_THIS);
+               primitives.add(PointcutPrimitive.AT_TARGET);
+               primitives.add(PointcutPrimitive.AT_ARGS);
+               primitives.add(PointcutPrimitive.AT_WITHIN);
+               primitives.add(PointcutPrimitive.AT_WITHINCODE);
+               primitives.add(PointcutPrimitive.REFERENCE);
+
+               return primitives;
+       }
+
+       /**
+        * Returns a pointcut parser that can parse the full AspectJ pointcut language with the following exceptions:
+        * <ul>
+        * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+        * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+        * <li>The pointcut expression must be anonymous with no formals allowed.
+        * </ul>
+        * <p>
+        * When resolving types in pointcut expressions, the context classloader is used to find types.
+        * </p>
+        */
+       public static StandardPointcutParser getPointcutParserSupportingAllPrimitives(World world) {
+               StandardPointcutParser p = new StandardPointcutParser(world);
+               return p;
+       }
+
+       /**
+        * Returns a pointcut parser that can parse pointcut expressions built from a user-defined subset of AspectJ's supported
+        * pointcut primitives. The following restrictions apply:
+        * <ul>
+        * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+        * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+        * <li>The pointcut expression must be anonymous with no formals allowed.
+        * </ul>
+        * <p>
+        * When resolving types in pointcut expressions, the given classloader is used to find types.
+        * </p>
+        * 
+        * @param supportedPointcutKinds a set of PointcutPrimitives this parser should support
+        * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below
+        */
+       public static StandardPointcutParser getPointcutParserSupportingSpecifiedPrimitives(Set supportedPointcutKinds, World world) {
+               StandardPointcutParser p = new StandardPointcutParser(supportedPointcutKinds, world);
+               return p;
+       }
+
+       /**
+        * Create a pointcut parser that can parse the full AspectJ pointcut language with the following exceptions:
+        * <ul>
+        * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+        * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+        * <li>The pointcut expression must be anonymous with no formals allowed.
+        * </ul>
+        */
+       protected StandardPointcutParser(World world) {
+               supportedPrimitives = getAllSupportedPointcutPrimitives();
+               this.world = world;
+       }
+
+       /**
+        * Create a pointcut parser that can parse pointcut expressions built from a user-defined subset of AspectJ's supported pointcut
+        * primitives. The following restrictions apply:
+        * <ul>
+        * <li>The <code>if, cflow, and cflowbelow</code> pointcut designators are not supported
+        * <li>Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts
+        * <li>The pointcut expression must be anonymous with no formals allowed.
+        * </ul>
+        * 
+        * @param supportedPointcutKinds a set of PointcutPrimitives this parser should support
+        * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below
+        */
+       private StandardPointcutParser(Set/* <PointcutPrimitives> */supportedPointcutKinds, World world) {
+               supportedPrimitives = supportedPointcutKinds;
+               for (Iterator iter = supportedPointcutKinds.iterator(); iter.hasNext();) {
+                       PointcutPrimitive element = (PointcutPrimitive) iter.next();
+                       if ((element == PointcutPrimitive.IF) || (element == PointcutPrimitive.CFLOW)
+                                       || (element == PointcutPrimitive.CFLOW_BELOW)) {
+                               throw new UnsupportedOperationException("Cannot handle if, cflow, and cflowbelow primitives");
+                       }
+               }
+               this.world = world;
+       }
+
+       // /**
+       // * Set the lint properties for this parser from the given resource on the classpath.
+       // *
+       // * @param resourcePath path to a file containing aspectj lint properties
+       // */
+       // public void setLintProperties(String resourcePath) throws IOException {
+       // URL url = this.classLoaderReference.getClassLoader().getResource(resourcePath);
+       // InputStream is = url.openStream();
+       // Properties p = new Properties();
+       // p.load(is);
+       // setLintProperties(p);
+       // }
+
+       /**
+        * Set the lint properties for this parser from the given properties set.
+        * 
+        * @param properties
+        */
+       public void setLintProperties(Properties properties) {
+               getWorld().getLint().setFromProperties(properties);
+       }
+
+       /**
+        * Register a new pointcut designator handler with this parser. This provides an extension mechansim for the integration of
+        * domain-specific pointcut designators with the AspectJ pointcut language.
+        * 
+        * @param designatorHandler
+        */
+       public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) {
+               this.pointcutDesignators.add(designatorHandler);
+               if (world != null)
+                       world.registerPointcutHandler(designatorHandler);
+       }
+
+       /**
+        * Create a pointcut parameter of the given name and type.
+        * 
+        * @param name
+        * @param type
+        * @return
+        */
+       public PointcutParameter createPointcutParameter(String name, Class type) {
+               return new PointcutParameterImpl(name, type);
+       }
+
+       /**
+        * Parse the given pointcut expression. A global scope is assumed for resolving any type references, and the pointcut must
+        * contain no formals (variables to be bound).
+        * 
+        * @throws UnsupportedPointcutPrimitiveException if the parser encounters a primitive pointcut expression of a kind not
+        *         supported by this PointcutParser.
+        * @throws IllegalArgumentException if the expression is not a well-formed pointcut expression
+        */
+       public StandardPointcutExpression parsePointcutExpression(String expression) throws UnsupportedPointcutPrimitiveException,
+                       IllegalArgumentException {
+               return parsePointcutExpression(expression, null, new PointcutParameter[0]);
+       }
+
+       /**
+        * Parse the given pointcut expression. The pointcut is resolved as if it had been declared inside the inScope class (this
+        * allows the pointcut to contain unqualified references to other pointcuts declared in the same type for example). The pointcut
+        * may contain zero or more formal parameters to be bound at matched join points.
+        * 
+        * @throws UnsupportedPointcutPrimitiveException if the parser encounters a primitive pointcut expression of a kind not
+        *         supported by this PointcutParser.
+        * @throws IllegalArgumentException if the expression is not a well-formed pointcut expression
+        */
+       public StandardPointcutExpression parsePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters)
+                       throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
+               StandardPointcutExpressionImpl pcExpr = null;
+               try {
+                       Pointcut pc = resolvePointcutExpression(expression, inScope, formalParameters);
+                       pc = concretizePointcutExpression(pc, inScope, formalParameters);
+                       validateAgainstSupportedPrimitives(pc, expression); // again, because we have now followed any ref'd pcuts
+                       pcExpr = new StandardPointcutExpressionImpl(pc, expression, formalParameters, getWorld());
+               } catch (ParserException pEx) {
+                       throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx));
+               } catch (ReflectionWorld.ReflectionWorldException rwEx) {
+                       throw new IllegalArgumentException(rwEx.getMessage());
+               }
+               return pcExpr;
+       }
+
+       protected Pointcut resolvePointcutExpression(String expression, Class inScope, PointcutParameter[] formalParameters) {
+               try {
+                       PatternParser parser = new PatternParser(expression);
+                       parser.setPointcutDesignatorHandlers(pointcutDesignators, world);
+                       Pointcut pc = parser.parsePointcut();
+                       validateAgainstSupportedPrimitives(pc, expression);
+                       IScope resolutionScope = buildResolutionScope((inScope == null ? Object.class : inScope), formalParameters);
+                       pc = pc.resolve(resolutionScope);
+                       return pc;
+               } catch (ParserException pEx) {
+                       throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx));
+               }
+       }
+
+       protected Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) {
+               ResolvedType declaringTypeForResolution = null;
+               if (inScope != null) {
+                       declaringTypeForResolution = getWorld().resolve(inScope.getName());
+               } else {
+                       declaringTypeForResolution = ResolvedType.OBJECT.resolve(getWorld());
+               }
+               IntMap arity = new IntMap(formalParameters.length);
+               for (int i = 0; i < formalParameters.length; i++) {
+                       arity.put(i, i);
+               }
+               return pc.concretize(declaringTypeForResolution, declaringTypeForResolution, arity);
+       }
+
+       /**
+        * Parse the given aspectj type pattern, and return a matcher that can be used to match types using it.
+        * 
+        * @param typePattern an aspectj type pattern
+        * @return a type pattern matcher that matches using the given pattern
+        * @throws IllegalArgumentException if the type pattern cannot be successfully parsed.
+        */
+       public TypePatternMatcher parseTypePattern(String typePattern) throws IllegalArgumentException {
+               try {
+                       TypePattern tp = new PatternParser(typePattern).parseTypePattern();
+                       tp.resolve(world);
+                       return new TypePatternMatcherImpl(tp, world);
+               } catch (ParserException pEx) {
+                       throw new IllegalArgumentException(buildUserMessageFromParserException(typePattern, pEx));
+               } catch (ReflectionWorld.ReflectionWorldException rwEx) {
+                       throw new IllegalArgumentException(rwEx.getMessage());
+               }
+       }
+
+       private World getWorld() {
+               return world;
+       }
+
+       /* for testing */
+       Set getSupportedPrimitives() {
+               return supportedPrimitives;
+       }
+
+       /* for testing */
+       IMessageHandler setCustomMessageHandler(IMessageHandler aHandler) {
+               IMessageHandler current = getWorld().getMessageHandler();
+               getWorld().setMessageHandler(aHandler);
+               return current;
+       }
+
+       private IScope buildResolutionScope(Class inScope, PointcutParameter[] formalParameters) {
+               if (formalParameters == null)
+                       formalParameters = new PointcutParameter[0];
+               FormalBinding[] formalBindings = new FormalBinding[formalParameters.length];
+               for (int i = 0; i < formalBindings.length; i++) {
+                       formalBindings[i] = new FormalBinding(toUnresolvedType(formalParameters[i].getType()), formalParameters[i].getName(), i);
+               }
+               if (inScope == null) {
+                       return new SimpleScope(getWorld(), formalBindings);
+               } else {
+                       ResolvedType inType = getWorld().resolve(inScope.getName());
+                       ISourceContext sourceContext = new ISourceContext() {
+                               public ISourceLocation makeSourceLocation(IHasPosition position) {
+                                       return new SourceLocation(new File(""), 0);
+                               }
+
+                               public ISourceLocation makeSourceLocation(int line, int offset) {
+                                       return new SourceLocation(new File(""), line);
+                               }
+
+                               public int getOffset() {
+                                       return 0;
+                               }
+
+                               public void tidy() {
+                               }
+                       };
+                       return new BindingScope(inType, sourceContext, formalBindings);
+               }
+       }
+
+       private UnresolvedType toUnresolvedType(Class clazz) {
+               if (clazz.isArray()) {
+                       return UnresolvedType.forSignature(clazz.getName().replace('.', '/'));
+               } else {
+                       return UnresolvedType.forName(clazz.getName());
+               }
+       }
+
+       private void validateAgainstSupportedPrimitives(Pointcut pc, String expression) {
+               switch (pc.getPointcutKind()) {
+               case Pointcut.AND:
+                       validateAgainstSupportedPrimitives(((AndPointcut) pc).getLeft(), expression);
+                       validateAgainstSupportedPrimitives(((AndPointcut) pc).getRight(), expression);
+                       break;
+               case Pointcut.ARGS:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.ARGS))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ARGS);
+                       break;
+               case Pointcut.CFLOW:
+                       CflowPointcut cfp = (CflowPointcut) pc;
+                       if (cfp.isCflowBelow()) {
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW_BELOW);
+                       } else {
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CFLOW);
+                       }
+               case Pointcut.HANDLER:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.HANDLER))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.HANDLER);
+                       break;
+               case Pointcut.IF:
+               case Pointcut.IF_FALSE:
+               case Pointcut.IF_TRUE:
+                       throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.IF);
+               case Pointcut.KINDED:
+                       validateKindedPointcut(((KindedPointcut) pc), expression);
+                       break;
+               case Pointcut.NOT:
+                       validateAgainstSupportedPrimitives(((NotPointcut) pc).getNegatedPointcut(), expression);
+                       break;
+               case Pointcut.OR:
+                       validateAgainstSupportedPrimitives(((OrPointcut) pc).getLeft(), expression);
+                       validateAgainstSupportedPrimitives(((OrPointcut) pc).getRight(), expression);
+                       break;
+               case Pointcut.THIS_OR_TARGET:
+                       boolean isThis = ((ThisOrTargetPointcut) pc).isThis();
+                       if (isThis && !supportedPrimitives.contains(PointcutPrimitive.THIS)) {
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.THIS);
+                       } else if (!supportedPrimitives.contains(PointcutPrimitive.TARGET)) {
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.TARGET);
+                       }
+                       break;
+               case Pointcut.WITHIN:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN);
+                       break;
+               case Pointcut.WITHINCODE:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.WITHIN_CODE))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.WITHIN_CODE);
+                       break;
+               case Pointcut.ATTHIS_OR_TARGET:
+                       isThis = ((ThisOrTargetAnnotationPointcut) pc).isThis();
+                       if (isThis && !supportedPrimitives.contains(PointcutPrimitive.AT_THIS)) {
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_THIS);
+                       } else if (!supportedPrimitives.contains(PointcutPrimitive.AT_TARGET)) {
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_TARGET);
+                       }
+                       break;
+               case Pointcut.ATARGS:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.AT_ARGS))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ARGS);
+                       break;
+               case Pointcut.ANNOTATION:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.AT_ANNOTATION))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_ANNOTATION);
+                       break;
+               case Pointcut.ATWITHIN:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHIN))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHIN);
+                       break;
+               case Pointcut.ATWITHINCODE:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.AT_WITHINCODE))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.AT_WITHINCODE);
+                       break;
+               case Pointcut.REFERENCE:
+                       if (!supportedPrimitives.contains(PointcutPrimitive.REFERENCE))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE);
+                       break;
+               case Pointcut.USER_EXTENSION:
+                       // always ok...
+                       break;
+               case Pointcut.NONE: // deliberate fall-through
+               default:
+                       throw new IllegalArgumentException("Unknown pointcut kind: " + pc.getPointcutKind());
+               }
+       }
+
+       private void validateKindedPointcut(KindedPointcut pc, String expression) {
+               Shadow.Kind kind = pc.getKind();
+               if ((kind == Shadow.MethodCall) || (kind == Shadow.ConstructorCall)) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.CALL))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.CALL);
+               } else if ((kind == Shadow.MethodExecution) || (kind == Shadow.ConstructorExecution)) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.EXECUTION))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.EXECUTION);
+               } else if (kind == Shadow.AdviceExecution) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.ADVICE_EXECUTION))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.ADVICE_EXECUTION);
+               } else if (kind == Shadow.FieldGet) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.GET))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.GET);
+               } else if (kind == Shadow.FieldSet) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.SET))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.SET);
+               } else if (kind == Shadow.Initialization) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.INITIALIZATION))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.INITIALIZATION);
+               } else if (kind == Shadow.PreInitialization) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.PRE_INITIALIZATION))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.PRE_INITIALIZATION);
+               } else if (kind == Shadow.StaticInitialization) {
+                       if (!supportedPrimitives.contains(PointcutPrimitive.STATIC_INITIALIZATION))
+                               throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.STATIC_INITIALIZATION);
+               }
+       }
+
+       private String buildUserMessageFromParserException(String pc, ParserException ex) {
+               StringBuffer msg = new StringBuffer();
+               msg.append("Pointcut is not well-formed: expecting '");
+               msg.append(ex.getMessage());
+               msg.append("'");
+               IHasPosition location = ex.getLocation();
+               msg.append(" at character position ");
+               msg.append(location.getStart());
+               msg.append("\n");
+               msg.append(pc);
+               msg.append("\n");
+               for (int i = 0; i < location.getStart(); i++) {
+                       msg.append(" ");
+               }
+               for (int j = location.getStart(); j <= location.getEnd(); j++) {
+                       msg.append("^");
+               }
+               msg.append("\n");
+               return msg.toString();
+       }
+}
diff --git a/org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/CommonPointcutExpressionTests.java b/org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/CommonPointcutExpressionTests.java
new file mode 100644 (file)
index 0000000..26e0e0b
--- /dev/null
@@ -0,0 +1,659 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Contributors
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Andy Clement
+ *******************************************************************************/
+package org.aspectj.matcher.tools;
+
+import junit.framework.TestCase;
+
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.tools.StandardPointcutExpression;
+import org.aspectj.weaver.tools.StandardPointcutParser;
+
+/**
+ * Test the use of the pointcut parser and matching infrastructure. The org.aspectj.matcher.tools infrastructure used should not be
+ * aware of what kind of World it is working with and only operate in terms of the type abstraction expressed in the
+ * org.aspectj.matcher project (so Members, etc).
+ * 
+ * This is based on the Reflection oriented PointcutExpressionTest in the weaver project.
+ * 
+ * @author Andy Clement
+ */
+public abstract class CommonPointcutExpressionTests extends TestCase {
+
+       private World world;
+       private StandardPointcutParser pointcutParser;
+
+       protected abstract World getWorld();
+
+       protected void setUp() throws Exception {
+               super.setUp();
+               world = getWorld();
+               pointcutParser = StandardPointcutParser.getPointcutParserSupportingAllPrimitives(world);
+       }
+
+       public void testResolvingOneType() {
+               // do it via name
+               ResolvedType type = world.resolve("java.lang.String");
+               assertNotNull(type);
+               // do it via signature
+               type = world.resolve(UnresolvedType.forSignature("Ljava/lang/String;"));
+               assertNotNull(type);
+       }
+
+       public void testResolveTypeAndRetrieveMethod() {
+               ResolvedType type = world.resolve("java.lang.String");
+               assertNotNull(type);
+               ResolvedMember method = getMethod(type, "valueOf", "(Z)Ljava/lang/String;"); // grab the method 'String valueOf()'
+               assertNotNull(method);
+       }
+
+       public void testMethodExecutionMatching01() {
+               checkAlwaysMatches("execution(String valueOf(boolean))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+       }
+
+       public void testMethodExecutionMatching02() {
+               checkAlwaysMatches("execution(* *val*(..))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkAlwaysMatches("execution(String *(..))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkAlwaysMatches("execution(* *(boolean))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkAlwaysMatches("execution(* j*..*.valueOf(..))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkAlwaysMatches("execution(* *(*))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+
+               checkNeverMatches("execution(* vulueOf(..))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkNeverMatches("execution(int *(..))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkNeverMatches("execution(* valueOf(String))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+               checkNeverMatches("execution(private * valueOf(..))", "java.lang.String", "valueOf", "(Z)Ljava/lang/String;");
+       }
+
+       public void testMethodExecutionMatching03() {
+               checkAlwaysMatches("execution(* *())", "java.util.List", "toArray", "()[Ljava/lang/Object;");
+               checkAlwaysMatches("execution(*[] *())", "java.util.List", "toArray", "()[Ljava/lang/Object;");
+               checkAlwaysMatches("execution(*b*[] *())", "java.util.List", "toArray", "()[Ljava/lang/Object;");
+       }
+
+       // ---
+
+       public void testMethodMatchesStaticInitialization() {
+               StandardPointcutExpression ex = pointcutParser.parsePointcutExpression("staticinitialization(java.lang.String)");
+               assertNotNull(ex);
+
+               ResolvedType jlString = world.resolve("java.lang.String");
+
+               boolean b = ex.matchesStaticInitialization(jlString).alwaysMatches();
+               assertTrue(b);
+
+               // was execution((* *..A.aa(..))
+               // assertTrue("Should match execution of A.aa", ex.matchesMethodExecution(aa).alwaysMatches());
+               // assertTrue("Should match execution of B.aa", ex.matchesMethodExecution(bsaa).alwaysMatches());
+               // assertTrue("Should not match execution of A.a", ex.matchesMethodExecution(a).neverMatches());
+               // ex = p.parsePointcutExpression("call(* *..A.a*(int))");
+               // assertTrue("Should not match execution of A.a", ex.matchesMethodExecution(a).neverMatches());
+               //
+               // // test this
+               // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+               // assertTrue("Should match A", ex.matchesMethodExecution(a).alwaysMatches());
+               // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+               // assertTrue("Maybe matches B", ex.matchesMethodExecution(a).maybeMatches());
+               // assertFalse("Maybe matches B", ex.matchesMethodExecution(a).alwaysMatches());
+               //
+               // // test target
+               // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+               // assertTrue("Should match A", ex.matchesMethodExecution(a).alwaysMatches());
+               // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+               // assertTrue("Maybe matches B", ex.matchesMethodExecution(a).maybeMatches());
+               // assertFalse("Maybe matches B", ex.matchesMethodExecution(a).alwaysMatches());
+               //
+               // // test args
+               // ex = p.parsePointcutExpression("args(..,int)");
+               // assertTrue("Should match A.aa", ex.matchesMethodExecution(aa).alwaysMatches());
+               // assertTrue("Should match A.aaa", ex.matchesMethodExecution(aaa).alwaysMatches());
+               // assertTrue("Should not match A.a", ex.matchesMethodExecution(a).neverMatches());
+               //
+               // // within
+               // ex = p.parsePointcutExpression("within(*..A)");
+               // assertTrue("Matches in class A", ex.matchesMethodExecution(a).alwaysMatches());
+               // assertTrue("Does not match in class B", ex.matchesMethodExecution(bsaa).neverMatches());
+               //
+               // // withincode
+               // ex = p.parsePointcutExpression("withincode(* a*(..))");
+               // assertTrue("Should not match", ex.matchesMethodExecution(a).neverMatches());
+       }
+
+       // public void testMatchesMethodCall() {
+       // PointcutExpression ex = p.parsePointcutExpression("call(* *..A.a*(..))");
+       // assertTrue("Should match call to A.a()", ex.matchesMethodCall(a, a).alwaysMatches());
+       // assertTrue("Should match call to A.aaa()", ex.matchesMethodCall(aaa, a).alwaysMatches());
+       // assertTrue("Should match call to B.aa()", ex.matchesMethodCall(bsaa, a).alwaysMatches());
+       // assertTrue("Should not match call to B.b()", ex.matchesMethodCall(b, a).neverMatches());
+       // ex = p.parsePointcutExpression("call(* *..A.a*(int))");
+       // assertTrue("Should match call to A.aa()", ex.matchesMethodCall(aa, a).alwaysMatches());
+       // assertTrue("Should not match call to A.a()", ex.matchesMethodCall(a, a).neverMatches());
+       // ex = p.parsePointcutExpression("call(void aaa(..)) && this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match call to A.aaa() from Client", ex.matchesMethodCall(aaa, foo).alwaysMatches());
+       // ex = p.parsePointcutExpression("call(void aaa(..)) && this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Should match call to A.aaa() from B", ex.matchesMethodCall(aaa, b).alwaysMatches());
+       // assertTrue("May match call to A.aaa() from A", ex.matchesMethodCall(aaa, a).maybeMatches());
+       // assertFalse("May match call to A.aaa() from A", ex.matchesMethodCall(aaa, a).alwaysMatches());
+       // ex = p.parsePointcutExpression("execution(* *.*(..))");
+       // assertTrue("Should not match call to A.aa", ex.matchesMethodCall(aa, a).neverMatches());
+       // // this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match Client", ex.matchesMethodCall(a, foo).alwaysMatches());
+       // assertTrue("Should not match A", ex.matchesMethodCall(a, a).neverMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Should maybe match B", ex.matchesMethodCall(bsaa, a).maybeMatches());
+       // assertFalse("Should maybe match B", ex.matchesMethodCall(bsaa, a).alwaysMatches());
+       // // target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should not match Client", ex.matchesMethodCall(a, a).neverMatches());
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("Should match A", ex.matchesMethodCall(a, a).alwaysMatches());
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Should maybe match A", ex.matchesMethodCall(aa, a).maybeMatches());
+       // assertFalse("Should maybe match A", ex.matchesMethodCall(aa, a).alwaysMatches());
+       // // test args
+       // ex = p.parsePointcutExpression("args(..,int)");
+       // assertTrue("Should match A.aa", ex.matchesMethodCall(aa, a).alwaysMatches());
+       // assertTrue("Should match A.aaa", ex.matchesMethodCall(aaa, a).alwaysMatches());
+       // assertTrue("Should not match A.a", ex.matchesMethodCall(a, a).neverMatches());
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesMethodCall(a, a).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesMethodCall(a, b).neverMatches());
+       // assertTrue("Matches in class A", ex.matchesMethodCall(a, A.class).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesMethodCall(a, B.class).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Should match", ex.matchesMethodCall(b, bsaa).alwaysMatches());
+       // assertTrue("Should not match", ex.matchesMethodCall(b, b).neverMatches());
+       // }
+       // public void testMatchesConstructorCall() {
+       // PointcutExpression ex = p.parsePointcutExpression("call(new(String))");
+       // assertTrue("Should match A(String)", ex.matchesConstructorCall(asCons, b).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesConstructorCall(bsStringCons, b).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesConstructorCall(bsCons, foo).neverMatches());
+       // ex = p.parsePointcutExpression("call(*..A.new(String))");
+       // assertTrue("Should match A(String)", ex.matchesConstructorCall(asCons, b).alwaysMatches());
+       // assertTrue("Should not match B(String)", ex.matchesConstructorCall(bsStringCons, foo).neverMatches());
+       // // this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match Client", ex.matchesConstructorCall(asCons, foo).alwaysMatches());
+       // assertTrue("Should not match A", ex.matchesConstructorCall(asCons, a).neverMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Should maybe match B", ex.matchesConstructorCall(asCons, a).maybeMatches());
+       // assertFalse("Should maybe match B", ex.matchesConstructorCall(asCons, a).alwaysMatches());
+       // // target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should not match Client", ex.matchesConstructorCall(asCons, foo).neverMatches());
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("Should not match A (no target)", ex.matchesConstructorCall(asCons, a).neverMatches());
+       // // args
+       // ex = p.parsePointcutExpression("args(String)");
+       // assertTrue("Should match A(String)", ex.matchesConstructorCall(asCons, b).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesConstructorCall(bsStringCons, foo).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesConstructorCall(bsCons, foo).neverMatches());
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesConstructorCall(asCons, a).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesConstructorCall(asCons, b).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Should match", ex.matchesConstructorCall(bsCons, aa).alwaysMatches());
+       // assertTrue("Should not match", ex.matchesConstructorCall(bsCons, b).neverMatches());
+       // }
+       //
+       // public void testMatchesConstructorExecution() {
+       // PointcutExpression ex = p.parsePointcutExpression("execution(new(String))");
+       // assertTrue("Should match A(String)", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesConstructorExecution(bsStringCons).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesConstructorExecution(bsCons).neverMatches());
+       // ex = p.parsePointcutExpression("execution(*..A.new(String))");
+       // assertTrue("Should match A(String)", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // assertTrue("Should not match B(String)", ex.matchesConstructorExecution(bsStringCons).neverMatches());
+       //
+       // // test this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("Should match A", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesConstructorExecution(asCons).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // assertTrue("Should match B", ex.matchesConstructorExecution(bsCons).alwaysMatches());
+       // assertTrue("Does not match client", ex.matchesConstructorExecution(clientCons).neverMatches());
+       //
+       // // test target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("Should match A", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesConstructorExecution(asCons).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // assertTrue("Should match B", ex.matchesConstructorExecution(bsCons).alwaysMatches());
+       // assertTrue("Does not match client", ex.matchesConstructorExecution(clientCons).neverMatches());
+       //
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesConstructorExecution(bsCons).neverMatches());
+       //
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Does not match", ex.matchesConstructorExecution(bsCons).neverMatches());
+       //
+       // // args
+       // ex = p.parsePointcutExpression("args(String)");
+       // assertTrue("Should match A(String)", ex.matchesConstructorExecution(asCons).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesConstructorExecution(bsStringCons).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesConstructorExecution(bsCons).neverMatches());
+       // }
+       //
+       // public void testMatchesAdviceExecution() {
+       // PointcutExpression ex = p.parsePointcutExpression("adviceexecution()");
+       // assertTrue("Should match (advice) A.a", ex.matchesAdviceExecution(a).alwaysMatches());
+       // // test this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match Client", ex.matchesAdviceExecution(foo).alwaysMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesAdviceExecution(a).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesAdviceExecution(a).alwaysMatches());
+       // assertTrue("Does not match client", ex.matchesAdviceExecution(foo).neverMatches());
+       //
+       // // test target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match Client", ex.matchesAdviceExecution(foo).alwaysMatches());
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesAdviceExecution(a).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesAdviceExecution(a).alwaysMatches());
+       // assertTrue("Does not match client", ex.matchesAdviceExecution(foo).neverMatches());
+       //
+       // // test within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesAdviceExecution(a).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesAdviceExecution(b).neverMatches());
+       //
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Does not match", ex.matchesAdviceExecution(a).neverMatches());
+       //
+       // // test args
+       // ex = p.parsePointcutExpression("args(..,int)");
+       // assertTrue("Should match A.aa", ex.matchesAdviceExecution(aa).alwaysMatches());
+       // assertTrue("Should match A.aaa", ex.matchesAdviceExecution(aaa).alwaysMatches());
+       // assertTrue("Should not match A.a", ex.matchesAdviceExecution(a).neverMatches());
+       // }
+       //
+       // public void testMatchesHandler() {
+       // PointcutExpression ex = p.parsePointcutExpression("handler(Exception)");
+       // assertTrue("Should match catch(Exception)", ex.matchesHandler(Exception.class, Client.class).alwaysMatches());
+       // assertTrue("Should not match catch(Throwable)", ex.matchesHandler(Throwable.class, Client.class).neverMatches());
+       // // test this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match Client", ex.matchesHandler(Exception.class, foo).alwaysMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesHandler(Exception.class, a).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesHandler(Exception.class, a).alwaysMatches());
+       // assertTrue("Does not match client", ex.matchesHandler(Exception.class, foo).neverMatches());
+       // // target - no target for exception handlers
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("Should match Client", ex.matchesHandler(Exception.class, foo).neverMatches());
+       // // args
+       // ex = p.parsePointcutExpression("args(Exception)");
+       // assertTrue("Should match Exception", ex.matchesHandler(Exception.class, foo).alwaysMatches());
+       // assertTrue("Should match RuntimeException", ex.matchesHandler(RuntimeException.class, foo).alwaysMatches());
+       // assertTrue("Should not match String", ex.matchesHandler(String.class, foo).neverMatches());
+       // assertTrue("Maybe matches Throwable", ex.matchesHandler(Throwable.class, foo).maybeMatches());
+       // assertFalse("Maybe matches Throwable", ex.matchesHandler(Throwable.class, foo).alwaysMatches());
+       // // within
+       // ex = p.parsePointcutExpression("within(*..Client)");
+       // assertTrue("Matches in class Client", ex.matchesHandler(Exception.class, foo).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesHandler(Exception.class, b).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Matches within aa", ex.matchesHandler(Exception.class, aa).alwaysMatches());
+       // assertTrue("Does not match within b", ex.matchesHandler(Exception.class, b).neverMatches());
+       // }
+       //
+       // public void testMatchesInitialization() {
+       // PointcutExpression ex = p.parsePointcutExpression("initialization(new(String))");
+       // assertTrue("Should match A(String)", ex.matchesInitialization(asCons).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesInitialization(bsStringCons).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesInitialization(bsCons).neverMatches());
+       // ex = p.parsePointcutExpression("initialization(*..A.new(String))");
+       // assertTrue("Should match A(String)", ex.matchesInitialization(asCons).alwaysMatches());
+       // assertTrue("Should not match B(String)", ex.matchesInitialization(bsStringCons).neverMatches());
+       // // test this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("Should match A", ex.matchesInitialization(asCons).alwaysMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesInitialization(asCons).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesInitialization(asCons).alwaysMatches());
+       //
+       // // test target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("Should match A", ex.matchesInitialization(asCons).alwaysMatches());
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("Maybe matches B", ex.matchesInitialization(asCons).maybeMatches());
+       // assertFalse("Maybe matches B", ex.matchesInitialization(asCons).alwaysMatches());
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesInitialization(asCons).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesInitialization(bsCons).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Does not match", ex.matchesInitialization(bsCons).neverMatches());
+       // // args
+       // ex = p.parsePointcutExpression("args(String)");
+       // assertTrue("Should match A(String)", ex.matchesInitialization(asCons).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesInitialization(bsStringCons).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesInitialization(bsCons).neverMatches());
+       // }
+       //
+       // public void testMatchesPreInitialization() {
+       // PointcutExpression ex = p.parsePointcutExpression("preinitialization(new(String))");
+       // assertTrue("Should match A(String)", ex.matchesPreInitialization(asCons).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesPreInitialization(bsStringCons).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesPreInitialization(bsCons).neverMatches());
+       // ex = p.parsePointcutExpression("preinitialization(*..A.new(String))");
+       // assertTrue("Should match A(String)", ex.matchesPreInitialization(asCons).alwaysMatches());
+       // assertTrue("Should not match B(String)", ex.matchesPreInitialization(bsStringCons).neverMatches());
+       // // test this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("No match, no this at preinit", ex.matchesPreInitialization(asCons).neverMatches());
+       //
+       // // test target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("No match, no target at preinit", ex.matchesPreInitialization(asCons).neverMatches());
+       //
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesPreInitialization(asCons).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesPreInitialization(bsCons).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Does not match", ex.matchesPreInitialization(bsCons).neverMatches());
+       // // args
+       // ex = p.parsePointcutExpression("args(String)");
+       // assertTrue("Should match A(String)", ex.matchesPreInitialization(asCons).alwaysMatches());
+       // assertTrue("Should match B(String)", ex.matchesPreInitialization(bsStringCons).alwaysMatches());
+       // assertTrue("Should not match B()", ex.matchesPreInitialization(bsCons).neverMatches());
+       // }
+       //
+       // public void testMatchesStaticInitialization() {
+       // // staticinit
+       // PointcutExpression ex = p.parsePointcutExpression("staticinitialization(*..A+)");
+       // assertTrue("Matches A", ex.matchesStaticInitialization(A.class).alwaysMatches());
+       // assertTrue("Matches B", ex.matchesStaticInitialization(B.class).alwaysMatches());
+       // assertTrue("Doesn't match Client", ex.matchesStaticInitialization(Client.class).neverMatches());
+       // // this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("No this", ex.matchesStaticInitialization(A.class).neverMatches());
+       // // target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // assertTrue("No target", ex.matchesStaticInitialization(A.class).neverMatches());
+       //
+       // // args
+       // ex = p.parsePointcutExpression("args()");
+       // assertTrue("No args", ex.matchesStaticInitialization(A.class).alwaysMatches());
+       // ex = p.parsePointcutExpression("args(String)");
+       // assertTrue("No args", ex.matchesStaticInitialization(A.class).neverMatches());
+       //
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesStaticInitialization(A.class).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesStaticInitialization(B.class).neverMatches());
+       //
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Does not match", ex.matchesStaticInitialization(A.class).neverMatches());
+       // }
+       //
+       // public void testMatchesFieldSet() {
+       // PointcutExpression ex = p.parsePointcutExpression("set(* *..A+.*)");
+       // assertTrue("matches x", ex.matchesFieldSet(x, a).alwaysMatches());
+       // assertTrue("matches y", ex.matchesFieldSet(y, foo).alwaysMatches());
+       // assertTrue("does not match n", ex.matchesFieldSet(n, foo).neverMatches());
+       // // this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("matches Client", ex.matchesFieldSet(x, foo).alwaysMatches());
+       // assertTrue("does not match A", ex.matchesFieldSet(n, a).neverMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("maybe matches A", ex.matchesFieldSet(x, a).maybeMatches());
+       // assertFalse("maybe matches A", ex.matchesFieldSet(x, a).alwaysMatches());
+       // // target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("matches B", ex.matchesFieldSet(y, foo).alwaysMatches());
+       // assertTrue("maybe matches A", ex.matchesFieldSet(x, foo).maybeMatches());
+       // assertFalse("maybe matches A", ex.matchesFieldSet(x, foo).alwaysMatches());
+       // // args
+       // ex = p.parsePointcutExpression("args(int)");
+       // assertTrue("matches x", ex.matchesFieldSet(x, a).alwaysMatches());
+       // assertTrue("matches y", ex.matchesFieldSet(y, a).alwaysMatches());
+       // assertTrue("does not match n", ex.matchesFieldSet(n, a).neverMatches());
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesFieldSet(x, a).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesFieldSet(x, b).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Should match", ex.matchesFieldSet(x, aa).alwaysMatches());
+       // assertTrue("Should not match", ex.matchesFieldSet(x, b).neverMatches());
+       // }
+       //
+       // public void testMatchesFieldGet() {
+       // PointcutExpression ex = p.parsePointcutExpression("get(* *..A+.*)");
+       // assertTrue("matches x", ex.matchesFieldGet(x, a).alwaysMatches());
+       // assertTrue("matches y", ex.matchesFieldGet(y, foo).alwaysMatches());
+       // assertTrue("does not match n", ex.matchesFieldGet(n, foo).neverMatches());
+       // // this
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)");
+       // assertTrue("matches Client", ex.matchesFieldGet(x, foo).alwaysMatches());
+       // assertTrue("does not match A", ex.matchesFieldGet(n, a).neverMatches());
+       // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("maybe matches A", ex.matchesFieldGet(x, a).maybeMatches());
+       // assertFalse("maybe matches A", ex.matchesFieldGet(x, a).alwaysMatches());
+       // // target
+       // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertTrue("matches B", ex.matchesFieldGet(y, foo).alwaysMatches());
+       // assertTrue("maybe matches A", ex.matchesFieldGet(x, foo).maybeMatches());
+       // assertFalse("maybe matches A", ex.matchesFieldGet(x, foo).alwaysMatches());
+       // // args - no args at get join point
+       // ex = p.parsePointcutExpression("args(int)");
+       // assertTrue("matches x", ex.matchesFieldGet(x, a).neverMatches());
+       // // within
+       // ex = p.parsePointcutExpression("within(*..A)");
+       // assertTrue("Matches in class A", ex.matchesFieldGet(x, a).alwaysMatches());
+       // assertTrue("Does not match in class B", ex.matchesFieldGet(x, b).neverMatches());
+       // // withincode
+       // ex = p.parsePointcutExpression("withincode(* a*(..))");
+       // assertTrue("Should match", ex.matchesFieldGet(x, aa).alwaysMatches());
+       // assertTrue("Should not match", ex.matchesFieldGet(x, b).neverMatches());
+       // }
+       //
+       // public void testArgsMatching() {
+       // // too few args
+       // PointcutExpression ex = p.parsePointcutExpression("args(*,*,*,*)");
+       // assertTrue("Too few args", ex.matchesMethodExecution(foo).neverMatches());
+       // assertTrue("Matching #args", ex.matchesMethodExecution(bar).alwaysMatches());
+       // // one too few + ellipsis
+       // ex = p.parsePointcutExpression("args(*,*,*,..)");
+       // assertTrue("Matches with ellipsis", ex.matchesMethodExecution(foo).alwaysMatches());
+       // // exact number + ellipsis
+       // assertTrue("Matches with ellipsis", ex.matchesMethodExecution(bar).alwaysMatches());
+       // assertTrue("Does not match with ellipsis", ex.matchesMethodExecution(a).neverMatches());
+       // // too many + ellipsis
+       // ex = p.parsePointcutExpression("args(*,..,*)");
+       // assertTrue("Matches with ellipsis", ex.matchesMethodExecution(bar).alwaysMatches());
+       // assertTrue("Does not match with ellipsis", ex.matchesMethodExecution(a).neverMatches());
+       // assertTrue("Matches with ellipsis", ex.matchesMethodExecution(aaa).alwaysMatches());
+       // // exact match
+       // ex = p.parsePointcutExpression("args(String,int,Number)");
+       // assertTrue("Matches exactly", ex.matchesMethodExecution(foo).alwaysMatches());
+       // // maybe match
+       // ex = p.parsePointcutExpression("args(String,int,Double)");
+       // assertTrue("Matches maybe", ex.matchesMethodExecution(foo).maybeMatches());
+       // assertFalse("Matches maybe", ex.matchesMethodExecution(foo).alwaysMatches());
+       // // never match
+       // ex = p.parsePointcutExpression("args(String,Integer,Number)");
+       // if (LangUtil.is15VMOrGreater()) {
+       // assertTrue("matches", ex.matchesMethodExecution(foo).alwaysMatches());
+       // } else {
+       // assertTrue("Does not match", ex.matchesMethodExecution(foo).neverMatches());
+       // }
+       // }
+       //
+       // // public void testMatchesDynamically() {
+       // // // everything other than this,target,args should just return true
+       // // PointcutExpression ex = p.parsePointcutExpression("call(* *.*(..)) && execution(* *.*(..)) &&" +
+       // // "get(* *) && set(* *) && initialization(new(..)) && preinitialization(new(..)) &&" +
+       // // "staticinitialization(X) && adviceexecution() && within(Y) && withincode(* *.*(..)))");
+       // // assertTrue("Matches dynamically",ex.matchesDynamically(a,b,new Object[0]));
+       // // // this
+       // // ex = p.parsePointcutExpression("this(String)");
+       // // assertTrue("String matches",ex.matchesDynamically("",this,new Object[0]));
+       // // assertFalse("Object doesn't match",ex.matchesDynamically(new Object(),this,new Object[0]));
+       // // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // // assertTrue("A matches",ex.matchesDynamically(new A(""),this,new Object[0]));
+       // // assertTrue("B matches",ex.matchesDynamically(new B(""),this,new Object[0]));
+       // // // target
+       // // ex = p.parsePointcutExpression("target(String)");
+       // // assertTrue("String matches",ex.matchesDynamically(this,"",new Object[0]));
+       // // assertFalse("Object doesn't match",ex.matchesDynamically(this,new Object(),new Object[0]));
+       // // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)");
+       // // assertTrue("A matches",ex.matchesDynamically(this,new A(""),new Object[0]));
+       // // assertTrue("B matches",ex.matchesDynamically(this,new B(""),new Object[0]));
+       // // // args
+       // // ex = p.parsePointcutExpression("args(*,*,*,*)");
+       // // assertFalse("Too few args",ex.matchesDynamically(null,null,new Object[]{a,b}));
+       // // assertTrue("Matching #args",ex.matchesDynamically(null,null,new Object[]{a,b,aa,aaa}));
+       // // // one too few + ellipsis
+       // // ex = p.parsePointcutExpression("args(*,*,*,..)");
+       // // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b,aa,aaa}));
+       // // // exact number + ellipsis
+       // // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b,aa}));
+       // // assertFalse("Does not match with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b}));
+       // // // too many + ellipsis
+       // // ex = p.parsePointcutExpression("args(*,..,*)");
+       // // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b,aa,aaa}));
+       // // assertFalse("Does not match with ellipsis",ex.matchesDynamically(null,null,new Object[]{a}));
+       // // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b}));
+       // // // exact match
+       // // ex = p.parsePointcutExpression("args(String,int,Number)");
+       // // assertTrue("Matches exactly",ex.matchesDynamically(null,null,new Object[]{"",new Integer(5),new Double(5.0)}));
+       // // ex = p.parsePointcutExpression("args(String,Integer,Number)");
+       // // assertTrue("Matches exactly",ex.matchesDynamically(null,null,new Object[]{"",new Integer(5),new Double(5.0)}));
+       // // // never match
+       // // ex = p.parsePointcutExpression("args(String,Integer,Number)");
+       // // assertFalse("Does not match",ex.matchesDynamically(null,null,new Object[]{a,b,aa}));
+       // // }
+       //
+       // public void testGetPointcutExpression() {
+       // PointcutExpression ex = p.parsePointcutExpression("staticinitialization(*..A+)");
+       // assertEquals("staticinitialization(*..A+)", ex.getPointcutExpression());
+       // }
+       //
+       // public void testCouldMatchJoinPointsInType() {
+       // PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))");
+       // assertTrue("Could maybe match String (as best we know at this point)", ex.couldMatchJoinPointsInType(String.class));
+       // assertTrue("Will always match B", ex.couldMatchJoinPointsInType(B.class));
+       // ex = p.parsePointcutExpression("within(org.aspectj.weaver.tools.PointcutExpressionTest.B)");
+       // assertFalse("Will never match String", ex.couldMatchJoinPointsInType(String.class));
+       // assertTrue("Will always match B", ex.couldMatchJoinPointsInType(B.class));
+       // }
+       //
+       // public void testMayNeedDynamicTest() {
+       // PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))");
+       // assertFalse("No dynamic test needed", ex.mayNeedDynamicTest());
+       // ex = p
+       // .parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..)) && args(org.aspectj.weaver.tools.PointcutExpressionTest.X)");
+       // assertTrue("Dynamic test needed", ex.mayNeedDynamicTest());
+       // }
+
+       // static class A {
+       // public A(String s) {
+       // }
+       //
+       // public void a() {
+       // }
+       //
+       // public void aa(int i) {
+       // }
+       //
+       // public void aaa(String s, int i) {
+       // }
+       //
+       // int x;
+       // }
+       //
+       // static class B extends A {
+       // public B() {
+       // super("");
+       // }
+       //
+       // public B(String s) {
+       // super(s);
+       // }
+       //
+       // public String b() {
+       // return null;
+       // }
+       //
+       // public void aa(int i) {
+       // }
+       //
+       // int y;
+       // }
+       //
+       // static class Client {
+       // public Client() {
+       // }
+       //
+       // Number n;
+       //
+       // public void foo(String s, int i, Number n) {
+       // }
+       //
+       // public void bar(String s, int i, Integer i2, Number n) {
+       // }
+       // }
+       //
+       // static class X {
+       // }
+
+       private ResolvedMember getMethod(ResolvedType type, String methodName, String methodSignature) {
+               ResolvedMember[] methods = type.getDeclaredMethods();
+               for (int i = 0; i < methods.length; i++) {
+                       if (methods[i].getName().equals(methodName)
+                                       && (methodSignature == null || methodSignature.equals(methods[i].getSignature()))) {
+                               return methods[i];
+                       }
+               }
+               return null;
+       }
+
+       private void checkAlwaysMatches(String pointcutExpression, String type, String methodName, String methodSignature) {
+               StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression);
+               assertNotNull(ex);
+               ResolvedType resolvedType = world.resolve(type);
+               ResolvedMember method = getMethod(resolvedType, methodName, methodSignature);
+               assertNotNull(method);
+               boolean b = ex.matchesMethodExecution(method).alwaysMatches();
+               assertTrue(b);
+       }
+
+       private void checkNeverMatches(String pointcutExpression, String type, String methodName, String methodSignature) {
+               StandardPointcutExpression ex = pointcutParser.parsePointcutExpression(pointcutExpression);
+               assertNotNull(ex);
+               ResolvedType resolvedType = world.resolve(type);
+               ResolvedMember method = getMethod(resolvedType, methodName, methodSignature);
+               assertNotNull(method);
+               boolean b = ex.matchesMethodExecution(method).neverMatches();
+               assertTrue(b);
+       }
+}
diff --git a/org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/ReflectionWorldPointcutExpressionTests.java b/org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/ReflectionWorldPointcutExpressionTests.java
new file mode 100644 (file)
index 0000000..1a5f9be
--- /dev/null
@@ -0,0 +1,17 @@
+package org.aspectj.matcher.tools;
+
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.reflect.ReflectionWorld;
+
+/**
+ * Run all the pointcut parsing/matching tests against a ReflectionWorld.
+ * 
+ * @author Andy Clement
+ */
+public class ReflectionWorldPointcutExpressionTests extends CommonPointcutExpressionTests {
+
+       protected World getWorld() {
+               return new ReflectionWorld(true, getClass().getClassLoader());
+       }
+
+}
index acb04c03f9d8b1ffe419c2fac357bf272a3ba25c..5b646c5df18235d1721a2efad273fb08494dbe17 100644 (file)
@@ -17,6 +17,7 @@ import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
+import org.aspectj.matcher.tools.ReflectionWorldPointcutExpressionTests;
 import org.aspectj.weaver.patterns.PatternsTests;
 import org.aspectj.weaver.reflect.ReflectionWorldBasicTest;
 import org.aspectj.weaver.reflect.ReflectionWorldSpecificTest;
@@ -31,8 +32,8 @@ public class MatcherModuleTests extends TestCase {
                TestSuite suite = new TestSuite(MatcherModuleTests.class.getName());
                suite.addTestSuite(ReflectionWorldSpecificTest.class);
                suite.addTestSuite(ReflectionWorldBasicTest.class);
+               suite.addTestSuite(ReflectionWorldPointcutExpressionTests.class);
                suite.addTest(PatternsTests.suite());
                return suite;
        }
-
 }