From: aclement Date: Wed, 10 Dec 2008 05:00:55 +0000 (+0000) Subject: split weaving/matching: pointcut matching tests X-Git-Tag: V1_6_3rc1~28 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=44c40113a96fa4238c8f5dbed5242f8054a757ab;p=aspectj.git split weaving/matching: pointcut matching tests --- 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 index 000000000..2459366f0 --- /dev/null +++ b/org.aspectj.matcher/src/org/aspectj/weaver/internal/tools/StandardPointcutExpressionImpl.java @@ -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; + } + } +} diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java index 75929e7a1..4c714b90c 100644 --- a/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/org.aspectj.matcher/src/org/aspectj/weaver/patterns/PatternParser.java @@ -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 index 000000000..8e741b6c9 --- /dev/null +++ b/org.aspectj.matcher/src/org/aspectj/weaver/reflect/StandardShadow.java @@ -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("") ? 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 = 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, "", 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 index 000000000..3d5534944 --- /dev/null +++ b/org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutExpression.java @@ -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 may 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 index 000000000..eee063f0f --- /dev/null +++ b/org.aspectj.matcher/src/org/aspectj/weaver/tools/StandardPointcutParser.java @@ -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: + *
    + *
  • The if, cflow, and cflowbelow pointcut designators are not supported + *
  • Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts + *
  • The pointcut expression must be anonymous with no formals allowed. + *
+ *

+ * When resolving types in pointcut expressions, the context classloader is used to find types. + *

+ */ + 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: + *
    + *
  • The if, cflow, and cflowbelow pointcut designators are not supported + *
  • Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts + *
  • The pointcut expression must be anonymous with no formals allowed. + *
+ *

+ * When resolving types in pointcut expressions, the given classloader is used to find types. + *

+ * + * @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: + *
    + *
  • The if, cflow, and cflowbelow pointcut designators are not supported + *
  • Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts + *
  • The pointcut expression must be anonymous with no formals allowed. + *
+ */ + 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: + *
    + *
  • The if, cflow, and cflowbelow pointcut designators are not supported + *
  • Pointcut expressions must be self-contained :- they cannot contain references to other named pointcuts + *
  • The pointcut expression must be anonymous with no formals allowed. + *
+ * + * @param supportedPointcutKinds a set of PointcutPrimitives this parser should support + * @throws UnsupportedOperationException if the set contains if, cflow, or cflow below + */ + private StandardPointcutParser(Set/* */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 index 000000000..26e0e0b5c --- /dev/null +++ b/org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/CommonPointcutExpressionTests.java @@ -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 index 000000000..1a5f9be43 --- /dev/null +++ b/org.aspectj.matcher/testsrc/org/aspectj/matcher/tools/ReflectionWorldPointcutExpressionTests.java @@ -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()); + } + +} diff --git a/org.aspectj.matcher/testsrc/org/aspectj/weaver/MatcherModuleTests.java b/org.aspectj.matcher/testsrc/org/aspectj/weaver/MatcherModuleTests.java index acb04c03f..5b646c5df 100644 --- a/org.aspectj.matcher/testsrc/org/aspectj/weaver/MatcherModuleTests.java +++ b/org.aspectj.matcher/testsrc/org/aspectj/weaver/MatcherModuleTests.java @@ -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; } - }