diff options
author | acolyer <acolyer> | 2005-09-21 14:59:55 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2005-09-21 14:59:55 +0000 |
commit | a39f595c0cdcddf8eac0b99e1918d0578f2dc501 (patch) | |
tree | 94865da1d5f277582d9d0720347693cd3b3c258a /weaver | |
parent | fc2d08e2ae9d03fb377bd0ed0bd56983af4687a5 (diff) | |
download | aspectj-a39f595c0cdcddf8eac0b99e1918d0578f2dc501.tar.gz aspectj-a39f595c0cdcddf8eac0b99e1918d0578f2dc501.zip |
tests and implementation for 108120 - runtime pointcut parsing and matching.
Diffstat (limited to 'weaver')
74 files changed, 3610 insertions, 2483 deletions
diff --git a/weaver/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java new file mode 100644 index 000000000..31abe3056 --- /dev/null +++ b/weaver/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java @@ -0,0 +1,152 @@ +/* ******************************************************************* + * 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.annotation.Annotation; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.Repository; +import org.aspectj.apache.bcel.util.ClassLoaderRepository; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; + +/** + * Find the given annotation (if present) on the given object + * + */ +public class Java15AnnotationFinder implements AnnotationFinder { + + private Repository bcelRepository; + + public Java15AnnotationFinder() { + this.bcelRepository = new ClassLoaderRepository(getClass().getClassLoader()); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.reflect.AnnotationFinder#getAnnotation(org.aspectj.weaver.ResolvedType, java.lang.Object) + */ + public Object getAnnotation(ResolvedType annotationType, Object onObject) { + try { + Class annotationClass = Class.forName(annotationType.getName()); + if (onObject.getClass().isAnnotationPresent(annotationClass)) { + return onObject.getClass().getAnnotation(annotationClass); + } + } catch (ClassNotFoundException ex) { + // just return null + } + return null; + } + + public Object getAnnotationFromClass(ResolvedType annotationType, Class aClass) { + try { + Class annotationClass = Class.forName(annotationType.getName()); + if (aClass.isAnnotationPresent(annotationClass)) { + return aClass.getAnnotation(annotationClass); + } + } catch (ClassNotFoundException ex) { + // just return null + } + return null; + } + + public Object getAnnotationFromMember(ResolvedType annotationType, Member aMember) { + if (!(aMember instanceof AccessibleObject)) return null; + AccessibleObject ao = (AccessibleObject) aMember; + try { + Class annotationClass = Class.forName(annotationType.getName()); + if (ao.isAnnotationPresent(annotationClass)) { + return ao.getAnnotation(annotationClass); + } + } catch (ClassNotFoundException ex) { + // just return null + } + return null; + } + + public Set getAnnotations(Member onMember) { + if (!(onMember instanceof AccessibleObject)) return Collections.EMPTY_SET; + // here we really want both the runtime visible AND the class visible annotations + // so we bail out to Bcel and then chuck away the JavaClass so that we don't hog + // memory. + try { + JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); + org.aspectj.apache.bcel.classfile.annotation.Annotation[] anns = new org.aspectj.apache.bcel.classfile.annotation.Annotation[0]; + if (onMember instanceof Method) { + org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method)onMember); + anns = bcelMethod.getAnnotations(); + } else if (onMember instanceof Constructor) { + org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor)onMember); + anns = bcelCons.getAnnotations(); + } else if (onMember instanceof Field) { + org.aspectj.apache.bcel.classfile.Field bcelField = jc.getField((Field)onMember); + anns = bcelField.getAnnotations(); + } + // the answer is cached and we don't want to hold on to memory + bcelRepository.clear(); + if (anns == null) anns = new org.aspectj.apache.bcel.classfile.annotation.Annotation[0]; + // convert to our Annotation type + Set<UnresolvedType> annSet = new HashSet<UnresolvedType>(); + for (int i = 0; i < anns.length; i++) { + annSet.add(UnresolvedType.forName(anns[i].getTypeName())); + } + return annSet; + } catch (ClassNotFoundException cnfEx) { + // just use reflection then + } + + + AccessibleObject ao = (AccessibleObject) onMember; + Annotation[] anns = ao.getDeclaredAnnotations(); + Set<UnresolvedType> annSet = new HashSet<UnresolvedType>(); + for (int i = 0; i < anns.length; i++) { + annSet.add(UnresolvedType.forName(anns[i].annotationType().getName())); + } + return annSet; + } + + public ResolvedType[] getAnnotations(Class forClass, World inWorld) { + // here we really want both the runtime visible AND the class visible annotations + // so we bail out to Bcel and then chuck away the JavaClass so that we don't hog + // memory. + try { + JavaClass jc = bcelRepository.loadClass(forClass); + org.aspectj.apache.bcel.classfile.annotation.Annotation[] anns =jc.getAnnotations(); + bcelRepository.clear(); + if (anns == null) return new ResolvedType[0]; + ResolvedType[] ret = new ResolvedType[anns.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = inWorld.resolve(anns[i].getTypeName()); + } + return ret; + } catch (ClassNotFoundException cnfEx) { + // just use reflection then + } + + Annotation[] classAnnotations = forClass.getAnnotations(); + ResolvedType[] ret = new ResolvedType[classAnnotations.length]; + for (int i = 0; i < classAnnotations.length; i++) { + ret[i] = inWorld.resolve(classAnnotations[i].annotationType().getName()); + } + + return ret; + } + +} diff --git a/weaver/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java b/weaver/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java new file mode 100644 index 000000000..5e6f111fe --- /dev/null +++ b/weaver/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java @@ -0,0 +1,314 @@ +/* ******************************************************************* + * 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.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.AjType; +import org.aspectj.lang.reflect.AjTypeSystem; +import org.aspectj.lang.reflect.Pointcut; +import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.BoundedReferenceType; +import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedPointcutDefinition; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.TypeFactory; +import org.aspectj.weaver.TypeVariable; +import org.aspectj.weaver.TypeVariableReferenceType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; +import org.aspectj.weaver.UnresolvedType.TypeKind; +import org.aspectj.weaver.internal.tools.PointcutExpressionImpl; +import org.aspectj.weaver.patterns.PatternParser; +import org.aspectj.weaver.tools.PointcutExpression; +import org.aspectj.weaver.tools.PointcutParameter; +import org.aspectj.weaver.tools.PointcutParser; + +/** + * @author colyer + * Provides Java 5 behaviour in reflection based delegates (overriding + * 1.4 behaviour from superclass where appropriate) + */ +public class Java15ReflectionBasedReferenceTypeDelegate extends + ReflectionBasedReferenceTypeDelegate { + + private AjType myType; + private ResolvedType[] annotations; + private ResolvedMember[] pointcuts; + private ResolvedMember[] methods; + private ResolvedMember[] fields; + private TypeVariable[] typeVariables; + private ResolvedType superclass; + private ResolvedType[] superInterfaces; + private String genericSignature = null; + private Java15AnnotationFinder annotationFinder = new Java15AnnotationFinder(); + + + public Java15ReflectionBasedReferenceTypeDelegate() {} + + public void initialize(ReferenceType aType, Class aClass, World aWorld) { + super.initialize(aType, aClass, aWorld); + myType = AjTypeSystem.getAjType(aClass); + } + + + public ReferenceType buildGenericType() { + return (ReferenceType) UnresolvedType.forGenericTypeVariables( + getResolvedTypeX().getSignature(), + getTypeVariables()).resolve(getWorld()); + } + + public AnnotationX[] getAnnotations() { + // AMC - we seem not to need to implement this method... + throw new UnsupportedOperationException("getAnnotations on Java15ReflectionBasedReferenceTypeDelegate is not implemented yet"); + //return super.getAnnotations(); + } + + public ResolvedType[] getAnnotationTypes() { + if (annotations == null) { + annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); + } + return annotations; + } + + public boolean hasAnnotation(UnresolvedType ofType) { + ResolvedType[] myAnns = getAnnotationTypes(); + ResolvedType toLookFor = ofType.resolve(getWorld()); + for (int i = 0; i < myAnns.length; i++) { + if (myAnns[i] == toLookFor) return true; + } + return false; + } + + // use the MAP to ensure that any aj-synthetic fields are filtered out + public ResolvedMember[] getDeclaredFields() { + if (fields == null) { + Field[] reflectFields = this.myType.getDeclaredFields(); + this.fields = new ResolvedMember[reflectFields.length]; + for (int i = 0; i < reflectFields.length; i++) { + this.fields[i] = createGenericFieldMember(reflectFields[i]); + } + } + return fields; + } + + public String getDeclaredGenericSignature() { + if (this.genericSignature == null && isGeneric()) { + + } + return genericSignature; + } + + public ResolvedType[] getDeclaredInterfaces() { + if (superInterfaces == null) { + Type[] genericInterfaces = getBaseClass().getGenericInterfaces(); + this.superInterfaces = fromTypes(genericInterfaces); + } + return superInterfaces; + } + + public ResolvedType getSuperclass() { + if (superclass == null) + superclass = fromType(this.getBaseClass().getGenericSuperclass()); + return superclass; + } + + public TypeVariable[] getTypeVariables() { + if (this.typeVariables == null) { + java.lang.reflect.TypeVariable[] tVars = this.getBaseClass().getTypeParameters(); + this.typeVariables = new TypeVariable[tVars.length]; + for (int i = 0; i < tVars.length; i++) { + this.typeVariables[i] = ((TypeVariableReferenceType) fromType(tVars[i])).getTypeVariable(); + } + } + return this.typeVariables; + } + + // overrides super method since by using the MAP we can filter out advice + // methods that really shouldn't be seen in this list + public ResolvedMember[] getDeclaredMethods() { + if (methods == null) { + Method[] reflectMethods = this.myType.getDeclaredMethods(); + Constructor[] reflectCons = this.myType.getDeclaredConstructors(); + this.methods = new ResolvedMember[reflectMethods.length + reflectCons.length]; + for (int i = 0; i < reflectMethods.length; i++) { + this.methods[i] = createGenericMethodMember(reflectMethods[i]); + } + for (int i = 0; i < reflectCons.length; i++) { + this.methods[i + reflectMethods.length] = + createGenericConstructorMember(reflectCons[i]); + } + } + return methods; + } + + private ResolvedMember createGenericMethodMember(Method forMethod) { + ReflectionBasedResolvedMemberImpl ret = + new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, + getResolvedTypeX(), + forMethod.getModifiers(), + fromType(forMethod.getGenericReturnType()), + forMethod.getName(), + fromTypes(forMethod.getGenericParameterTypes()), + fromTypes(forMethod.getGenericExceptionTypes()), + forMethod + ); + return ret; + } + + private ResolvedMember createGenericConstructorMember(Constructor forConstructor) { + ReflectionBasedResolvedMemberImpl ret = + new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, + getResolvedTypeX(), + forConstructor.getModifiers(), + getResolvedTypeX(), + "init", + fromTypes(forConstructor.getGenericParameterTypes()), + fromTypes(forConstructor.getGenericExceptionTypes()), + forConstructor + ); + return ret; + } + + private ResolvedMember createGenericFieldMember(Field forField) { + return new ReflectionBasedResolvedMemberImpl( + org.aspectj.weaver.Member.FIELD, + getResolvedTypeX(), + forField.getModifiers(), + fromType(forField.getGenericType()), + forField.getName(), + new UnresolvedType[0], + forField); + } + + public ResolvedMember[] getDeclaredPointcuts() { + if (pointcuts == null) { + Pointcut[] pcs = this.myType.getDeclaredPointcuts(); + pointcuts = new ResolvedMember[pcs.length]; + PointcutParser parser = new PointcutParser(); + for (int i = 0; i < pcs.length; i++) { + Class[] ptypes = pcs[i].getParameterTypes(); + String[] pnames = pcs[i].getParameterNames(); + if (pnames.length != ptypes.length) { + throw new IllegalStateException("Required parameter names not available when parsing pointcut " + pcs[i].getName() + " in type " + getResolvedTypeX().getName()); + } + PointcutParameter[] parameters = new PointcutParameter[ptypes.length]; + for (int j = 0; j < parameters.length; j++) { + parameters[j] = parser.createPointcutParameter(pnames[j],ptypes[j]); + } + String pcExpr = pcs[i].getPointcutExpression().toString(); + PointcutExpressionImpl pEx = (PointcutExpressionImpl) parser.parsePointcutExpression(pcExpr,getBaseClass(),parameters); + org.aspectj.weaver.patterns.Pointcut pc = pEx.getUnderlyingPointcut(); + UnresolvedType[] weaverPTypes = new UnresolvedType[ptypes.length]; + for (int j = 0; j < weaverPTypes.length; j++) { + weaverPTypes[j] = UnresolvedType.forName(ptypes[j].getName()); + } + pointcuts[i] = new ResolvedPointcutDefinition(getResolvedTypeX(),pcs[i].getModifiers(),pcs[i].getName(),weaverPTypes,pc); + } + } + return pointcuts; + } + + public boolean isAnnotation() { + return getBaseClass().isAnnotation(); + } + + public boolean isAnnotationStyleAspect() { + return getBaseClass().isAnnotationPresent(Aspect.class); + } + + public boolean isAnnotationWithRuntimeRetention() { + if (!isAnnotation()) return false; + if (getBaseClass().isAnnotationPresent(Retention.class)) { + Retention retention = (Retention) getBaseClass().getAnnotation(Retention.class); + RetentionPolicy policy = retention.value(); + return policy == RetentionPolicy.RUNTIME; + } else { + return false; + } + } + + public boolean isAspect() { + return this.myType.isAspect(); + } + + public boolean isEnum() { + return getBaseClass().isEnum(); + } + + public boolean isGeneric() { + //return false; // for now + return getBaseClass().getTypeParameters().length > 0; + } + + private ResolvedType fromType(Type aType) { + if (aType instanceof Class) { + return getWorld().resolve(((Class)aType).getName()); + } else if (aType instanceof ParameterizedType) { + ParameterizedType pt = (ParameterizedType) aType; + ResolvedType baseType = fromType(pt.getRawType()); + Type[] args = pt.getActualTypeArguments(); + ResolvedType[] resolvedArgs = fromTypes(args); + return TypeFactory.createParameterizedType(baseType, resolvedArgs, getWorld()); + } else if (aType instanceof java.lang.reflect.TypeVariable) { + java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) aType; + Type[] bounds = tv.getBounds(); + ResolvedType[] resBounds = fromTypes(bounds); + ResolvedType upperBound = resBounds[0]; + ResolvedType[] additionalBounds = new ResolvedType[0]; + if (resBounds.length > 1) { + additionalBounds = new ResolvedType[resBounds.length - 1]; + System.arraycopy(resBounds,1,additionalBounds,0,additionalBounds.length); + } + TypeVariable rt_tv = new TypeVariable(tv.getName(),upperBound,additionalBounds); + return new TypeVariableReferenceType(rt_tv,getWorld()); + } else if (aType instanceof WildcardType) { + WildcardType wildType = (WildcardType) aType; + Type[] lowerBounds = wildType.getLowerBounds(); + Type[] upperBounds = wildType.getUpperBounds(); + ResolvedType bound = null; + boolean isExtends = lowerBounds.length == 0; + if (isExtends) { + bound = fromType(upperBounds[0]); + } else { + bound = fromType(lowerBounds[0]); + } + return new BoundedReferenceType((ReferenceType)bound,isExtends,getWorld()); + } else if (aType instanceof GenericArrayType) { + GenericArrayType gt = (GenericArrayType) aType; + Type componentType = gt.getGenericComponentType(); + UnresolvedType.makeArray(fromType(componentType),1); + } + return ResolvedType.MISSING; + } + + private ResolvedType[] fromTypes(Type[] types) { + ResolvedType[] ret = new ResolvedType[types.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = fromType(types[i]); + } + return ret; + } + +} + diff --git a/weaver/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java b/weaver/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java new file mode 100644 index 000000000..10651dc90 --- /dev/null +++ b/weaver/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java @@ -0,0 +1,270 @@ +/* ******************************************************************* + * 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.tools; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Method; + +import org.aspectj.lang.annotation.Pointcut; + +import junit.framework.TestCase; + +/** + * @author colyer + * + */ +public class Java15PointcutExpressionTest extends TestCase { + + private PointcutParser parser; + private Method a; + private Method b; + private Method c; + + public void testAtThis() { + PointcutExpression atThis = parser.parsePointcutExpression("@this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); + ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); + assertTrue("matches",jp2.matches()); + } + + public void testAtTarget() { + PointcutExpression atTarget = parser.parsePointcutExpression("@target(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atTarget.matchesMethodExecution(a); + ShadowMatch sMatch2 = atTarget.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); + assertTrue("matches",jp2.matches()); + } + + public void testAtThisWithBinding() { + PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class); + B myB = new B(); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + PointcutExpression atThis = parser.parsePointcutExpression("@this(a)",A.class,new PointcutParameter[] {param}); + ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); + ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]); + assertTrue("matches",jp2.matches()); + assertEquals(1,jp2.getParameterBindings().length); + assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + } + + public void testAtTargetWithBinding() { + PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class); + B myB = new B(); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + PointcutExpression atThis = parser.parsePointcutExpression("@target(a)",A.class,new PointcutParameter[] {param}); + ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); + ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]); + assertTrue("matches",jp2.matches()); + assertEquals(1,jp2.getParameterBindings().length); + assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + } + + public void testAtArgs() { + PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atArgs.matchesMethodExecution(a); + ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("never matches A",sMatch1.neverMatches()); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()}); + assertTrue("matches",jp2.matches()); + + atArgs = parser.parsePointcutExpression("@args(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + sMatch1 = atArgs.matchesMethodExecution(a); + sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("never matches A",sMatch1.neverMatches()); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch2.matchesJoinPoint(new A(), new A(), new Object[] {new A(), new B()}); + assertFalse("does not match",jp1.matches()); + jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()}); + assertTrue("matches",jp2.matches()); + } + + public void testAtArgsWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("a",MyAnnotation.class); + PointcutParameter p2 = parser.createPointcutParameter("b", MyAnnotation.class); + PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,a)",A.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()}); + assertTrue("matches",jp2.matches()); + assertEquals(1,jp2.getParameterBindings().length); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + + atArgs = parser.parsePointcutExpression("@args(a,b)",A.class,new PointcutParameter[] {p1,p2}); + sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()}); + assertTrue("matches",jp2.matches()); + assertEquals(2,jp2.getParameterBindings().length); + assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[1].getBinding()); + } + + public void testAtWithin() { + PointcutExpression atWithin = parser.parsePointcutExpression("@within(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a); + ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b); + assertTrue("does not match a",sMatch1.neverMatches()); + assertTrue("matches b",sMatch2.alwaysMatches()); + } + + public void testAtWithinWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); + PointcutExpression atWithin = parser.parsePointcutExpression("@within(x)",B.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a); + ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b); + assertTrue("does not match a",sMatch1.neverMatches()); + assertTrue("matches b",sMatch2.alwaysMatches()); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); + assertTrue(jpm.matches()); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + assertEquals("annotation on B",bAnnotation,jpm.getParameterBindings()[0].getBinding()); + } + + public void testAtWithinCode() { + PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atWithinCode.matchesMethodCall(a,b); + ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a); + assertTrue("does not match from b",sMatch1.neverMatches()); + assertTrue("matches from a",sMatch2.alwaysMatches()); + } + + public void testAtWithinCodeWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); + PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(x)",A.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a); + assertTrue("matches from a",sMatch2.alwaysMatches()); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation annOna = a.getAnnotation(MyAnnotation.class); + assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding()); + } + + public void testAtAnnotation() { + PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atAnnotation.matchesMethodCall(b,a); + ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a); + assertTrue("does not match call to b",sMatch1.neverMatches()); + assertTrue("matches call to a",sMatch2.alwaysMatches()); + } + + public void testAtAnnotationWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); + PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(x)",A.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a); + assertTrue("matches call to a",sMatch2.alwaysMatches()); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]); + assertTrue(jpm.matches()); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation annOna = a.getAnnotation(MyAnnotation.class); + assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding()); + } + + public void testReferencePointcutNoParams() { + PointcutExpression pc = parser.parsePointcutExpression("foo()",C.class,new PointcutParameter[0]); + ShadowMatch sMatch1 = pc.matchesMethodCall(a,b); + ShadowMatch sMatch2 = pc.matchesMethodExecution(a); + assertTrue("no match on call",sMatch1.neverMatches()); + assertTrue("match on execution",sMatch2.alwaysMatches()); + + pc = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.C.foo()"); + sMatch1 = pc.matchesMethodCall(a,b); + sMatch2 = pc.matchesMethodExecution(a); + assertTrue("no match on call",sMatch1.neverMatches()); + assertTrue("match on execution",sMatch2.alwaysMatches()); + } + + public void testReferencePointcutParams() { + PointcutParameter p1 = parser.createPointcutParameter("x",A.class); + PointcutExpression pc = parser.parsePointcutExpression("goo(x)",C.class,new PointcutParameter[] {p1}); + + ShadowMatch sMatch1 = pc.matchesMethodCall(a,b); + ShadowMatch sMatch2 = pc.matchesMethodExecution(a); + assertTrue("no match on call",sMatch1.neverMatches()); + assertTrue("match on execution",sMatch2.maybeMatches()); + A anA = new A(); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(anA, new A(), new Object[0]); + assertTrue(jpm.matches()); + assertEquals("should be bound to anA",anA,jpm.getParameterBindings()[0].getBinding()); + + } + + public void testExecutionWithClassFileRetentionAnnotation() { + PointcutExpression pc1 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation * *(..))"); + PointcutExpression pc2 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyClassFileRetentionAnnotation * *(..))"); + ShadowMatch sMatch = pc1.matchesMethodExecution(a); + assertTrue("matches",sMatch.alwaysMatches()); + sMatch = pc2.matchesMethodExecution(a); + assertTrue("no match",sMatch.neverMatches()); + sMatch = pc1.matchesMethodExecution(b); + assertTrue("no match",sMatch.neverMatches()); + sMatch = pc2.matchesMethodExecution(b); + assertTrue("matches",sMatch.alwaysMatches()); + } + + protected void setUp() throws Exception { + super.setUp(); + parser = new PointcutParser(); + a = A.class.getMethod("a"); + b = B.class.getMethod("b"); + c = B.class.getMethod("c",new Class[] {A.class,B.class}); + } + + @Retention(RetentionPolicy.RUNTIME) + private @interface MyAnnotation {} + + private @interface MyClassFileRetentionAnnotation {} + + private static class A { + @MyAnnotation public void a() {} + } + + @MyAnnotation + private static class B { + @MyClassFileRetentionAnnotation public void b() {} + public void c(A anA, B aB) {} + } + + private static class C { + + @Pointcut("execution(* *(..))") + public void foo() {} + + @Pointcut(value="execution(* *(..)) && this(x)", argNames="x") + public void goo(A x) {} + } + +} + + diff --git a/weaver/src/org/aspectj/weaver/Shadow.java b/weaver/src/org/aspectj/weaver/Shadow.java index c31dfbf46..a245c173e 100644 --- a/weaver/src/org/aspectj/weaver/Shadow.java +++ b/weaver/src/org/aspectj/weaver/Shadow.java @@ -16,6 +16,7 @@ package org.aspectj.weaver; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -242,11 +243,13 @@ public abstract class Shadow { AdviceExecution, Initialization, ExceptionHandler, }; - public static final Set ALL_SHADOW_KINDS = new HashSet(); + public static final Set ALL_SHADOW_KINDS; static { + HashSet aSet = new HashSet(); for (int i = 0; i < SHADOW_KINDS.length; i++) { - ALL_SHADOW_KINDS.add(SHADOW_KINDS[i]); + aSet.add(SHADOW_KINDS[i]); } + ALL_SHADOW_KINDS = Collections.unmodifiableSet(aSet); } /** A type-safe enum representing the kind of shadows diff --git a/weaver/src/org/aspectj/weaver/UnresolvedType.java b/weaver/src/org/aspectj/weaver/UnresolvedType.java index 9948a4183..f6c8804ba 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedType.java @@ -351,6 +351,15 @@ public class UnresolvedType implements TypeVariableDeclaringElement { return ret; } + public static UnresolvedType forGenericTypeVariables(String sig, TypeVariable[] tVars) { + UnresolvedType ret = UnresolvedType.forSignature(sig); + ret.typeKind=TypeKind.GENERIC; + ret.typeVariables = tVars; + ret.signatureErasure = sig; + ret.signature = ret.signatureErasure; + return ret; + } + public static UnresolvedType forRawTypeName(String name) { UnresolvedType ret = UnresolvedType.forName(name); ret.typeKind = TypeKind.RAW; diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 87d021bf1..d7a2533e9 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -285,8 +285,7 @@ public abstract class World implements Dump.INode { if (delegate.isGeneric() && behaveInJava5Way) { // ======== raw type =========== simpleOrRawType.typeKind = TypeKind.RAW; - ReferenceType genericType = new ReferenceType( - UnresolvedType.forGenericTypeSignature(erasedSignature,delegate.getDeclaredGenericSignature()),this); + ReferenceType genericType = makeGenericTypeFrom(delegate,simpleOrRawType); // name = ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(ty.getName()),this); simpleOrRawType.setDelegate(delegate); genericType.setDelegate(delegate); @@ -334,14 +333,24 @@ public abstract class World implements Dump.INode { } else { // Fault in the generic that underpins the raw type ;) ReferenceTypeDelegate delegate = resolveDelegate((ReferenceType)rawType); - ReferenceType genericRefType = new ReferenceType( - UnresolvedType.forGenericTypeSignature(rawType.getSignature(),delegate.getDeclaredGenericSignature()),this); + ReferenceType genericRefType = makeGenericTypeFrom(delegate,((ReferenceType)rawType)); ((ReferenceType)rawType).setGenericType(genericRefType); genericRefType.setDelegate(delegate); ((ReferenceType)rawType).setDelegate(delegate); return genericRefType; } } + + private ReferenceType makeGenericTypeFrom(ReferenceTypeDelegate delegate, ReferenceType rawType) { + String genericSig = delegate.getDeclaredGenericSignature(); + if (genericSig != null) { + return new ReferenceType( + UnresolvedType.forGenericTypeSignature(rawType.getSignature(),delegate.getDeclaredGenericSignature()),this); + } else { + return new ReferenceType( + UnresolvedType.forGenericTypeVariables(rawType.getSignature(), delegate.getTypeVariables()),this); + } + } /** * Go from an unresolved generic wildcard (represented by UnresolvedType) to a resolved version (BoundedReferenceType). diff --git a/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java b/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java index f1e7aa50f..fd0558cd8 100644 --- a/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java +++ b/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java @@ -14,35 +14,52 @@ import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; -import org.aspectj.lang.JoinPoint; +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.ArgsAnnotationPointcut; import org.aspectj.weaver.patterns.ArgsPointcut; import org.aspectj.weaver.patterns.CflowPointcut; +import org.aspectj.weaver.patterns.ExposedState; +import org.aspectj.weaver.patterns.FastMatchInfo; 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.tools.FuzzyBoolean; +import org.aspectj.weaver.reflect.ReflectionShadow; +import org.aspectj.weaver.reflect.ShadowMatchImpl; import org.aspectj.weaver.tools.PointcutExpression; +import org.aspectj.weaver.tools.PointcutParameter; +import org.aspectj.weaver.tools.ShadowMatch; /** * Map from weaver.tools interface to internal Pointcut implementation... */ public class PointcutExpressionImpl implements PointcutExpression { + private World world; private Pointcut pointcut; private String expression; + private PointcutParameter[] parameters; - public PointcutExpressionImpl(Pointcut pointcut, String expression) { + public PointcutExpressionImpl(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; } public boolean couldMatchJoinPointsInType(Class aClass) { - return pointcut.fastMatch(aClass).maybeTrue(); + return pointcut.fastMatch(new FastMatchInfo(world.resolve(aClass.getName()),null)).maybeTrue(); } public boolean mayNeedDynamicTest() { @@ -50,152 +67,162 @@ public class PointcutExpressionImpl implements PointcutExpression { pointcut.traverse(visitor, null); return visitor.hasDynamicContent(); } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesMethodCall(java.lang.reflect.Method, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesMethodCall(Method aMethod, Class thisClass, - Class targetClass, Member withinCode) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.METHOD_CALL, - aMethod, - thisClass, - targetClass, - withinCode)); + + private ExposedState getExposedState() { + return new ExposedState(parameters.length); } - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesMethodExecution(java.lang.reflect.Method, java.lang.Class) - */ - public FuzzyBoolean matchesMethodExecution(Method aMethod, Class thisClass) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.METHOD_EXECUTION, - aMethod, - thisClass, - thisClass, - null)); + public ShadowMatch matchesMethodExecution(Method aMethod) { + return matchesExecution(aMethod); } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesConstructorCall(java.lang.reflect.Constructor, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesConstructorCall(Constructor aConstructor, - Class thisClass, Member withinCode) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.CONSTRUCTOR_CALL, - aConstructor, - thisClass, - aConstructor.getDeclaringClass(), - withinCode)); + + public ShadowMatch matchesConstructorExecution(Constructor aConstructor) { + return matchesExecution(aConstructor); } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesConstructorExecution(java.lang.reflect.Constructor) - */ - public FuzzyBoolean matchesConstructorExecution(Constructor aConstructor, Class thisClass) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.CONSTRUCTOR_EXECUTION, - aConstructor, - thisClass, - thisClass, - null)); + + private ShadowMatch matchesExecution(Member aMember) { + Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aMember); + sm.setWithinCode(null); + sm.setWithinType(aMember.getDeclaringClass()); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesAdviceExecution(java.lang.reflect.Method, java.lang.Class) - */ - public FuzzyBoolean matchesAdviceExecution(Method anAdviceMethod, - Class thisClass) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.ADVICE_EXECUTION, - anAdviceMethod, - thisClass, - thisClass, - null)); + + public ShadowMatch matchesStaticInitialization(Class aClass) { + Shadow s = ReflectionShadow.makeStaticInitializationShadow(world, aClass); + 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); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aMethod); + sm.setWithinCode(null); + sm.setWithinType(aMethod.getDeclaringClass()); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesHandler(java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesHandler(Class exceptionType, Class inClass, - Member withinCode) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.EXCEPTION_HANDLER, - new Handler(inClass,exceptionType), - inClass, - inClass, - withinCode)); + + public ShadowMatch matchesInitialization(Constructor aConstructor) { + Shadow s = ReflectionShadow.makeInitializationShadow(world, aConstructor); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aConstructor); + sm.setWithinCode(null); + sm.setWithinType(aConstructor.getDeclaringClass()); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesInitialization(java.lang.reflect.Constructor) - */ - public FuzzyBoolean matchesInitialization(Constructor aConstructor) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.INITIALIZATION, - aConstructor, - aConstructor.getDeclaringClass(), - aConstructor.getDeclaringClass(), - null)); + + public ShadowMatch matchesPreInitialization(Constructor aConstructor) { + Shadow s = ReflectionShadow.makePreInitializationShadow(world, aConstructor); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aConstructor); + sm.setWithinCode(null); + sm.setWithinType(aConstructor.getDeclaringClass()); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesPreInitialization(java.lang.reflect.Constructor) - */ - public FuzzyBoolean matchesPreInitialization(Constructor aConstructor) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.PREINTIALIZATION, - aConstructor, - aConstructor.getDeclaringClass(), - aConstructor.getDeclaringClass(), - null)); + + public ShadowMatch matchesMethodCall(Method aMethod, Member withinCode) { + Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, withinCode); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aMethod); + sm.setWithinCode(withinCode); + sm.setWithinType(withinCode.getDeclaringClass()); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesStaticInitialization(java.lang.Class) - */ - public FuzzyBoolean matchesStaticInitialization(Class aClass) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.STATICINITIALIZATION, - null, - aClass, - aClass, - null - )); + + public ShadowMatch matchesMethodCall(Method aMethod, Class callerType) { + Shadow s = ReflectionShadow.makeCallShadow(world, aMethod, callerType); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aMethod); + sm.setWithinCode(null); + sm.setWithinType(callerType); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesFieldSet(java.lang.reflect.Field, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesFieldSet(Field aField, Class thisClass, - Class targetClass, Member withinCode) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.FIELD_SET, - aField, - thisClass, - targetClass, - withinCode)); + + public ShadowMatch matchesConstructorCall(Constructor aConstructor, Class callerType) { + Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor, callerType); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aConstructor); + sm.setWithinCode(null); + sm.setWithinType(callerType); + return sm; } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesFieldGet(java.lang.reflect.Field, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesFieldGet(Field aField, Class thisClass, - Class targetClass, Member withinCode) { - return fuzzyMatch(pointcut.matchesStatically( - JoinPoint.FIELD_GET, - aField, - thisClass, - targetClass, - withinCode)); + + public ShadowMatch matchesConstructorCall(Constructor aConstructor, Member withinCode) { + Shadow s = ReflectionShadow.makeCallShadow(world, aConstructor,withinCode); + ShadowMatchImpl sm = getShadowMatch(s); + sm.setSubject(aConstructor); + sm.setWithinCode(withinCode); + sm.setWithinType(withinCode.getDeclaringClass()); + return sm; } - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return pointcut.matchesDynamically(thisObject,targetObject,args); + public ShadowMatch matchesHandler(Class exceptionType, Class handlingType) { + Shadow s = ReflectionShadow.makeHandlerShadow(world,exceptionType,handlingType); + 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); + 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); + 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); + 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); + 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); + 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); + } + return new ShadowMatchImpl(match,residueTest,state,parameters); } /* (non-Javadoc) @@ -205,13 +232,6 @@ public class PointcutExpressionImpl implements PointcutExpression { return expression; } - private FuzzyBoolean fuzzyMatch(org.aspectj.util.FuzzyBoolean fb) { - if (fb == org.aspectj.util.FuzzyBoolean.YES) return FuzzyBoolean.YES; - if (fb == org.aspectj.util.FuzzyBoolean.NO) return FuzzyBoolean.NO; - if (fb == org.aspectj.util.FuzzyBoolean.MAYBE) return FuzzyBoolean.MAYBE; - throw new IllegalArgumentException("Cant match FuzzyBoolean " + fb); - } - private static class HasPossibleDynamicContentVisitor extends AbstractPatternNodeVisitor { private boolean hasDynamicContent = false; @@ -254,6 +274,7 @@ public class PointcutExpressionImpl implements PointcutExpression { hasDynamicContent = true; return null; } + } public static class Handler implements Member { diff --git a/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java b/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java index 3277d981f..0aa55e115 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java @@ -15,12 +15,10 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Member; import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.aspectj.lang.JoinPoint; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; @@ -53,44 +51,12 @@ public class AndPointcut extends Pointcut { return left.fastMatch(type).and(right.fastMatch(type)); } - public FuzzyBoolean fastMatch(Class targetType) { - return left.fastMatch(targetType).and(right.fastMatch(targetType)); - } - protected FuzzyBoolean matchInternal(Shadow shadow) { FuzzyBoolean leftMatch = left.match(shadow); if (leftMatch.alwaysFalse()) return leftMatch; return leftMatch.and(right.match(shadow)); } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) { - return left.match(jp,encJP).and(right.match(jp,encJP)); - } - - public FuzzyBoolean match(JoinPoint.StaticPart jpsp) { - return left.match(jpsp).and(right.match(jpsp)); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return left.matchesDynamically(thisObject,targetObject,args) && - right.matchesDynamically(thisObject,targetObject,args); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - return left.matchesStatically(joinpointKind,member,thisClass,targetClass,withinCode) - .and( - right.matchesStatically(joinpointKind,member,thisClass,targetClass,withinCode)); - } - public String toString() { return "(" + left.toString() + " && " + right.toString() + ")"; } @@ -112,11 +78,6 @@ public class AndPointcut extends Pointcut { left.resolveBindings(scope, bindings); right.resolveBindings(scope, bindings); } - - public void resolveBindingsFromRTTI() { - left.resolveBindingsFromRTTI(); - right.resolveBindingsFromRTTI(); - } public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.AND); diff --git a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java index e3d4d3d86..245d5c88d 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java @@ -55,20 +55,6 @@ public class AndTypePattern extends TypePattern { protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { return left.matchesExactly(type,annotatedType) && right.matchesExactly(type,annotatedType); } - - - public boolean matchesStatically(Class type) { - return left.matchesStatically(type) && right.matchesStatically(type); - } - - public FuzzyBoolean matchesInstanceof(Class type) { - return left.matchesInstanceof(type).and(right.matchesInstanceof(type)); - } - - protected boolean matchesExactly(Class type) { - //??? if these had side-effects, this sort-circuit could be a mistake - return left.matchesExactly(type) && right.matchesExactly(type); - } public boolean matchesStatically(ResolvedType type) { return left.matchesStatically(type) && right.matchesStatically(type); @@ -129,13 +115,6 @@ public class AndTypePattern extends TypePattern { return ret; } - public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) { - if (requireExactType) return TypePattern.NO; - left = left.resolveBindingsFromRTTI(allowBinding,requireExactType); - right = right.resolveBindingsFromRTTI(allowBinding,requireExactType); - return this; - } - public String toString() { StringBuffer buff = new StringBuffer(); if (annotationPattern != AnnotationTypePattern.ANY) { diff --git a/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java index 6dd2f65df..cc1ae7d70 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java @@ -93,11 +93,6 @@ public class AnnotationPointcut extends NameBindingPointcut { } } - public FuzzyBoolean fastMatch(Class targetType) { - // TODO AMC - return FuzzyBoolean.MAYBE; - } - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -164,14 +159,6 @@ public class AnnotationPointcut extends NameBindingPointcut { } /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI() - */ - protected void resolveBindingsFromRTTI() { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap) */ protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java index 7dc86e166..04a89d80a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java @@ -47,6 +47,7 @@ public class ArgsAnnotationPointcut extends NameBindingPointcut { public ArgsAnnotationPointcut(AnnotationPatternList arguments) { super(); this.arguments = arguments; + this.pointcutKind = ATARGS; } public AnnotationPatternList getArguments() { @@ -64,10 +65,6 @@ public class ArgsAnnotationPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -90,13 +87,6 @@ public class ArgsAnnotationPointcut extends NameBindingPointcut { } /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI() - */ - protected void resolveBindingsFromRTTI() { - // TODO Auto-generated method stub - } - - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap) */ protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { @@ -154,7 +144,10 @@ public class ArgsAnnotationPointcut extends NameBindingPointcut { } if (!ap.matches(rArgType).alwaysTrue()) { // we need a test... - ret = Test.makeAnd(ret,Test.makeHasAnnotation(shadow.getArgVar(argsIndex),rAnnType)); + ret = Test.makeAnd(ret, + Test.makeHasAnnotation( + shadow.getArgVar(argsIndex), + rAnnType)); } argsIndex++; } diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java index 0dcc59630..c39a83858 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java @@ -15,10 +15,6 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -29,8 +25,6 @@ import java.util.Set; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.reflect.CodeSignature; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.BetaException; import org.aspectj.weaver.ISourceContext; @@ -43,7 +37,6 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; -import org.aspectj.weaver.internal.tools.PointcutExpressionImpl; /** * args(arguments) @@ -74,10 +67,6 @@ public class ArgsPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - protected FuzzyBoolean matchInternal(Shadow shadow) { ResolvedType[] argumentsToMatchAgainst = getArgumentsToMatchAgainst(shadow); FuzzyBoolean ret = @@ -120,19 +109,6 @@ public class ArgsPointcut extends NameBindingPointcut { return argumentsToMatchAgainst; } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) { - FuzzyBoolean ret = arguments.matches(jp.getArgs(),TypePattern.DYNAMIC); - // this may have given a false match (e.g. args(int) may have matched a call to doIt(Integer x)) due to boxing - // check for this... - if (ret == FuzzyBoolean.YES) { - // are the sigs compatible too... - CodeSignature sig = (CodeSignature)jp.getSignature(); - Class[] pTypes = sig.getParameterTypes(); - ret = checkSignatureMatch(pTypes); - } - return ret; - } - /** * @param ret * @param pTypes @@ -157,34 +133,6 @@ public class ArgsPointcut extends NameBindingPointcut { return FuzzyBoolean.YES; } - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return (arguments.matches(args,TypePattern.DYNAMIC) == FuzzyBoolean.YES); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically(String joinpointKind, Member member, - Class thisClass, Class targetClass, Member withinCode) { - Class[] paramTypes = new Class[0]; - if (member instanceof Method) { - paramTypes = ((Method)member).getParameterTypes(); - } else if (member instanceof Constructor) { - paramTypes = ((Constructor)member).getParameterTypes(); - } else if (member instanceof PointcutExpressionImpl.Handler){ - paramTypes = new Class[] {((PointcutExpressionImpl.Handler)member).getHandledExceptionType()}; - } else if (member instanceof Field) { - if (joinpointKind.equals(Shadow.FieldGet.getName())) return FuzzyBoolean.NO; // no args here - paramTypes = new Class[] {((Field)member).getType()}; - } else { - return FuzzyBoolean.NO; - } - return arguments.matchesArgsPatternSubset(paramTypes); - } private Class getPossiblyBoxed(UnresolvedType tp) { Class ret = (Class) ExactTypePattern.primitiveTypesMap.get(tp.getName()); if (ret == null) ret = (Class) ExactTypePattern.boxedPrimitivesMap.get(tp.getName()); @@ -243,13 +191,6 @@ public class ArgsPointcut extends NameBindingPointcut { } } - public void resolveBindingsFromRTTI() { - arguments.resolveBindingsFromRTTI(true, true); - if (arguments.ellipsisCount > 1) { - throw new UnsupportedOperationException("uses more than one .. in args (compiler limitation)"); - } - } - public void postRead(ResolvedType enclosingType) { arguments.postRead(enclosingType); } diff --git a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java index 6cd1f7e3f..17d30f10f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java @@ -89,33 +89,11 @@ public class CflowPointcut extends Pointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - protected FuzzyBoolean matchInternal(Shadow shadow) { //??? this is not maximally efficient return FuzzyBoolean.MAYBE; } - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - throw new UnsupportedOperationException("cflow pointcut matching not supported by this operation"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, java.lang.reflect.Member member, - Class thisClass, Class targetClass, - java.lang.reflect.Member withinCode) { - throw new UnsupportedOperationException("cflow pointcut matching not supported by this operation"); - } - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.CFLOW); entry.write(s); @@ -148,12 +126,6 @@ public class CflowPointcut extends Pointcut { } } - public void resolveBindingsFromRTTI() { - if (entry.state != RESOLVED) { - entry.resolveBindingsFromRTTI(); - } - } - public boolean equals(Object other) { if (!(other instanceof CflowPointcut)) return false; CflowPointcut o = (CflowPointcut)other; diff --git a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java index 2c6fc51ba..cc198a8c6 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java @@ -52,34 +52,12 @@ public class ConcreteCflowPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - + protected FuzzyBoolean matchInternal(Shadow shadow) { //??? this is not maximally efficient return FuzzyBoolean.MAYBE; } - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - throw new UnsupportedOperationException("cflow pointcut matching not supported by this operation"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, java.lang.reflect.Member member, - Class thisClass, Class targetClass, - java.lang.reflect.Member withinCode) { - throw new UnsupportedOperationException("cflow pointcut matching not supported by this operation"); - } - // used by weaver when validating bindings public int[] getUsedFormalSlots() { if (slots == null) return new int[0]; @@ -99,10 +77,6 @@ public class ConcreteCflowPointcut extends Pointcut { throw new RuntimeException("unimplemented"); } - public void resolveBindingsFromRTTI() { - throw new RuntimeException("unimplemented"); - } - public boolean equals(Object other) { if (!(other instanceof ConcreteCflowPointcut)) return false; ConcreteCflowPointcut o = (ConcreteCflowPointcut)other; diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java index 1b712a226..5f6c90267 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java @@ -145,65 +145,7 @@ public class ExactTypePattern extends TypePattern { return matchType.isCoerceableFrom(type.resolve(matchType.getWorld())) ? FuzzyBoolean.MAYBE : FuzzyBoolean.NO; } } - - public boolean matchesExactly(Class matchType) { - try { - Class toMatchAgainst = getClassFor(type.getName()); - return matchType == toMatchAgainst; - } catch (ClassNotFoundException cnfEx) { - return false; - } - } - - public FuzzyBoolean matchesInstanceof(Class matchType) { - if (matchType.equals(Object.class)) return FuzzyBoolean.YES; - - try { - String typeName = type.getName(); - Class toMatchAgainst = getClassFor(typeName); - FuzzyBoolean ret = FuzzyBoolean.fromBoolean(toMatchAgainst.isAssignableFrom(matchType)); - if (ret == FuzzyBoolean.NO) { - if (boxedTypesMap.containsKey(typeName)) { - // try again with 'boxed' alternative - toMatchAgainst = (Class) boxedTypesMap.get(typeName); - ret = FuzzyBoolean.fromBoolean(toMatchAgainst.isAssignableFrom(matchType)); - } - } - return ret; - } catch (ClassNotFoundException cnfEx) { - return FuzzyBoolean.NO; - } - } - - /** - * Return YES if any subtype of the static type would match, - * MAYBE if some subtypes could match - * NO if there could never be a match - * @param staticType - * @return - */ - public FuzzyBoolean willMatchDynamically(Class staticType) { - if (matchesExactly(staticType)) return FuzzyBoolean.YES; - if (matchesInstanceof(staticType) == FuzzyBoolean.YES) return FuzzyBoolean.YES; - try { - String typeName = type.getName(); - Class toMatchAgainst = getClassFor(typeName); - if (toMatchAgainst.isInterface()) return FuzzyBoolean.MAYBE; - if (staticType.isAssignableFrom(toMatchAgainst)) return FuzzyBoolean.MAYBE; - return FuzzyBoolean.NO; - } catch (ClassNotFoundException cnfEx) { - return FuzzyBoolean.NO; - } - } - - private Class getClassFor(String typeName) throws ClassNotFoundException { - Class ret = null; - ret = (Class) primitiveTypesMap.get(typeName); - if (ret == null) ret = Class.forName(typeName); - return ret; - } - public boolean equals(Object other) { if (!(other instanceof ExactTypePattern)) return false; ExactTypePattern o = (ExactTypePattern)other; @@ -280,10 +222,6 @@ public class ExactTypePattern extends TypePattern { } - public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) { - throw new IllegalStateException("trying to re-resolve"); - } - /** * return a version of this type pattern with all type variables references replaced * by the corresponding entry in the map. diff --git a/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java b/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java index dbd0d5761..936cecf83 100644 --- a/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java @@ -15,12 +15,10 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Member; import java.util.HashSet; import java.util.Set; import org.aspectj.bridge.MessageUtil; -import org.aspectj.lang.JoinPoint; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; @@ -31,7 +29,6 @@ import org.aspectj.weaver.VersionedDataInputStream; import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; -import org.aspectj.weaver.internal.tools.PointcutExpressionImpl; /** * This is a kind of KindedPointcut. This belongs either in @@ -61,10 +58,6 @@ public class HandlerPointcut extends Pointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - protected FuzzyBoolean matchInternal(Shadow shadow) { if (shadow.getKind() != Shadow.ExceptionHandler) return FuzzyBoolean.NO; @@ -76,39 +69,6 @@ public class HandlerPointcut extends Pointcut { TypePattern.STATIC); } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) { - if (!jp.getKind().equals(JoinPoint.EXCEPTION_HANDLER)) return FuzzyBoolean.NO; - if (jp.getArgs().length > 0) { - Object caughtException = jp.getArgs()[0]; - return exceptionType.matches(caughtException,TypePattern.STATIC); - } else { - return FuzzyBoolean.NO; - } - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - if (args.length > 0) { - return (exceptionType.matches(args[0],TypePattern.STATIC) == FuzzyBoolean.YES); - } else return false; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically(String joinpointKind, Member member, - Class thisClass, Class targetClass, Member withinCode) { - if (!(member instanceof PointcutExpressionImpl.Handler)) { - return FuzzyBoolean.NO; - } else { - Class exceptionClass = ((PointcutExpressionImpl.Handler)member).getHandledExceptionType(); - return exceptionType.matches(exceptionClass,TypePattern.STATIC); - } - } - public boolean equals(Object other) { if (!(other instanceof HandlerPointcut)) return false; HandlerPointcut o = (HandlerPointcut)other; @@ -160,10 +120,6 @@ public class HandlerPointcut extends Pointcut { //XXX add error if exact binding and not an exception } - public void resolveBindingsFromRTTI() { - exceptionType = exceptionType.resolveBindingsFromRTTI(false,false); - } - protected Test findResidueInternal(Shadow shadow, ExposedState state) { return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE; } diff --git a/weaver/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java index b70ead92f..e8aa8ba4f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/HasMemberTypePattern.java @@ -98,14 +98,6 @@ public class HasMemberTypePattern extends TypePattern { throw new UnsupportedOperationException("hasmethod/field do not support instanceof matching"); } - public FuzzyBoolean matchesInstanceof(Class toMatch) { - return FuzzyBoolean.NO; - } - - protected boolean matchesExactly(Class toMatch) { - return false; - } - public TypePattern parameterizeWith(Map typeVariableMap) { HasMemberTypePattern ret = new HasMemberTypePattern(signaturePattern.parameterizeWith(typeVariableMap)); ret.copyLocationFrom(this); diff --git a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java index 5efff72a8..3afb4350e 100644 --- a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java @@ -14,7 +14,6 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Member; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -26,6 +25,7 @@ import org.aspectj.bridge.IMessage; import org.aspectj.lang.JoinPoint; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.Advice; +import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; import org.aspectj.weaver.ResolvedMember; @@ -34,10 +34,9 @@ import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.Shadow; import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.VersionedDataInputStream; import org.aspectj.weaver.WeaverMessages; -import org.aspectj.weaver.UnresolvedType; -import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.ast.Expr; import org.aspectj.weaver.ast.Literal; import org.aspectj.weaver.ast.Test; @@ -81,11 +80,7 @@ public class IfPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - + protected FuzzyBoolean matchInternal(Shadow shadow) { //??? this is not maximally efficient return FuzzyBoolean.MAYBE; @@ -104,23 +99,6 @@ public class IfPointcut extends Pointcut { return residueSource; } - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - throw new UnsupportedOperationException("If pointcut matching not supported by this operation"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - throw new UnsupportedOperationException("If pointcut matching not supported by this operation"); - } - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.IF); s.writeBoolean(testMethod != null); // do we have a test method? @@ -142,9 +120,7 @@ public class IfPointcut extends Pointcut { public void resolveBindings(IScope scope, Bindings bindings) { //??? all we need is good error messages in here in cflow contexts } - - public void resolveBindingsFromRTTI() {} - + public boolean equals(Object other) { if (!(other instanceof IfPointcut)) return false; IfPointcut o = (IfPointcut)other; @@ -436,9 +412,6 @@ public class IfPointcut extends Pointcut { public void resolveBindings(IScope scope, Bindings bindings) { } - public void resolveBindingsFromRTTI() { - } - public void postRead(ResolvedType enclosingType) { } @@ -508,9 +481,6 @@ public class IfPointcut extends Pointcut { public void resolveBindings(IScope scope, Bindings bindings) { } - public void resolveBindingsFromRTTI() { - } - public void postRead(ResolvedType enclosingType) { } diff --git a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java index cc19d438e..34fcd8ce9 100644 --- a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java @@ -21,7 +21,6 @@ import java.util.Set; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.MessageUtil; -import org.aspectj.lang.JoinPoint; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.Checker; import org.aspectj.weaver.ISourceContext; @@ -99,12 +98,7 @@ public class KindedPointcut extends Pointcut { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.fromBoolean(signature.couldMatch(targetType)); - } - - + protected FuzzyBoolean matchInternal(Shadow shadow) { if (shadow.getKind() != kind) return FuzzyBoolean.NO; @@ -134,35 +128,6 @@ public class KindedPointcut extends Pointcut { // } // } - public FuzzyBoolean match(JoinPoint.StaticPart jpsp) { - if (jpsp.getKind().equals(kind.getName())) { - if (signature.matches(jpsp)) { - return FuzzyBoolean.YES; - } - } - return FuzzyBoolean.NO; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return true; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically(String joinpointKind, - java.lang.reflect.Member member, Class thisClass, - Class targetClass, java.lang.reflect.Member withinCode) { - if (joinpointKind.equals(kind.getName())) { - return FuzzyBoolean.fromBoolean(signature.matches(targetClass,member)); - } - return FuzzyBoolean.NO; - } - private void warnOnConfusingSig(Shadow shadow) { // Don't do all this processing if we don't need to ! if (!shadow.getIWorld().getLint().unmatchedSuperTypeInCall.isEnabled()) return; @@ -389,10 +354,6 @@ public class KindedPointcut extends Pointcut { } } - public void resolveBindingsFromRTTI() { - signature = signature.resolveBindingsFromRTTI(); - } - protected Test findResidueInternal(Shadow shadow, ExposedState state) { return match(shadow).alwaysTrue() ? Literal.TRUE : Literal.FALSE; } diff --git a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java index 8a1dc5539..91a0512bc 100644 --- a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java @@ -51,38 +51,10 @@ public class NotPointcut extends Pointcut { return body.fastMatch(type).not(); } - public FuzzyBoolean fastMatch(Class targetType) { - return body.fastMatch(targetType).not(); - } - protected FuzzyBoolean matchInternal(Shadow shadow) { return body.match(shadow).not(); } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) { - return body.match(jp,encJP).not(); - } - - public FuzzyBoolean match(JoinPoint.StaticPart jpsp) { - return body.match(jpsp).not(); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return !body.matchesDynamically(thisObject,targetObject,args); - } - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - return body.matchesStatically(joinpointKind,member,thisClass,targetClass,withinCode).not(); - } - public String toString() { return "!" + body.toString(); @@ -111,11 +83,6 @@ public class NotPointcut extends Pointcut { } - public void resolveBindingsFromRTTI() { - body.resolveBindingsFromRTTI(); - } - - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.NOT); body.write(s); diff --git a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java index cc611cb88..e8a50d972 100644 --- a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java @@ -63,19 +63,7 @@ public class NotTypePattern extends TypePattern { protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { return (!negatedPattern.matchesExactly(type,annotatedType) && annotationPattern.matches(annotatedType).alwaysTrue()); } - - public boolean matchesStatically(Class type) { - return !negatedPattern.matchesStatically(type); - } - - public FuzzyBoolean matchesInstanceof(Class type) { - return negatedPattern.matchesInstanceof(type).not(); - } - - protected boolean matchesExactly(Class type) { - return !negatedPattern.matchesExactly(type); - } - + public boolean matchesStatically(ResolvedType type) { return !negatedPattern.matchesStatically(type); } @@ -122,12 +110,6 @@ public class NotTypePattern extends TypePattern { return ret; } - public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) { - if (requireExactType) return TypePattern.NO; - negatedPattern = negatedPattern.resolveBindingsFromRTTI(allowBinding,requireExactType); - return this; - } - public String toString() { StringBuffer buff = new StringBuffer(); if (annotationPattern != AnnotationTypePattern.ANY) { diff --git a/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java b/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java index 5ec0962c3..76774e613 100644 --- a/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java @@ -15,12 +15,10 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Member; import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.aspectj.lang.JoinPoint; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; @@ -50,10 +48,6 @@ public class OrPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return left.fastMatch(type).or(right.fastMatch(type)); } - - public FuzzyBoolean fastMatch(Class targetType) { - return left.fastMatch(targetType).or(right.fastMatch(targetType)); - } protected FuzzyBoolean matchInternal(Shadow shadow) { FuzzyBoolean leftMatch = left.match(shadow); @@ -61,34 +55,6 @@ public class OrPointcut extends Pointcut { return leftMatch.or(right.match(shadow)); } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) { - return left.match(jp,encJP).or(right.match(jp,encJP)); - } - - public FuzzyBoolean match(JoinPoint.StaticPart jpsp) { - return left.match(jpsp).or(right.match(jpsp)); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return left.matchesDynamically(thisObject,targetObject,args) - || - right.matchesDynamically(thisObject,targetObject,args); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - return left.matchesStatically(joinpointKind,member,thisClass,targetClass,withinCode) - .or( - right.matchesStatically(joinpointKind,member,thisClass,targetClass,withinCode)); - } public String toString() { return "(" + left.toString() + " || " + right.toString() + ")"; } @@ -116,11 +82,6 @@ public class OrPointcut extends Pointcut { } - public void resolveBindingsFromRTTI() { - left.resolveBindingsFromRTTI(); - right.resolveBindingsFromRTTI(); - } - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.OR); left.write(s); diff --git a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java index 8dd01b9f0..6ade9fc47 100644 --- a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java @@ -72,19 +72,6 @@ public class OrTypePattern extends TypePattern { public boolean matchesStatically(ResolvedType type) { return left.matchesStatically(type) || right.matchesStatically(type); } - - public FuzzyBoolean matchesInstanceof(Class type) { - return left.matchesInstanceof(type).or(right.matchesInstanceof(type)); - } - - protected boolean matchesExactly(Class type) { - //??? if these had side-effects, this sort-circuit could be a mistake - return left.matchesExactly(type) || right.matchesExactly(type); - } - - public boolean matchesStatically(Class type) { - return left.matchesStatically(type) || right.matchesStatically(type); - } public void setIsVarArgs(boolean isVarArgs) { this.isVarArgs = isVarArgs; @@ -141,13 +128,6 @@ public class OrTypePattern extends TypePattern { return ret; } - public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) { - if (requireExactType) return TypePattern.NO; - left = left.resolveBindingsFromRTTI(allowBinding,requireExactType); - right = right.resolveBindingsFromRTTI(allowBinding,requireExactType); - return this; - } - public String toString() { StringBuffer buff = new StringBuffer(); if (annotationPattern != AnnotationTypePattern.ANY) { diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java index 7afddbc8a..d697c8d68 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java @@ -60,11 +60,7 @@ public class PerCflow extends PerClause { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - + protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.YES; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerClause.java b/weaver/src/org/aspectj/weaver/patterns/PerClause.java index bd3f7f801..5bd69abab 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerClause.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerClause.java @@ -59,10 +59,6 @@ public abstract class PerClause extends Pointcut { } } - public void resolveBindingsFromRTTI() { - throw new UnsupportedOperationException("Can't resolve per-clauses at runtime"); - } - public static final Kind SINGLETON = new Kind("issingleton", 1); public static final Kind PERCFLOW = new Kind("percflow", 2); public static final Kind PEROBJECT = new Kind("perobject", 3); diff --git a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java index f677fdba0..1b197374e 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java @@ -44,11 +44,7 @@ public class PerFromSuper extends PerClause { public FuzzyBoolean fastMatch(FastMatchInfo type) { throw new RuntimeException("unimplemented"); } - - public FuzzyBoolean fastMatch(Class targetType) { - throw new RuntimeException("unimplemented"); - } - + protected FuzzyBoolean matchInternal(Shadow shadow) { throw new RuntimeException("unimplemented"); } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerObject.java b/weaver/src/org/aspectj/weaver/patterns/PerObject.java index bb3bbbf63..18e0aedf1 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerObject.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerObject.java @@ -64,12 +64,7 @@ public class PerObject extends PerClause { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - - + protected FuzzyBoolean matchInternal(Shadow shadow) { //System.err.println("matches " + this + " ? " + shadow + ", " + shadow.hasTarget()); //??? could probably optimize this better by testing could match diff --git a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java index bf2b60d39..8c3339e47 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java @@ -44,10 +44,6 @@ public class PerSingleton extends PerClause { return FuzzyBoolean.YES; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.YES; - } - protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.YES; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java index f952f1461..6a4f5ecd8 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java @@ -69,12 +69,7 @@ public class PerTypeWithin extends PerClause { } return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - - + protected FuzzyBoolean matchInternal(Shadow shadow) { ResolvedType enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true); if (enclosingType == ResolvedType.MISSING) { diff --git a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java index 2ae97f3ae..e120b43dd 100644 --- a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java @@ -81,7 +81,7 @@ import org.aspectj.weaver.ast.Test; * match the shadow. * */ -public abstract class Pointcut extends PatternNode implements PointcutExpressionMatching { +public abstract class Pointcut extends PatternNode { public static final class State extends TypeSafeEnum { public State(String name, int key) { super(name, key); @@ -104,7 +104,6 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression protected int lastMatchedShadowId; private FuzzyBoolean lastMatchedShadowResult; - private Test lastMatchedShadowResidue; private String[] typeVariablesInScope = new String[0]; /** @@ -122,11 +121,6 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression public abstract FuzzyBoolean fastMatch(FastMatchInfo info); /** - * Could I match any shadows defined in this type? - */ - public abstract FuzzyBoolean fastMatch(Class targetType); - - /** * The set of ShadowKinds that this Pointcut could possibly match */ public abstract /*Enum*/Set/*<Shadow.Kind>*/ couldMatchKinds(); @@ -159,40 +153,6 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression protected abstract FuzzyBoolean matchInternal(Shadow shadow); - /* - * for runtime / dynamic pointcuts. - * Default implementation delegates to StaticPart matcher - */ - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart enclosingJoinPoint) { - return match(jp.getStaticPart()); - } - - /* - * for runtime / dynamic pointcuts. - * Not all pointcuts can be matched at runtime, those that can should overide either - * match(JoinPoint), or this method, or both. - */ - public FuzzyBoolean match(JoinPoint.StaticPart jpsp) { - throw new UnsupportedOperationException("Pointcut expression " + this.toString() + "cannot be matched at runtime"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesDynamically(java.lang.String, java.lang.reflect.Member, java.lang.Object, java.lang.Object, java.lang.reflect.Member) - */ - public boolean matchesDynamically( - Object thisObject, Object targetObject, Object[] args) { - throw new UnsupportedOperationException("Pointcut expression " + this.toString() + "cannot be matched by this operation"); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.tools.PointcutExpression#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - throw new UnsupportedOperationException("Pointcut expression " + this.toString() + "cannot be matched by this operation"); - } - public static final byte KINDED = 1; public static final byte WITHIN = 2; public static final byte THIS_OR_TARGET = 3; @@ -221,9 +181,6 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression // internal, only called from resolve protected abstract void resolveBindings(IScope scope, Bindings bindings); - // internal, only called from resolve - protected abstract void resolveBindingsFromRTTI(); - /** * Returns this pointcut mutated */ @@ -240,16 +197,6 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression return this; } - /** - * Returns this pointcut with type patterns etc resolved based on available RTTI - */ - public Pointcut resolve() { - assertState(SYMBOLIC); - this.resolveBindingsFromRTTI(); - this.state = RESOLVED; - return this; - } - /** * Returns a new pointcut * Only used by test cases @@ -386,41 +333,13 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression return FuzzyBoolean.NO; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.NO; - } - protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.NO; } - - public FuzzyBoolean match(JoinPoint.StaticPart jpsp) { - return FuzzyBoolean.NO; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, - Object targetObject, Object[] args) { - return false; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - return FuzzyBoolean.NO; - } - + public void resolveBindings(IScope scope, Bindings bindings) { } - public void resolveBindingsFromRTTI() { - } - public void postRead(ResolvedType enclosingType) { } diff --git a/weaver/src/org/aspectj/weaver/patterns/PointcutExpressionMatching.java b/weaver/src/org/aspectj/weaver/patterns/PointcutExpressionMatching.java deleted file mode 100644 index 0e054ed45..000000000 --- a/weaver/src/org/aspectj/weaver/patterns/PointcutExpressionMatching.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Common Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * ******************************************************************/ -package org.aspectj.weaver.patterns; - -import java.lang.reflect.Member; - -import org.aspectj.util.FuzzyBoolean; - - -/** - * Interface used by PointcutExpressionImpl to determine matches. - */ -public interface PointcutExpressionMatching { - - FuzzyBoolean matchesStatically( - String joinpointKind, - Member member, - Class thisClass, - Class targetClass, - Member withinCode); - - /** - * Only considers this, target, and args primitives, returns - * true for all others. - * @param thisObject - * @param targetObject - * @param args - * @return - */ - boolean matchesDynamically( - Object thisObject, - Object targetObject, - Object[] args); -} diff --git a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java index 39afad012..67407a408 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java @@ -76,11 +76,7 @@ public class ReferencePointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - + /** * Do I really match this shadow? */ @@ -236,10 +232,6 @@ public class ReferencePointcut extends Pointcut { } } - public void resolveBindingsFromRTTI() { - throw new UnsupportedOperationException("Referenced pointcuts are not supported in runtime evaluation"); - } - public void postRead(ResolvedType enclosingType) { arguments.postRead(enclosingType); } diff --git a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java index 7f1266396..0684164e6 100644 --- a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java @@ -92,24 +92,6 @@ public class SignaturePattern extends PatternNode { return this; } - public SignaturePattern resolveBindingsFromRTTI() { - if (returnType != null) { - returnType = returnType.resolveBindingsFromRTTI(false, false); - } - if (declaringType != null) { - declaringType = declaringType.resolveBindingsFromRTTI(false, false); - } - if (parameterTypes != null) { - parameterTypes = parameterTypes.resolveBindingsFromRTTI(false, false); - } - if (throwsPattern != null) { - throwsPattern = throwsPattern.resolveBindingsFromRTTI(); - } - - return this; - } - - public void postRead(ResolvedType enclosingType) { if (returnType != null) { returnType.postRead(enclosingType); @@ -371,134 +353,6 @@ public class SignaturePattern extends PatternNode { return false; } - // for dynamic join point matching - public boolean matches(JoinPoint.StaticPart jpsp) { - Signature sig = jpsp.getSignature(); - if (kind == Member.ADVICE && !(sig instanceof AdviceSignature)) return false; - if (kind == Member.CONSTRUCTOR && !(sig instanceof ConstructorSignature)) return false; - if (kind == Member.FIELD && !(sig instanceof FieldSignature)) return false; - if (kind == Member.METHOD && !(sig instanceof MethodSignature)) return false; - if (kind == Member.STATIC_INITIALIZATION && !(jpsp.getKind().equals(JoinPoint.STATICINITIALIZATION))) return false; - if (kind == Member.POINTCUT) return false; - - if (kind == Member.ADVICE) return true; - - if (!modifiers.matches(sig.getModifiers())) return false; - - if (kind == Member.STATIC_INITIALIZATION) { - //System.err.println("match static init: " + sig.getDeclaringType() + " with " + this); - return declaringType.matchesStatically(sig.getDeclaringType()); - } else if (kind == Member.FIELD) { - Class returnTypeClass = ((FieldSignature)sig).getFieldType(); - if (!returnType.matchesStatically(returnTypeClass)) return false; - if (!name.matches(sig.getName())) return false; - boolean ret = declaringTypeMatch(sig); - //System.out.println(" ret: " + ret); - return ret; - } else if (kind == Member.METHOD) { - MethodSignature msig = ((MethodSignature)sig); - Class returnTypeClass = msig.getReturnType(); - Class[] params = msig.getParameterTypes(); - Class[] exceptionTypes = msig.getExceptionTypes(); - if (!returnType.matchesStatically(returnTypeClass)) return false; - if (!name.matches(sig.getName())) return false; - if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { - return false; - } - if (matchedArrayAgainstVarArgs(parameterTypes,msig.getModifiers())) { return false; } - - if (!throwsPattern.matches(exceptionTypes)) return false; - return declaringTypeMatch(sig); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work - } else if (kind == Member.CONSTRUCTOR) { - ConstructorSignature csig = (ConstructorSignature)sig; - Class[] params = csig.getParameterTypes(); - Class[] exceptionTypes = csig.getExceptionTypes(); - if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { - return false; - } - if (matchedArrayAgainstVarArgs(parameterTypes,csig.getModifiers())) { return false; } - - if (!throwsPattern.matches(exceptionTypes)) return false; - return declaringType.matchesStatically(sig.getDeclaringType()); - //return declaringTypeMatch(member.getDeclaringType(), member, world); - } - - return false; - } - - public boolean couldMatch(Class declaringClass) { - return declaringTypeMatch(declaringClass); - } - - public boolean matches(Class declaringClass, java.lang.reflect.Member member) { - if (kind == Member.ADVICE) return true; - if (kind == Member.POINTCUT) return false; - if ((member != null) && !(modifiers.matches(member.getModifiers()))) return false; - if (kind == Member.STATIC_INITIALIZATION) { - return declaringType.matchesStatically(declaringClass); - } - if (kind == Member.FIELD) { - if (!(member instanceof Field)) return false; - - Class fieldTypeClass = ((Field)member).getType(); - if (!returnType.matchesStatically(fieldTypeClass)) return false; - if (!name.matches(member.getName())) return false; - return declaringTypeMatch(member.getDeclaringClass()); - } - if (kind == Member.METHOD) { - if (! (member instanceof Method)) return false; - - Class returnTypeClass = ((Method)member).getReturnType(); - Class[] params = ((Method)member).getParameterTypes(); - Class[] exceptionTypes = ((Method)member).getExceptionTypes(); - if (!returnType.matchesStatically(returnTypeClass)) return false; - if (!name.matches(member.getName())) return false; - if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { - return false; - } - if (matchedArrayAgainstVarArgs(parameterTypes,member.getModifiers())) { return false; } - if (!throwsPattern.matches(exceptionTypes)) return false; - return declaringTypeMatch(member.getDeclaringClass()); // XXXAJ5 - Need to make this a covariant aware version for dynamic JP matching to work - } - if (kind == Member.CONSTRUCTOR) { - if (! (member instanceof Constructor)) return false; - - Class[] params = ((Constructor)member).getParameterTypes(); - Class[] exceptionTypes = ((Constructor)member).getExceptionTypes(); - if (!parameterTypes.matches(params, TypePattern.STATIC).alwaysTrue()) { - return false; - } - if (matchedArrayAgainstVarArgs(parameterTypes,member.getModifiers())) { return false; } - if (!throwsPattern.matches(exceptionTypes)) return false; - return declaringType.matchesStatically(declaringClass); - } - return false; - } - - private boolean declaringTypeMatch(Signature sig) { - Class onType = sig.getDeclaringType(); - if (declaringType.matchesStatically(onType)) return true; - - Collection declaringTypes = getDeclaringTypes(sig); - - for (Iterator it = declaringTypes.iterator(); it.hasNext(); ) { - Class pClass = (Class) it.next(); - if (declaringType.matchesStatically(pClass)) return true; - } - - return false; - } - - private boolean declaringTypeMatch(Class clazz) { - if (clazz == null) return false; - if (declaringType.matchesStatically(clazz)) return true; - Class[] ifs = clazz.getInterfaces(); - for (int i = 0; i<ifs.length; i++) { - if (declaringType.matchesStatically(ifs[i])) return true; - } - return declaringTypeMatch(clazz.getSuperclass()); - } - private Collection getDeclaringTypes(Signature sig) { List l = new ArrayList(); Class onType = sig.getDeclaringType(); diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java index 784c42674..0a83c3d49 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java @@ -62,6 +62,7 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut { super(); this.isThis = isThis; this.annotationTypePattern = type; + this.pointcutKind = ATTHIS_OR_TARGET; } public ThisOrTargetAnnotationPointcut(boolean isThis, ExactAnnotationTypePattern type, ShadowMunger munger) { @@ -84,10 +85,6 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -128,14 +125,6 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut { } /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI() - */ - protected void resolveBindingsFromRTTI() { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap) */ protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java index 71f6c8a91..dbb262fc3 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java @@ -86,10 +86,6 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - private boolean couldMatch(Shadow shadow) { return isThis ? shadow.hasThis() : shadow.hasTarget(); } @@ -102,34 +98,6 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { return type.matches(typeToMatch.resolve(shadow.getIWorld()), TypePattern.DYNAMIC); } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) { - Object toMatch = isThis ? jp.getThis() : jp.getTarget(); - if (toMatch == null) return FuzzyBoolean.NO; - return type.matches(toMatch.getClass(), TypePattern.DYNAMIC); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - Object toMatch = isThis ? thisObject : targetObject; - if (toMatch == null) return false; - return type.matchesSubtypes(toMatch.getClass()); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically(String joinpointKind, Member member, - Class thisClass, Class targetClass, Member withinCode) { - Class staticType = isThis ? thisClass : targetClass; - if (joinpointKind.equals(Shadow.StaticInitialization.getName())) { - return FuzzyBoolean.NO; // no this or target at these jps - } - return(((ExactTypePattern)type).willMatchDynamically(staticType)); - } - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.THIS_OR_TARGET); s.writeBoolean(isThis); @@ -158,10 +126,6 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { // ??? handle non-formal } - public void resolveBindingsFromRTTI() { - type = type.resolveBindingsFromRTTI(true,true); - } - public void postRead(ResolvedType enclosingType) { type.postRead(enclosingType); } diff --git a/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java b/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java index c678dcdb3..2bf400769 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java @@ -75,13 +75,7 @@ public class ThrowsPattern extends PatternNode { forbidden = forbidden.resolveBindings(scope, bindings, false, false); return this; } - - public ThrowsPattern resolveBindingsFromRTTI() { - required = required.resolveBindingsFromRTTI(false,false); - forbidden = forbidden.resolveBindingsFromRTTI(false,false); - return this; - } - + public ThrowsPattern parameterizeWith(Map/*name -> resolved type*/ typeVariableMap) { ThrowsPattern ret = new ThrowsPattern( required.parameterizeWith(typeVariableMap), @@ -110,25 +104,6 @@ public class ThrowsPattern extends PatternNode { return true; } - public boolean matches(Class[] onTypes) { - if (this == ANY) return true; - - //System.out.println("matching: " + this + " with " + Arrays.asList(tys)); - - for (int j=0, lenj = required.size(); j < lenj; j++) { - if (! matchesAny(required.get(j), onTypes)) { - return false; - } - } - for (int j=0, lenj = forbidden.size(); j < lenj; j++) { - if (matchesAny(forbidden.get(j), onTypes)) { - return false; - } - } - return true; - - } - private boolean matchesAny( TypePattern typePattern, ResolvedType[] types) @@ -139,13 +114,6 @@ public class ThrowsPattern extends PatternNode { return false; } - private boolean matchesAny(TypePattern typePattern, Class[] types) { - for (int i = types.length - 1; i >= 0; i--) { - if (typePattern.matchesStatically(types[i])) return true; - } - return false; - } - public static ThrowsPattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { TypePatternList required = TypePatternList.read(s, context); TypePatternList forbidden = TypePatternList.read(s, context); diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java index 6d77c7ac0..b98b7a169 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java @@ -141,65 +141,7 @@ public abstract class TypePattern extends PatternNode { throw new IllegalArgumentException("kind must be DYNAMIC or STATIC"); } } - - - // methods for dynamic pc matching... - public final FuzzyBoolean matches(Class toMatch, MatchKind kind) { - if (kind == STATIC) { - return FuzzyBoolean.fromBoolean(matchesStatically(toMatch)); - } else if (kind == DYNAMIC) { - //System.err.println("matching: " + this + " with " + type); - FuzzyBoolean ret = matchesInstanceof(toMatch); - //System.err.println(" got: " + ret); - return ret; - } else { - throw new IllegalArgumentException("kind must be DYNAMIC or STATIC"); - } - } - /** - * This variant is only called by the args and handler pcds when doing runtime - * matching. We need to handle primitive types correctly in this case (an Integer - * should match an int,...). - */ - public final FuzzyBoolean matches(Object o, MatchKind kind) { - if (kind == STATIC) { // handler pcd - return FuzzyBoolean.fromBoolean(matchesStatically(o.getClass())); - } else if (kind == DYNAMIC) { // args pcd -// Class clazz = o.getClass(); -// FuzzyBoolean ret = FuzzyBoolean.fromBoolean(matchesSubtypes(clazz)); -// if (ret == FuzzyBoolean.NO) { -// // try primitive type instead -// if (clazz == Integer.class) ret = FuzzyBoolean.fromBoolean(matchesExactly(int.class)); -// } -// return ret; - return matchesInstanceof(o.getClass()); - } else { - throw new IllegalArgumentException("kind must be DYNAMIC or STATIC"); - } - } - - public boolean matchesStatically(Class toMatch) { - if (includeSubtypes) { - return matchesSubtypes(toMatch); - } else { - return matchesExactly(toMatch); - } - } - public abstract FuzzyBoolean matchesInstanceof(Class toMatch); - - protected abstract boolean matchesExactly(Class toMatch); - protected boolean matchesSubtypes(Class toMatch) { - if (matchesExactly(toMatch)) { - return true; - } - Class superClass = toMatch.getSuperclass(); - if (superClass != null) { - return matchesSubtypes(superClass); - } - return false; - } - protected abstract boolean matchesExactly(ResolvedType type); protected abstract boolean matchesExactly(ResolvedType type, ResolvedType annotatedType); @@ -272,10 +214,6 @@ public abstract class TypePattern extends PatternNode { return this; } - public TypePattern resolveBindingsFromRTTI(boolean allowBindng, boolean requireExactType) { - return this; - } - public void resolve(World world) { annotationPattern.resolve(world); } @@ -389,19 +327,6 @@ class EllipsisTypePattern extends TypePattern { } /** - * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) - */ - protected boolean matchesExactly(Class type) { - return false; - } - - /** - * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) - */ - public FuzzyBoolean matchesInstanceof(Class type) { - return FuzzyBoolean.NO; - } - /** * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream) */ public void write(DataOutputStream s) throws IOException { @@ -470,19 +395,6 @@ class AnyTypePattern extends TypePattern { } /** - * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) - */ - protected boolean matchesExactly(Class type) { - return true; - } - - /** - * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) - */ - public FuzzyBoolean matchesInstanceof(Class type) { - return FuzzyBoolean.YES; - } - /** * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream) */ public void write(DataOutputStream s) throws IOException { @@ -563,14 +475,6 @@ class AnyWithAnnotationTypePattern extends TypePattern { return FuzzyBoolean.MAYBE; } - protected boolean matchesExactly(Class type) { - return true; - } - - public FuzzyBoolean matchesInstanceof(Class type) { - return FuzzyBoolean.YES; - } - public TypePattern parameterizeWith(Map typeVariableMap) { return this; } @@ -645,19 +549,6 @@ class NoTypePattern extends TypePattern { } /** - * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType) - */ - protected boolean matchesExactly(Class type) { - return false; - } - - /** - * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType) - */ - public FuzzyBoolean matchesInstanceof(Class type) { - return FuzzyBoolean.NO; - } - /** * @see org.aspectj.weaver.patterns.PatternNode#write(DataOutputStream) */ public void write(DataOutputStream s) throws IOException { diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java index de106c4d5..3a5b81e52 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java @@ -74,53 +74,7 @@ public class TypePatternList extends PatternNode { buf.append(")"); return buf.toString(); } - - - /** - * Used by reflection-based matching for args pcds. - * Returns YES if types will always be matched by the pattern, - * NO if types do not match the pattern, - * MAYBE if types may match the pattern dependent on a runtime test - */ - public FuzzyBoolean matchesArgsPatternSubset(Class[] types) { - int argsLength = types.length; - int patternLength = typePatterns.length; - int argsIndex = 0; - - if ((argsLength < patternLength) && (ellipsisCount == 0)) return FuzzyBoolean.NO; - if (argsLength < (patternLength -1)) return FuzzyBoolean.NO; - - int ellipsisMatchCount = argsLength - (patternLength - ellipsisCount); - - FuzzyBoolean ret = FuzzyBoolean.YES; - - for (int i = 0; i < typePatterns.length; i++) { - if (typePatterns[i] == TypePattern.ELLIPSIS) { - // match ellipsisMatchCount args - argsIndex += ellipsisMatchCount; - } else if (typePatterns[i] == TypePattern.ANY) { - argsIndex++; - } else { - // be defensive, might see a type-pattern NO - if (! (typePatterns[i] instanceof ExactTypePattern)) { - return FuzzyBoolean.NO; - } - // match the argument type at argsIndex with the ExactTypePattern - // we it is exact because nothing else is allowed in args - ExactTypePattern tp = (ExactTypePattern)typePatterns[i]; - FuzzyBoolean matches = tp.willMatchDynamically(types[argsIndex]); - if (matches == FuzzyBoolean.NO) { - return FuzzyBoolean.NO; - } else { - argsIndex++; - ret = ret.and(matches); - } - } - } - - return ret; - } - + //XXX shares much code with WildTypePattern and with NamePattern /** * When called with TypePattern.STATIC this will always return either @@ -170,85 +124,6 @@ public class TypePatternList extends PatternNode { } } - - // TODO Add TypePatternList.matches(Object[] objs) - public FuzzyBoolean matches(Object[] objs, TypePattern.MatchKind kind) { - int nameLength = objs.length; - int patternLength = typePatterns.length; - - int nameIndex = 0; - int patternIndex = 0; - - if (ellipsisCount == 0) { - if (nameLength != patternLength) return FuzzyBoolean.NO; - FuzzyBoolean finalReturn = FuzzyBoolean.YES; - while (patternIndex < patternLength) { - FuzzyBoolean ret = typePatterns[patternIndex++].matches(objs[nameIndex++],kind); - if (ret == FuzzyBoolean.NO) return ret; - if (ret == FuzzyBoolean.MAYBE) finalReturn = ret; - } - return finalReturn; - } else if (ellipsisCount == 1) { - if (nameLength < patternLength-1) return FuzzyBoolean.NO; - FuzzyBoolean finalReturn = FuzzyBoolean.YES; - while (patternIndex < patternLength) { - TypePattern p = typePatterns[patternIndex++]; - if (p == TypePattern.ELLIPSIS) { - nameIndex = nameLength - (patternLength-patternIndex); - } else { - FuzzyBoolean ret = p.matches(objs[nameIndex++],kind); - if (ret == FuzzyBoolean.NO) return ret; - if (ret == FuzzyBoolean.MAYBE) finalReturn = ret; - } - } - return finalReturn; - } else { -// System.err.print("match(" + arguments + ", " + types + ") -> "); - FuzzyBoolean b = outOfStar(typePatterns, objs, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind); -// System.err.println(b); - return b; - } - } - - // XXX run-time signature matching, too much duplicated code - public FuzzyBoolean matches(Class[] types, TypePattern.MatchKind kind) { - int nameLength = types.length; - int patternLength = typePatterns.length; - - int nameIndex = 0; - int patternIndex = 0; - - if (ellipsisCount == 0) { - if (nameLength != patternLength) return FuzzyBoolean.NO; - FuzzyBoolean finalReturn = FuzzyBoolean.YES; - while (patternIndex < patternLength) { - FuzzyBoolean ret = typePatterns[patternIndex++].matches(types[nameIndex++], kind); - if (ret == FuzzyBoolean.NO) return ret; - if (ret == FuzzyBoolean.MAYBE) finalReturn = ret; - } - return finalReturn; - } else if (ellipsisCount == 1) { - if (nameLength < patternLength-1) return FuzzyBoolean.NO; - FuzzyBoolean finalReturn = FuzzyBoolean.YES; - while (patternIndex < patternLength) { - TypePattern p = typePatterns[patternIndex++]; - if (p == TypePattern.ELLIPSIS) { - nameIndex = nameLength - (patternLength-patternIndex); - } else { - FuzzyBoolean ret = p.matches(types[nameIndex++], kind); - if (ret == FuzzyBoolean.NO) return ret; - if (ret == FuzzyBoolean.MAYBE) finalReturn = ret; - } - } - return finalReturn; - } else { -// System.err.print("match(" + arguments + ", " + types + ") -> "); - FuzzyBoolean b = outOfStar(typePatterns, types, 0, 0, patternLength - ellipsisCount, nameLength, ellipsisCount, kind); -// System.err.println(b); - return b; - } - } - private static FuzzyBoolean outOfStar(final TypePattern[] pattern, final ResolvedType[] target, int pi, int ti, int pLeft, int tLeft, @@ -295,129 +170,7 @@ public class TypePatternList extends PatternNode { ti++; tLeft--; } } - - - - private static FuzzyBoolean outOfStar(final TypePattern[] pattern, - final Class[] target, int pi, int ti, int pLeft, int tLeft, - final int starsLeft, TypePattern.MatchKind kind) { - if (pLeft > tLeft) - return FuzzyBoolean.NO; - FuzzyBoolean finalReturn = FuzzyBoolean.YES; - while (true) { - // invariant: if (tLeft > 0) then (ti < target.length && pi < - // pattern.length) - if (tLeft == 0) - return finalReturn; - if (pLeft == 0) { - if (starsLeft > 0) { - return finalReturn; - } else { - return FuzzyBoolean.NO; - } - } - if (pattern[pi] == TypePattern.ELLIPSIS) { - return inStar(pattern, target, pi + 1, ti, pLeft, tLeft, - starsLeft - 1, kind); - } - FuzzyBoolean ret = pattern[pi].matches(target[ti], kind); - if (ret == FuzzyBoolean.NO) - return ret; - if (ret == FuzzyBoolean.MAYBE) - finalReturn = ret; - pi++; - ti++; - pLeft--; - tLeft--; - } - } - - private static FuzzyBoolean inStar(final TypePattern[] pattern, - final Class[] target, int pi, int ti, final int pLeft, - int tLeft, int starsLeft, TypePattern.MatchKind kind) { - // invariant: pLeft > 0, so we know we'll run out of stars and find a - // real char in pattern - TypePattern patternChar = pattern[pi]; - while (patternChar == TypePattern.ELLIPSIS) { - starsLeft--; - patternChar = pattern[++pi]; - } - while (true) { - // invariant: if (tLeft > 0) then (ti < target.length) - if (pLeft > tLeft) - return FuzzyBoolean.NO; - FuzzyBoolean ff = patternChar.matches(target[ti], kind); - if (ff.maybeTrue()) { - FuzzyBoolean xx = outOfStar(pattern, target, pi + 1, ti + 1, - pLeft - 1, tLeft - 1, starsLeft, kind); - if (xx.maybeTrue()) - return ff.and(xx); - } - ti++; - tLeft--; - } - } - - private static FuzzyBoolean outOfStar(final TypePattern[] pattern, - final Object[] target, int pi, int ti, int pLeft, int tLeft, - final int starsLeft, TypePattern.MatchKind kind) { - if (pLeft > tLeft) - return FuzzyBoolean.NO; - FuzzyBoolean finalReturn = FuzzyBoolean.YES; - while (true) { - // invariant: if (tLeft > 0) then (ti < target.length && pi < - // pattern.length) - if (tLeft == 0) - return finalReturn; - if (pLeft == 0) { - if (starsLeft > 0) { - return finalReturn; - } else { - return FuzzyBoolean.NO; - } - } - if (pattern[pi] == TypePattern.ELLIPSIS) { - return inStar(pattern, target, pi + 1, ti, pLeft, tLeft, - starsLeft - 1,kind); - } - FuzzyBoolean ret = pattern[pi].matches(target[ti],kind); - if (ret == FuzzyBoolean.NO) - return ret; - if (ret == FuzzyBoolean.MAYBE) - finalReturn = ret; - pi++; - ti++; - pLeft--; - tLeft--; - } - } - - private static FuzzyBoolean inStar(final TypePattern[] pattern, - final Object[] target, int pi, int ti, final int pLeft, - int tLeft, int starsLeft, TypePattern.MatchKind kind) { - // invariant: pLeft > 0, so we know we'll run out of stars and find a - // real char in pattern - TypePattern patternChar = pattern[pi]; - while (patternChar == TypePattern.ELLIPSIS) { - starsLeft--; - patternChar = pattern[++pi]; - } - while (true) { - // invariant: if (tLeft > 0) then (ti < target.length) - if (pLeft > tLeft) - return FuzzyBoolean.NO; - FuzzyBoolean ff = patternChar.matches(target[ti],kind); - if (ff.maybeTrue()) { - FuzzyBoolean xx = outOfStar(pattern, target, pi + 1, ti + 1, - pLeft - 1, tLeft - 1, starsLeft,kind); - if (xx.maybeTrue()) - return ff.and(xx); - } - ti++; - tLeft--; - } - } - + /** * Return a version of this type pattern list in which all type variable references * are replaced by their corresponding entry in the map @@ -442,16 +195,6 @@ public class TypePatternList extends PatternNode { return this; } - public TypePatternList resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) { - for (int i=0; i<typePatterns.length; i++) { - TypePattern p = typePatterns[i]; - if (p != null) { - typePatterns[i] = typePatterns[i].resolveBindingsFromRTTI(allowBinding, requireExactType); - } - } - return this; - } - public TypePatternList resolveReferences(IntMap bindings) { int len = typePatterns.length; TypePattern[] ret = new TypePattern[len]; diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java index 3f6a2cc6f..e16ce3d66 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -914,58 +914,6 @@ public class WildTypePattern extends TypePattern { return true; } - public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) { - if (isStar()) { - return TypePattern.ANY; //??? loses source location - } - - String cleanName = maybeGetCleanName(); - if (cleanName != null) { - Class clazz = null; - clazz = maybeGetPrimitiveClass(cleanName); - - while (clazz == null) { - try { - clazz = Class.forName(cleanName); - } catch (ClassNotFoundException cnf) { - int lastDotIndex = cleanName.lastIndexOf('.'); - if (lastDotIndex == -1) break; - cleanName = cleanName.substring(0, lastDotIndex) + '$' + cleanName.substring(lastDotIndex+1); - } - } - - if (clazz == null) { - try { - clazz = Class.forName("java.lang." + cleanName); - } catch (ClassNotFoundException cnf) { - } - } - - if (clazz == null) { - if (requireExactType) { - return NO; - } - } else { - UnresolvedType type = UnresolvedType.forName(clazz.getName()); - if (dim != 0) type = UnresolvedType.makeArray(type,dim); - TypePattern ret = new ExactTypePattern(type, includeSubtypes,isVarArgs); - ret.copyLocationFrom(this); - return ret; - } - } else if (requireExactType) { - return NO; - } - - importedPrefixes = SimpleScope.javaLangPrefixArray; - knownMatches = new String[0]; - - return this; - } - - private Class maybeGetPrimitiveClass(String typeName) { - return (Class) ExactTypePattern.primitiveTypesMap.get(typeName); - } - public boolean isStar() { boolean annPatternStar = annotationPattern == AnnotationTypePattern.ANY; return (isNamePatternStar() && annPatternStar); @@ -1072,16 +1020,6 @@ public class WildTypePattern extends TypePattern { if (lowerBound != null) result = 37*result + lowerBound.hashCode(); return result; } - - - public FuzzyBoolean matchesInstanceof(Class type) { - return FuzzyBoolean.NO; - } - - public boolean matchesExactly(Class type) { - return matchesExactlyByName(type.getName()); - } - private static final byte VERSION = 1; // rev on change /** diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java index 4f83d5512..29037c51a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java @@ -50,11 +50,13 @@ public class WithinAnnotationPointcut extends NameBindingPointcut { public WithinAnnotationPointcut(AnnotationTypePattern type) { super(); this.annotationTypePattern = type; + this.pointcutKind = ATWITHIN; } public WithinAnnotationPointcut(AnnotationTypePattern type, ShadowMunger munger) { this(type); this.munger = munger; + this.pointcutKind = ATWITHIN; } public AnnotationTypePattern getAnnotationTypePattern() { @@ -72,11 +74,6 @@ public class WithinAnnotationPointcut extends NameBindingPointcut { return annotationTypePattern.fastMatches(info.getType()); } - public FuzzyBoolean fastMatch(Class targetType) { - // TODO AMC - return FuzzyBoolean.MAYBE; - } - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -102,14 +99,6 @@ public class WithinAnnotationPointcut extends NameBindingPointcut { } /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI() - */ - protected void resolveBindingsFromRTTI() { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap) */ protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java index 08220f71b..5c07ef024 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java @@ -56,12 +56,13 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { public WithinCodeAnnotationPointcut(ExactAnnotationTypePattern type) { super(); this.annotationTypePattern = type; - this.pointcutKind = Pointcut.ANNOTATION; + this.pointcutKind = Pointcut.ATWITHINCODE; } public WithinCodeAnnotationPointcut(ExactAnnotationTypePattern type, ShadowMunger munger) { this(type); this.munger = munger; + this.pointcutKind = Pointcut.ATWITHINCODE; } public ExactAnnotationTypePattern getAnnotationTypePattern() { @@ -79,10 +80,6 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -113,14 +110,6 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { } /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#resolveBindingsFromRTTI() - */ - protected void resolveBindingsFromRTTI() { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap) */ protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java index 698da839a..9f3054643 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java @@ -15,14 +15,12 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Member; import java.util.Set; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.MessageUtil; -import org.aspectj.lang.JoinPoint; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; @@ -65,11 +63,7 @@ public class WithinPointcut extends Pointcut { } return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - + protected FuzzyBoolean matchInternal(Shadow shadow) { ResolvedType enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true); if (enclosingType == ResolvedType.MISSING) { @@ -82,48 +76,6 @@ public class WithinPointcut extends Pointcut { typePattern.resolve(shadow.getIWorld()); return isWithinType(enclosingType); } - - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJp) { - return isWithinType(encJp.getSignature().getDeclaringType()); - } - - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return true; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically( - String joinpointKind, Member member, Class thisClass, - Class targetClass, Member withinCode) { - if ((member != null) && - !(joinpointKind.equals(Shadow.ConstructorCall.getName()) || - joinpointKind.equals(Shadow.MethodCall.getName()) || - joinpointKind.equals(Shadow.FieldGet.getName()) || - joinpointKind.equals(Shadow.FieldSet.getName())) - ) { - return isWithinType(member.getDeclaringClass()); - } else { - return isWithinType(thisClass); - } - } - - private FuzzyBoolean isWithinType(Class type) { - while (type != null) { - if (typePattern.matchesStatically(type)) { - return FuzzyBoolean.YES; - } - type = type.getDeclaringClass(); - } - return FuzzyBoolean.NO; - } - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.WITHIN); @@ -150,10 +102,6 @@ public class WithinPointcut extends Pointcut { } } - public void resolveBindingsFromRTTI() { - typePattern = typePattern.resolveBindingsFromRTTI(false,false); - } - public void postRead(ResolvedType enclosingType) { typePattern.postRead(enclosingType); } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java index 9cbd5941a..dce908d9e 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java @@ -15,13 +15,10 @@ package org.aspectj.weaver.patterns; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.reflect.Member; import java.util.HashSet; import java.util.Set; import org.aspectj.bridge.MessageUtil; -import org.aspectj.lang.JoinPoint; -import org.aspectj.runtime.reflect.Factory; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.IntMap; @@ -62,12 +59,7 @@ public class WithincodePointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } - - public FuzzyBoolean fastMatch(Class targetType) { - return FuzzyBoolean.MAYBE; - } - - + protected FuzzyBoolean matchInternal(Shadow shadow) { //This will not match code in local or anonymous classes as if //they were withincode of the outer signature @@ -75,27 +67,6 @@ public class WithincodePointcut extends Pointcut { signature.matches(shadow.getEnclosingCodeSignature(), shadow.getIWorld(), false)); } - public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart encJP) { - return FuzzyBoolean.fromBoolean(signature.matches(encJP)); - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[]) - */ - public boolean matchesDynamically(Object thisObject, Object targetObject, - Object[] args) { - return true; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member) - */ - public FuzzyBoolean matchesStatically(String joinpointKind, Member member, - Class thisClass, Class targetClass, Member withinCode) { - if (withinCode == null) return FuzzyBoolean.NO; - return FuzzyBoolean.fromBoolean(signature.matches(Factory.makeEncSJP(withinCode))); - } - public void write(DataOutputStream s) throws IOException { s.writeByte(Pointcut.WITHINCODE); signature.write(s); @@ -128,10 +99,6 @@ public class WithincodePointcut extends Pointcut { } } - public void resolveBindingsFromRTTI() { - signature = signature.resolveBindingsFromRTTI(); - } - public void postRead(ResolvedType enclosingType) { signature.postRead(enclosingType); } diff --git a/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java b/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java new file mode 100644 index 000000000..f2807e4a0 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java @@ -0,0 +1,32 @@ +/* ******************************************************************* + * 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.Member; +import java.util.Set; + +import org.aspectj.weaver.ResolvedType; + +/** + * @author colyer + * Used in 1.4 code to access annotations safely + */ +public interface AnnotationFinder { + + Object getAnnotation(ResolvedType annotationType, Object onObject); + + Object getAnnotationFromMember(ResolvedType annotationType, Member aMember); + + Object getAnnotationFromClass(ResolvedType annotationType, Class aClass); + + Set/*UnresolvedType*/ getAnnotations(Member onMember); +} diff --git a/weaver/src/org/aspectj/weaver/reflect/JoinPointMatchImpl.java b/weaver/src/org/aspectj/weaver/reflect/JoinPointMatchImpl.java new file mode 100644 index 000000000..6fffd9b2c --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/JoinPointMatchImpl.java @@ -0,0 +1,53 @@ +/* ******************************************************************* + * 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 org.aspectj.weaver.tools.JoinPointMatch; +import org.aspectj.weaver.tools.PointcutParameter; + +/** + * @author colyer + * Implementation of JoinPointMatch for reflection based worlds. + */ +public class JoinPointMatchImpl implements JoinPointMatch { + + public static JoinPointMatch NO_MATCH = new JoinPointMatchImpl(); + private static PointcutParameter[] NO_BINDINGS = new PointcutParameter[0]; + + private boolean match; + private PointcutParameter[] bindings; + + public JoinPointMatchImpl(PointcutParameter[] bindings) { + this.match = true; + this.bindings = bindings; + } + + private JoinPointMatchImpl() { + this.match = false; + this.bindings = NO_BINDINGS; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.JoinPointMatch#matches() + */ + public boolean matches() { + return match; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.JoinPointMatch#getParameterBindings() + */ + public PointcutParameter[] getParameterBindings() { + return bindings; + } + +} diff --git a/weaver/src/org/aspectj/weaver/reflect/PointcutParameterImpl.java b/weaver/src/org/aspectj/weaver/reflect/PointcutParameterImpl.java new file mode 100644 index 000000000..722d64839 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/PointcutParameterImpl.java @@ -0,0 +1,43 @@ +/* ******************************************************************* + * 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 org.aspectj.weaver.tools.PointcutParameter; + +public class PointcutParameterImpl implements PointcutParameter { + + String name; + Class type; + Object binding; + + public PointcutParameterImpl(String name, Class type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public Class getType() { + return type; + } + + public Object getBinding() { + return binding; + } + + void setBinding(Object boundValue) { + this.binding = boundValue; + } + +}
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java new file mode 100644 index 000000000..e3fec7dc0 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java @@ -0,0 +1,313 @@ +/* ******************************************************************* + * 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.util.Collection; +import java.util.Collections; + +import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ReferenceTypeDelegate; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.TypeVariable; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.WeaverStateInfo; +import org.aspectj.weaver.World; +import org.aspectj.weaver.patterns.PerClause; + +/** + * @author colyer + * A delegate for a resolved type that uses runtime type information (java.lang.reflect) + * to answer questions. This class uses only Java 1.4 features to answer questions. + * In a Java 1.5 environment use the Java5ReflectionBasedReferenceTypeDelegate subtype. + */ +public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelegate { + + private Class myClass = null; + private World world; + private ReferenceType resolvedType; + private ResolvedMember[] fields = null; + private ResolvedMember[] methods = null; + private ResolvedType[] interfaces = null; + + public ReflectionBasedReferenceTypeDelegate(Class forClass, World inWorld, ReferenceType resolvedType) { + initialize(resolvedType,forClass,inWorld); + } + + /** for reflective construction only */ + public ReflectionBasedReferenceTypeDelegate() {} + + public void initialize(ReferenceType aType, Class aClass, World aWorld) { + this.myClass = aClass; + this.resolvedType = aType; + this.world = aWorld; + } + + protected Class getBaseClass() { + return this.myClass; + } + + protected World getWorld() { + return this.world; + } + + + public ReferenceType buildGenericType() { + throw new UnsupportedOperationException("Shouldn't be asking for generic type at 1.4 source level or lower"); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#addAnnotation(org.aspectj.weaver.AnnotationX) + */ + public void addAnnotation(AnnotationX annotationX) { + throw new UnsupportedOperationException("Cannot add an annotation to a reflection based delegate"); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isAspect() + */ + public boolean isAspect() { + // we could do better than this in Java 5 by looking at the annotations on the type... + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationStyleAspect() + */ + public boolean isAnnotationStyleAspect() { + // we could do better than this in Java 5 by looking at the annotations on the type... + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isInterface() + */ + public boolean isInterface() { + return this.myClass.isInterface(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isEnum() + */ + public boolean isEnum() { + // cant be an enum in Java 1.4 or prior + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotation() + */ + public boolean isAnnotation() { + // cant be an annotation in Java 1.4 or prior + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isAnnotationWithRuntimeRetention() + */ + public boolean isAnnotationWithRuntimeRetention() { + // cant be an annotation in Java 1.4 or prior + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isClass() + */ + public boolean isClass() { + return !this.myClass.isInterface() && !this.myClass.isPrimitive() && !this.myClass.isArray(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isGeneric() + */ + public boolean isGeneric() { + // cant be generic in 1.4 + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#isExposedToWeaver() + */ + public boolean isExposedToWeaver() { + // reflection based types are never exposed to the weaver + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#hasAnnotation(org.aspectj.weaver.UnresolvedType) + */ + public boolean hasAnnotation(UnresolvedType ofType) { + // in Java 1.4 we cant have an annotation + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotations() + */ + public AnnotationX[] getAnnotations() { + // no annotations in Java 1.4 + return new AnnotationX[0]; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getAnnotationTypes() + */ + public ResolvedType[] getAnnotationTypes() { + // no annotations in Java 1.4 + return new ResolvedType[0]; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredFields() + */ + public ResolvedMember[] getDeclaredFields() { + if (fields == null) { + Field[] reflectFields = this.myClass.getDeclaredFields(); + this.fields = new ResolvedMember[reflectFields.length]; + for (int i = 0; i < reflectFields.length; i++) { + this.fields[i] = + ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectFields[i], world); + } + } + return fields; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredInterfaces() + */ + public ResolvedType[] getDeclaredInterfaces() { + if (interfaces == null) { + Class[] reflectInterfaces = this.myClass.getInterfaces(); + this.interfaces = new ResolvedType[reflectInterfaces.length]; + for (int i = 0; i < reflectInterfaces.length; i++) { + this.interfaces[i] = world.resolve(reflectInterfaces[i].getName()); + } + } + return interfaces; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredMethods() + */ + public ResolvedMember[] getDeclaredMethods() { + if (methods == null) { + Method[] reflectMethods = this.myClass.getDeclaredMethods(); + Constructor[] reflectCons = this.myClass.getDeclaredConstructors(); + this.methods = new ResolvedMember[reflectMethods.length + reflectCons.length]; + for (int i = 0; i < reflectMethods.length; i++) { + this.methods[i] = + ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectMethods[i], world); + } + for (int i = 0; i < reflectCons.length; i++) { + this.methods[i + reflectMethods.length] = + ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectCons[i], world); + } + } + return methods; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredPointcuts() + */ + public ResolvedMember[] getDeclaredPointcuts() { + return new ResolvedMember[0]; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeVariables() + */ + public TypeVariable[] getTypeVariables() { + // no type variables in Java 1.4 + return new TypeVariable[0]; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getPerClause() + */ + public PerClause getPerClause() { + // no per clause... + return null; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclares() + */ + public Collection getDeclares() { + // no declares + return Collections.EMPTY_SET; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getTypeMungers() + */ + public Collection getTypeMungers() { + // no type mungers + return Collections.EMPTY_SET; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getPrivilegedAccesses() + */ + public Collection getPrivilegedAccesses() { + // no aspect members..., not used for weaving + return Collections.EMPTY_SET; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getModifiers() + */ + public int getModifiers() { + return this.myClass.getModifiers(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getSuperclass() + */ + public ResolvedType getSuperclass() { + if (this.myClass.getSuperclass() == null) return null; + return world.resolve(this.myClass.getSuperclass().getName()); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getWeaverState() + */ + public WeaverStateInfo getWeaverState() { + return null; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getResolvedTypeX() + */ + public ReferenceType getResolvedTypeX() { + return this.resolvedType; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#doesNotExposeShadowMungers() + */ + public boolean doesNotExposeShadowMungers() { + return false; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.ReferenceTypeDelegate#getDeclaredGenericSignature() + */ + public String getDeclaredGenericSignature() { + // no generic sig in 1.4 + return null; + } + +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java new file mode 100644 index 000000000..33d467415 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java @@ -0,0 +1,155 @@ +/* ******************************************************************* + * 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.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; + +/** + * @author colyer + * Creates the appropriate ReflectionBasedReferenceTypeDelegate according to + * the VM level we are running at. Uses reflection to avoid 1.5 dependencies in + * 1.4 and 1.3 code base. + */ +public class ReflectionBasedReferenceTypeDelegateFactory { + + public static ReflectionBasedReferenceTypeDelegate + createDelegate(ReferenceType forReferenceType, World inWorld) { + try { + Class c = Class.forName(forReferenceType.getName()); + if (LangUtil.is15VMOrGreater()) { + return create15Delegate(forReferenceType,c,inWorld); + } else { + return new ReflectionBasedReferenceTypeDelegate(c,inWorld,forReferenceType); + } + } catch (ClassNotFoundException cnfEx) { + return null; + } + } + + private static ReflectionBasedReferenceTypeDelegate create15Delegate(ReferenceType forReferenceType, Class forClass, World inWorld) { + try { + Class delegateClass = Class.forName("org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate"); + ReflectionBasedReferenceTypeDelegate ret = (ReflectionBasedReferenceTypeDelegate) delegateClass.newInstance(); + ret.initialize(forReferenceType,forClass,inWorld); + return ret; + } catch (ClassNotFoundException cnfEx) { + return null; + } catch (InstantiationException insEx) { + return null; + } catch (IllegalAccessException illAccEx) { + return null; + } + } + + /** + * convert a java.lang.reflect.Member into a resolved member in the world + * @param reflectMember + * @param inWorld + * @return + */ + public static ResolvedMember createResolvedMember(Member reflectMember, World inWorld) { + if (reflectMember instanceof Method) { + return createResolvedMethod((Method)reflectMember,inWorld); + } else if (reflectMember instanceof Constructor) { + return createResolvedConstructor((Constructor)reflectMember,inWorld); + } else { + return createResolvedField((Field)reflectMember,inWorld); + } + } + + public static ResolvedMember createResolvedMethod(Method aMethod, World inWorld) { + ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, + inWorld.resolve(aMethod.getDeclaringClass().getName()), + aMethod.getModifiers(), + inWorld.resolve(aMethod.getReturnType().getName()), + aMethod.getName(), + toResolvedTypeArray(aMethod.getParameterTypes(),inWorld), + toResolvedTypeArray(aMethod.getExceptionTypes(),inWorld), + aMethod + ); + return ret; + } + + public static ResolvedMember createResolvedAdviceMember(Method aMethod, World inWorld) { + return new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.ADVICE, + inWorld.resolve(aMethod.getDeclaringClass().getName()), + aMethod.getModifiers(), + inWorld.resolve(aMethod.getReturnType().getName()), + aMethod.getName(), + toResolvedTypeArray(aMethod.getParameterTypes(),inWorld), + toResolvedTypeArray(aMethod.getExceptionTypes(),inWorld), + aMethod + ); + } + + public static ResolvedMember createStaticInitMember(Class forType, World inWorld) { + return new ResolvedMemberImpl(org.aspectj.weaver.Member.STATIC_INITIALIZATION, + inWorld.resolve(forType.getName()), + Modifier.STATIC, + ResolvedType.VOID, + "<clinit>", + new UnresolvedType[0], + new UnresolvedType[0] + ); + } + + public static ResolvedMember createResolvedConstructor(Constructor aConstructor, World inWorld) { + return new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.CONSTRUCTOR, + inWorld.resolve(aConstructor.getDeclaringClass().getName()), + aConstructor.getModifiers(), + inWorld.resolve(aConstructor.getDeclaringClass().getName()), + "init", + toResolvedTypeArray(aConstructor.getParameterTypes(),inWorld), + toResolvedTypeArray(aConstructor.getExceptionTypes(),inWorld), + aConstructor + ); + } + + public static ResolvedMember createResolvedField(Field aField, World inWorld) { + return new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.FIELD, + inWorld.resolve(aField.getDeclaringClass().getName()), + aField.getModifiers(), + inWorld.resolve(aField.getType().getName()), + aField.getName(), + new UnresolvedType[0], + aField); + } + + public static ResolvedMember createHandlerMember(Class exceptionType, Class inType,World inWorld) { + return new ResolvedMemberImpl( + org.aspectj.weaver.Member.HANDLER, + inWorld.resolve(inType.getName()), + Modifier.STATIC, + "<catch>", + "(" + inWorld.resolve(exceptionType.getName()).getSignature() + ")V"); + } + + private static ResolvedType[] toResolvedTypeArray(Class[] classes, World inWorld) { + ResolvedType[] ret = new ResolvedType[classes.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = inWorld.resolve(classes[i].getName()); + } + return ret; + } +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java new file mode 100644 index 000000000..6380e6576 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java @@ -0,0 +1,133 @@ +/* ******************************************************************* + * 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.Member; + +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedMemberImpl; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; + +/** + * Subtype of ResolvedMemberImpl used in reflection world. + * Knows how to get annotations from a java.lang.reflect.Member + * + */ +public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { + + private static AnnotationFinder annotationFinder = null; + + static { + try { + Class java15AnnotationFinder = Class.forName("org.aspectj.weaver.reflect.Java15AnnotationFinder"); + annotationFinder = (AnnotationFinder) java15AnnotationFinder.newInstance(); + } catch(Exception ex) { + // must be on 1.4 or earlier + } + } + + private Member reflectMember; + + /** + * @param kind + * @param declaringType + * @param modifiers + * @param returnType + * @param name + * @param parameterTypes + */ + public ReflectionBasedResolvedMemberImpl(Kind kind, + UnresolvedType declaringType, int modifiers, + UnresolvedType returnType, String name, + UnresolvedType[] parameterTypes, + Member reflectMember) { + super(kind, declaringType, modifiers, returnType, name, parameterTypes); + this.reflectMember = reflectMember; + } + + /** + * @param kind + * @param declaringType + * @param modifiers + * @param returnType + * @param name + * @param parameterTypes + * @param checkedExceptions + */ + public ReflectionBasedResolvedMemberImpl(Kind kind, + UnresolvedType declaringType, int modifiers, + UnresolvedType returnType, String name, + UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions, + Member reflectMember) { + super(kind, declaringType, modifiers, returnType, name, parameterTypes, + checkedExceptions); + this.reflectMember = reflectMember; + } + + /** + * @param kind + * @param declaringType + * @param modifiers + * @param returnType + * @param name + * @param parameterTypes + * @param checkedExceptions + * @param backingGenericMember + */ + public ReflectionBasedResolvedMemberImpl(Kind kind, + UnresolvedType declaringType, int modifiers, + UnresolvedType returnType, String name, + UnresolvedType[] parameterTypes, + UnresolvedType[] checkedExceptions, + ResolvedMember backingGenericMember, + Member reflectMember) { + super(kind, declaringType, modifiers, returnType, name, parameterTypes, + checkedExceptions, backingGenericMember); + this.reflectMember = reflectMember; + } + + /** + * @param kind + * @param declaringType + * @param modifiers + * @param name + * @param signature + */ + public ReflectionBasedResolvedMemberImpl(Kind kind, + UnresolvedType declaringType, int modifiers, String name, + String signature, Member reflectMember) { + super(kind, declaringType, modifiers, name, signature); + this.reflectMember = reflectMember; + } + + public boolean hasAnnotation(UnresolvedType ofType) { + unpackAnnotations(); + return super.hasAnnotation(ofType); + } + + public boolean hasAnnotations() { + unpackAnnotations(); + return super.hasAnnotations(); + } + + public ResolvedType[] getAnnotationTypes() { + unpackAnnotations(); + return super.getAnnotationTypes(); + } + + private void unpackAnnotations() { + if (annotationTypes == null && annotationFinder != null) { + annotationTypes = annotationFinder.getAnnotations(reflectMember); + } + } +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionShadow.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionShadow.java new file mode 100644 index 000000000..35a1ace10 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionShadow.java @@ -0,0 +1,335 @@ +/* ******************************************************************* + * 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.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.ResolvedType; +import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; +import org.aspectj.weaver.ast.Var; + +/** + * @author colyer + * + */ +public class ReflectionShadow extends Shadow { + + private World world; + private ResolvedType enclosingType; + private ResolvedMember enclosingMember; + 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(); + + public static Shadow makeExecutionShadow(World inWorld, java.lang.reflect.Member forMethod) { + Kind kind = (forMethod instanceof Method) ? Shadow.MethodExecution : Shadow.ConstructorExecution; + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forMethod, inWorld); + ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld); + return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null); + } + + public static Shadow makeAdviceExecutionShadow(World inWorld, java.lang.reflect.Method forMethod) { + Kind kind = Shadow.AdviceExecution; + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedAdviceMember(forMethod, inWorld); + ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld); + return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null); + } + + public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, java.lang.reflect.Member withinCode) { + Shadow enclosingShadow = makeExecutionShadow(inWorld,withinCode); + 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 ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeCallShadow(World inWorld, java.lang.reflect.Member aMember, Class thisClass) { + Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, thisClass); + 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 ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeStaticInitializationShadow(World inWorld, Class forType) { + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(forType, inWorld); + ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld); + Kind kind = Shadow.StaticInitialization; + return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null); + } + + public static Shadow makePreInitializationShadow(World inWorld, Constructor forConstructor) { + Kind kind = Shadow.PreInitialization; + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld); + ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld); + return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null); + } + + public static Shadow makeInitializationShadow(World inWorld, Constructor forConstructor) { + Kind kind = Shadow.Initialization; + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forConstructor, inWorld); + ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld); + return new ReflectionShadow(inWorld,kind,signature,null,enclosingType,null); + } + + public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, Class withinType) { + Kind kind = Shadow.ExceptionHandler; + Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, withinType); + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinType, inWorld); + ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(withinType, inWorld); + ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld); + return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeHandlerShadow(World inWorld, Class exceptionType, java.lang.reflect.Member withinCode) { + Kind kind = Shadow.ExceptionHandler; + Shadow enclosingShadow = makeExecutionShadow(inWorld, withinCode); + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createHandlerMember(exceptionType, withinCode.getDeclaringClass(), inWorld); + ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(withinCode, inWorld); + ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld); + return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeFieldGetShadow(World inWorld, Field forField, Class callerType) { + Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType); + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld); + ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld); + ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld); + Kind kind = Shadow.FieldGet; + return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeFieldGetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember) { + Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember); + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld); + ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld); + ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld); + Kind kind = Shadow.FieldGet; + return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeFieldSetShadow(World inWorld, Field forField, Class callerType) { + Shadow enclosingShadow = makeStaticInitializationShadow(inWorld, callerType); + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld); + ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createStaticInitMember(callerType, inWorld); + ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld); + Kind kind = Shadow.FieldSet; + return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public static Shadow makeFieldSetShadow(World inWorld, Field forField, java.lang.reflect.Member inMember) { + Shadow enclosingShadow = makeExecutionShadow(inWorld,inMember); + Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedField(forField, inWorld); + ResolvedMember enclosingMember = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(inMember, inWorld); + ResolvedType enclosingType = enclosingMember.getDeclaringType().resolve(inWorld); + Kind kind = Shadow.FieldSet; + return new ReflectionShadow(inWorld,kind,signature,enclosingShadow,enclosingType,enclosingMember); + } + + public ReflectionShadow(World world, Kind kind, Member signature, Shadow enclosingShadow, ResolvedType enclosingType, ResolvedMember enclosingMember) { + super(kind,signature,enclosingShadow); + this.world = world; + this.enclosingType = enclosingType; + this.enclosingMember = enclosingMember; + } + + /* (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)); + } + return thisVar; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.Shadow#getTargetVar() + */ + public Var getTargetVar() { + if (targetVar == null && hasTarget()) { + targetVar = ReflectionVar.createTargetVar(getThisType().resolve(world)); + } + 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); + } + } + 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); + 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); + 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); + 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)); + } + 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)); + } + 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); + } + 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; + } + +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionVar.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionVar.java new file mode 100644 index 000000000..5fda4c347 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionVar.java @@ -0,0 +1,163 @@ +/* ******************************************************************* + * 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.Member; + +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ast.Var; + +/** + * A variable at a reflection shadow, used by the residual tests. + */ +public class ReflectionVar extends Var { + + static final int THIS_VAR = 0; + static final int TARGET_VAR = 1; + static final int ARGS_VAR = 2; + static final int AT_THIS_VAR = 3; + static final int AT_TARGET_VAR = 4; + static final int AT_ARGS_VAR = 5; + static final int AT_WITHIN_VAR = 6; + static final int AT_WITHINCODE_VAR = 7; + static final int AT_ANNOTATION_VAR = 8; + + private static AnnotationFinder annotationFinder = null; + + static { + try { + Class java15AnnotationFinder = Class.forName("org.aspectj.weaver.reflect.Java15AnnotationFinder"); + annotationFinder = (AnnotationFinder) java15AnnotationFinder.newInstance(); + } catch(Exception ex) { + // must be on 1.4 or earlier + } + } + + private int argsIndex = 0; + private int varType; + + public static ReflectionVar createThisVar(ResolvedType type) { + ReflectionVar ret = new ReflectionVar(type); + ret.varType = THIS_VAR; + return ret; + } + + public static ReflectionVar createTargetVar(ResolvedType type) { + ReflectionVar ret = new ReflectionVar(type); + ret.varType = TARGET_VAR; + return ret; + } + + public static ReflectionVar createArgsVar(ResolvedType type, int index) { + ReflectionVar ret = new ReflectionVar(type); + ret.varType = ARGS_VAR; + ret.argsIndex = index; + return ret; + } + + public static ReflectionVar createThisAnnotationVar(ResolvedType type) { + ReflectionVar ret = new ReflectionVar(type); + ret.varType = AT_THIS_VAR; + return ret; + } + + public static ReflectionVar createTargetAnnotationVar(ResolvedType type) { + ReflectionVar ret = new ReflectionVar(type); + ret.varType = AT_TARGET_VAR; + return ret; + } + + public static ReflectionVar createArgsAnnotationVar(ResolvedType type, int index) { + ReflectionVar ret = new ReflectionVar(type); + ret.varType = AT_ARGS_VAR; + ret.argsIndex = index; + return ret; + } + + public static ReflectionVar createWithinAnnotationVar(ResolvedType annType) { + ReflectionVar ret = new ReflectionVar(annType); + ret.varType = AT_WITHIN_VAR; + return ret; + } + + public static ReflectionVar createWithinCodeAnnotationVar(ResolvedType annType) { + ReflectionVar ret = new ReflectionVar(annType); + ret.varType = AT_WITHINCODE_VAR; + return ret; + } + + public static ReflectionVar createAtAnnotationVar(ResolvedType annType) { + ReflectionVar ret = new ReflectionVar(annType); + ret.varType = AT_ANNOTATION_VAR; + return ret; + } + + private ReflectionVar(ResolvedType type) { + super(type); + } + + + public Object getBindingAtJoinPoint(Object thisObject, Object targetObject, Object[] args) { + return getBindingAtJoinPoint(thisObject,targetObject,args,null,null,null); + } + /** + * At a join point with the given this, target, and args, return the object to which this + * var is bound. + * @param thisObject + * @param targetObject + * @param args + * @return + */ + public Object getBindingAtJoinPoint( + Object thisObject, + Object targetObject, + Object[] args, + Member subject, + Member withinCode, + Class withinType) { + switch( this.varType) { + case THIS_VAR: return thisObject; + case TARGET_VAR: return targetObject; + case ARGS_VAR: + if (this.argsIndex > (args.length - 1)) return null; + return args[argsIndex]; + case AT_THIS_VAR: + if (annotationFinder != null) { + return annotationFinder.getAnnotation(getType(), thisObject); + } else return null; + case AT_TARGET_VAR: + if (annotationFinder != null) { + return annotationFinder.getAnnotation(getType(), targetObject); + } else return null; + case AT_ARGS_VAR: + if (this.argsIndex > (args.length - 1)) return null; + if (annotationFinder != null) { + return annotationFinder.getAnnotation(getType(), args[argsIndex]); + } else return null; + case AT_WITHIN_VAR: + if (annotationFinder != null) { + return annotationFinder.getAnnotationFromClass(getType(), withinType); + } else return null; + case AT_WITHINCODE_VAR: + if (annotationFinder != null) { + return annotationFinder.getAnnotationFromMember(getType(), withinCode); + } else return null; + case AT_ANNOTATION_VAR: + if (annotationFinder != null) { + return annotationFinder.getAnnotationFromMember(getType(), subject); + } else return null; + } + + return null; + } + +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java new file mode 100644 index 000000000..3fd57314f --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java @@ -0,0 +1,119 @@ +/* ******************************************************************* + * 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 org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.ConcreteTypeMunger; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ReferenceTypeDelegate; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ResolvedTypeMunger; +import org.aspectj.weaver.World; +import org.aspectj.weaver.AjAttribute.AdviceAttribute; +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.PerClause.Kind; + +/** + * A ReflectionWorld is used solely for purposes of type resolution based on + * the runtime classpath (java.lang.reflect). It does not support weaving operations + * (creation of mungers etc..). + * + */ +public class ReflectionWorld extends World { + + public ReflectionWorld() { + super(); + this.setMessageHandler(new ExceptionBasedMessageHandler()); + setBehaveInJava5Way(LangUtil.is15VMOrGreater()); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.World#resolveDelegate(org.aspectj.weaver.ReferenceType) + */ + protected ReferenceTypeDelegate resolveDelegate(ReferenceType ty) { + return ReflectionBasedReferenceTypeDelegateFactory.createDelegate(ty, this); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.World#createAdviceMunger(org.aspectj.weaver.AjAttribute.AdviceAttribute, org.aspectj.weaver.patterns.Pointcut, org.aspectj.weaver.Member) + */ + public Advice createAdviceMunger(AdviceAttribute attribute, + Pointcut pointcut, Member signature) { + throw new UnsupportedOperationException("Cannot create advice munger in ReflectionWorld"); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.World#makeCflowStackFieldAdder(org.aspectj.weaver.ResolvedMember) + */ + public ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField) { + throw new UnsupportedOperationException("Cannot create cflow stack in ReflectionWorld"); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.World#makeCflowCounterFieldAdder(org.aspectj.weaver.ResolvedMember) + */ + public ConcreteTypeMunger makeCflowCounterFieldAdder( + ResolvedMember cflowField) { + throw new UnsupportedOperationException("Cannot create cflow counter in ReflectionWorld"); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.World#makePerClauseAspect(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind) + */ + public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, Kind kind) { + throw new UnsupportedOperationException("Cannot create per clause in ReflectionWorld"); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.World#concreteTypeMunger(org.aspectj.weaver.ResolvedTypeMunger, org.aspectj.weaver.ResolvedType) + */ + public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, + ResolvedType aspectType) { + throw new UnsupportedOperationException("Cannot create type munger in ReflectionWorld"); + } + + public static class ReflectionWorldException extends RuntimeException { + + private static final long serialVersionUID = -3432261918302793005L; + + public ReflectionWorldException(String message) { + super(message); + } + } + + private static class ExceptionBasedMessageHandler implements IMessageHandler { + + public boolean handleMessage(IMessage message) throws AbortException { + throw new ReflectionWorldException(message.toString()); + } + + public boolean isIgnoring(org.aspectj.bridge.IMessage.Kind kind) { + if (kind == IMessage.INFO) { + return true; + } else { + return false; + } + } + + public void dontIgnore(org.aspectj.bridge.IMessage.Kind kind) { + // empty + } + + } + +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ShadowMatchImpl.java b/weaver/src/org/aspectj/weaver/reflect/ShadowMatchImpl.java new file mode 100644 index 000000000..1cc631e77 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/ShadowMatchImpl.java @@ -0,0 +1,171 @@ +/* ******************************************************************* + * 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.Member; + +import org.aspectj.util.FuzzyBoolean; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.World; +import org.aspectj.weaver.ast.And; +import org.aspectj.weaver.ast.Call; +import org.aspectj.weaver.ast.FieldGetCall; +import org.aspectj.weaver.ast.HasAnnotation; +import org.aspectj.weaver.ast.ITestVisitor; +import org.aspectj.weaver.ast.Instanceof; +import org.aspectj.weaver.ast.Literal; +import org.aspectj.weaver.ast.Not; +import org.aspectj.weaver.ast.Or; +import org.aspectj.weaver.ast.Test; +import org.aspectj.weaver.ast.Var; +import org.aspectj.weaver.patterns.ExposedState; +import org.aspectj.weaver.tools.JoinPointMatch; +import org.aspectj.weaver.tools.PointcutParameter; +import org.aspectj.weaver.tools.ShadowMatch; + +/** + * @author colyer + * Implementation of ShadowMatch for reflection based worlds. + */ +public class ShadowMatchImpl implements ShadowMatch { + + private FuzzyBoolean match; + private ExposedState state; + private Test residualTest; + private PointcutParameter[] params; + private Member withinCode; + private Member subject; + private Class withinType; + + public ShadowMatchImpl(FuzzyBoolean match, Test test, ExposedState state, PointcutParameter[] params) { + this.match = match; + this.residualTest = test; + this.state = state; + this.params = params; + } + + public void setWithinCode(Member aMember) { this.withinCode = aMember; } + public void setSubject(Member aMember) { this.subject = aMember; } + public void setWithinType(Class aClass) { this.withinType = aClass; } + + public boolean alwaysMatches() { + return match.alwaysTrue(); + } + + public boolean maybeMatches() { + return match.maybeTrue(); + } + + public boolean neverMatches() { + return match.alwaysFalse(); + } + + public JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args) { + if (neverMatches()) return JoinPointMatchImpl.NO_MATCH; + if (new RuntimeTestEvaluator(residualTest,thisObject,targetObject,args).matches()) { + return new JoinPointMatchImpl(getPointcutParameters(thisObject,targetObject,args)); + } else { + return JoinPointMatchImpl.NO_MATCH; + } + } + + private PointcutParameter[] getPointcutParameters(Object thisObject, Object targetObject, Object[] args) { + Var[] vars = state.vars; + PointcutParameterImpl[] bindings = new PointcutParameterImpl[params.length]; + for (int i = 0; i < bindings.length; i++) { + bindings[i] = new PointcutParameterImpl(params[i].getName(),params[i].getType()); + bindings[i].setBinding(((ReflectionVar)vars[i]).getBindingAtJoinPoint(thisObject, targetObject, args,subject,withinCode,withinType)); + } + return bindings; + } + + private static class RuntimeTestEvaluator implements ITestVisitor { + + private boolean matches = true; + private Test test; + private Object thisObject; + private Object targetObject; + private Object[] args; + + public RuntimeTestEvaluator(Test aTest,Object thisObject, Object targetObject, Object[] args) { + this.test = aTest; + this.thisObject = thisObject; + this.targetObject = targetObject; + this.args = args; + } + + public boolean matches() { + test.accept(this); + return matches; + } + + public void visit(And e) { + boolean leftMatches = + new RuntimeTestEvaluator(e.getLeft(),thisObject,targetObject,args).matches(); + if (!leftMatches) { + matches = false; + } else { + matches = new RuntimeTestEvaluator(e.getRight(),thisObject,targetObject,args).matches(); + } + } + + public void visit(Instanceof i) { + ReflectionVar v = (ReflectionVar) i.getVar(); + Object value = v.getBindingAtJoinPoint(thisObject,targetObject, args); + World world = v.getType().getWorld(); + ResolvedType desiredType = i.getType().resolve(world); + ResolvedType actualType = world.resolve(value.getClass().getName()); + matches = desiredType.isAssignableFrom(actualType); + } + + public void visit(Not not) { + matches = ! new RuntimeTestEvaluator(not.getBody(),thisObject,targetObject,args).matches(); + } + + public void visit(Or or) { + boolean leftMatches = + new RuntimeTestEvaluator(or.getLeft(),thisObject,targetObject,args).matches(); + if (leftMatches) { + matches = true; + } else { + matches = new RuntimeTestEvaluator(or.getRight(),thisObject,targetObject,args).matches(); + } + } + + public void visit(Literal literal) { + if (literal == Literal.FALSE) { + matches = false; + } else { + matches = true; + } + } + + public void visit(Call call) { + throw new UnsupportedOperationException("Can't evaluate call test at runtime"); + } + + public void visit(FieldGetCall fieldGetCall) { + throw new UnsupportedOperationException("Can't evaluate fieldGetCall test at runtime"); + } + + public void visit(HasAnnotation hasAnnotation) { + ReflectionVar v = (ReflectionVar) hasAnnotation.getVar(); + Object value = v.getBindingAtJoinPoint(thisObject,targetObject, args); + World world = v.getType().getWorld(); + ResolvedType actualVarType = world.resolve(value.getClass().getName()); + ResolvedType requiredAnnotationType = hasAnnotation.getAnnotationType().resolve(world); + matches = actualVarType.hasAnnotation(requiredAnnotationType); + } + + } + +} diff --git a/weaver/src/org/aspectj/weaver/tools/JoinPointMatch.java b/weaver/src/org/aspectj/weaver/tools/JoinPointMatch.java new file mode 100644 index 000000000..588b3c0bc --- /dev/null +++ b/weaver/src/org/aspectj/weaver/tools/JoinPointMatch.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * 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.tools; + +/** + * @author colyer + * The result of asking a ShadowMatch to match at a given join point. + */ +public interface JoinPointMatch { + + /** + * True if the pointcut expression has matched at this join point, and false + * otherwise + */ + boolean matches(); + + /** + * Get the parameter bindings at the matched join point. + * If the join point was not matched an empty array is returned. + */ + PointcutParameter[] getParameterBindings(); +} diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java b/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java index 2f3a09e4a..64d82a96a 100644 --- a/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java +++ b/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java @@ -36,142 +36,159 @@ public interface PointcutExpression { boolean mayNeedDynamicTest(); /** - * Determine whether or not this pointcut matches a method call to the given method. - * @param aMethod the method being called - * @param thisClass the type making the method call - * @param targetClass the static type of the target of the call - * (may be a subtype of aMethod.getDeclaringClass() ) - * @param withinCode the Method or Constructor from within which the call is made - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the runtime - * types of the arguments, caller, and called object. - */ - FuzzyBoolean matchesMethodCall(Method aMethod, Class thisClass, Class targetClass, Member withinCode); - - /** * Determine whether or not this pointcut matches the execution of a given method. * @param aMethod the method being executed - * @param thisClass the static type of the object in which the method is executing - * (may be a subtype of aMethod.getDeclaringClass()) - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the - * runtime types of the arguments and executing object. + * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never + * matches join points representing the execution of the method. */ - FuzzyBoolean matchesMethodExecution(Method aMethod, Class thisClass); - - /** - * Determine whether or not this pointcut matches a call to the given constructor. - * @param aConstructor the constructor being called - * @param thisClass the type making the constructor call - * @param withinCode the Method or Constructor from within which the call is made - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the runtime - * types of the arguments and caller. - */ - FuzzyBoolean matchesConstructorCall(Constructor aConstructor, Class thisClass, Member withinCode); + ShadowMatch matchesMethodExecution(Method aMethod ); /** * Determine whether or not this pointcut matches the execution of a given constructor. * @param aConstructor the constructor being executed - * @param thisClass the static type of the object in which the constructor is executing - * (may be a subtype of aConstructor.getDeclaringClass()) - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the - * runtime types of the arguments and executing object. - */ - FuzzyBoolean matchesConstructorExecution(Constructor aConstructor, Class thisClass); + * @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 execution of a given piece of advice. * @param anAdviceMethod a method representing the advice being executed - * @param thisClass the static type of the aspect in which the advice is executing - * (may be a subtype of anAdviceMethod.getDeclaringClass()) - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the - * runtime type of the executing aspect. + * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never + * matches join points representing the execution of the advice. */ - FuzzyBoolean matchesAdviceExecution(Method anAdviceMethod, Class thisClass); - - /** - * Determine whether or not this pointcut matches the execution of a given exception - * handler - * @param exceptionType the static type of the exception being handled - * @param inClass the class in which the catch block is declared - * @param withinCode the method or constructor in which the catch block is declared - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the - * runtime types of the exception and exception-handling object. - */ - FuzzyBoolean matchesHandler(Class exceptionType, Class inClass, Member withinCode); + 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 FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the - * runtime types of the arguments. + * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never + * matches join points representing initialization via the given constructor. */ - FuzzyBoolean matchesInitialization(Constructor aConstructor); + ShadowMatch matchesInitialization(Constructor aConstructor); /** - * Determine whether or not this pointcut matches the preinitialization of an + * 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 FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the - * runtime types of the arguments. + * @return a ShadowMatch indicating whether the pointcut always, sometimes, or never + * matches join points representing pre-initialization via the given constructor. */ - FuzzyBoolean matchesPreInitialization(Constructor aConstructor); + ShadowMatch matchesPreInitialization(Constructor aConstructor); /** - * Determine whether or not this pointcut matches the static initialization - * of the given class. - * @param aClass the class being statically initialized - * @return FuzzyBoolean.YES is the pointcut always matches, FuzzyBoolean.NO if the - * pointcut never matches. + * 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. */ - FuzzyBoolean matchesStaticInitialization(Class aClass); + 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. + * 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 thisClass the type sending the update message - * @param targetClass the static type of the target of the field update message - * (may be a subtype of aField.getDeclaringClass() ) - * @param withinCode the Method or Constructor from within which the update message is sent - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the runtime - * types of the caller and called object. + * @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. */ - FuzzyBoolean matchesFieldSet(Field aField, Class thisClass, Class targetClass, Member withinCode); + ShadowMatch matchesFieldSet(Field aField, Member withinCode); /** - * Determine whether or not this pointcut matches a get of the given field. - * @param aField the field being accessed - * @param thisClass the type accessing the field - * @param targetClass the static type of the target of the field access message - * (may be a subtype of aField.getDeclaringClass() ) - * @param withinCode the Method or Constructor from within which the field is accessed - * @return a FuzzyBoolean indicating whether the pointcut always matches such a join point (YES), - * never matches such a join point (NO), or may match such a join point (MAYBE) depending on the runtime - * types of the caller and called object. + * 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. */ - FuzzyBoolean matchesFieldGet(Field aField, Class thisClass, Class targetClass, Member withinCode); + ShadowMatch matchesFieldSet(Field aField, Class withinType); /** - * Returns true iff the dynamic portions of the pointcut expression (this, target, and - * args) match the given this, target, and args objects. This method only needs to be - * called if a previous call to a FuzzyBoolean-returning matching method returned - * FuzzyBoolean.MAYBE. Even if this method returns true, the pointcut can only be - * considered to match the join point if the appropriate matches method for the join - * point kind has also returned FuzzyBoolean.YES or FuzzyBoolean.MAYBE. - * @param thisObject - * @param targetObject - * @param args - * @return + * 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. */ - boolean matchesDynamically(Object thisObject, Object targetObject, Object[] args); + ShadowMatch matchesFieldGet(Field aField, Class withinType); /** * Return a string representation of this pointcut expression. diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutParameter.java b/weaver/src/org/aspectj/weaver/tools/PointcutParameter.java new file mode 100644 index 000000000..a0eaa108a --- /dev/null +++ b/weaver/src/org/aspectj/weaver/tools/PointcutParameter.java @@ -0,0 +1,36 @@ +/* ******************************************************************* + * 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.tools; + +/** + * @author colyer + * Represents a parameter in a pointcut expression. + * For example pointcut pc(String s) : .....; has a PointcutParameter of + * name "s" and type String. + */ +public interface PointcutParameter { + + /** + * The name of this parameter + */ + String getName(); + + /** + * The type of the parameter + */ + Class getType(); + + /** + * At a matched join point, the parameter binding. + */ + Object getBinding(); +} diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java index a7c5c91d6..ef42e89e3 100644 --- a/weaver/src/org/aspectj/weaver/tools/PointcutParser.java +++ b/weaver/src/org/aspectj/weaver/tools/PointcutParser.java @@ -10,22 +10,38 @@ *******************************************************************************/ package org.aspectj.weaver.tools; +import java.io.File; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.SourceLocation; 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.bcel.AtAjAttributes; import org.aspectj.weaver.internal.tools.PointcutExpressionImpl; 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.reflect.PointcutParameterImpl; +import org.aspectj.weaver.reflect.ReflectionWorld; /** * A PointcutParser can be used to build PointcutExpressions for a @@ -33,6 +49,7 @@ import org.aspectj.weaver.patterns.ThisOrTargetPointcut; */ public class PointcutParser { + private static World world = new ReflectionWorld(); private Set supportedPrimitives; /** @@ -56,6 +73,14 @@ public class PointcutParser { 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; } @@ -100,9 +125,14 @@ public class PointcutParser { } } + 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 @@ -110,16 +140,51 @@ public class PointcutParser { */ public PointcutExpression parsePointcutExpression(String expression) throws UnsupportedPointcutPrimitiveException, IllegalArgumentException { - PointcutExpressionImpl pcExpr = null; - try { - Pointcut pc = new PatternParser(expression).parsePointcut(); - validateAgainstSupportedPrimitives(pc,expression); - pc.resolve(); - pcExpr = new PointcutExpressionImpl(pc,expression); - } catch (ParserException pEx) { - throw new IllegalArgumentException(buildUserMessageFromParserException(expression,pEx)); - } - return pcExpr; + 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 PointcutExpression parsePointcutExpression( + String expression, + Class inScope, + PointcutParameter[] formalParameters) + throws UnsupportedPointcutPrimitiveException, IllegalArgumentException { + PointcutExpressionImpl pcExpr = null; + try { + Pointcut pc = new PatternParser(expression).parsePointcut(); + validateAgainstSupportedPrimitives(pc,expression); + IScope resolutionScope = buildResolutionScope((inScope == null ? Object.class : inScope),formalParameters); + pc = pc.resolve(resolutionScope); + ResolvedType declaringTypeForResolution = null; + if (inScope != null) { + declaringTypeForResolution = world.resolve(inScope.getName()); + } else { + declaringTypeForResolution = ResolvedType.OBJECT.resolve(world); + } + IntMap arity = new IntMap(formalParameters.length); + for (int i = 0; i < formalParameters.length; i++) { + arity.put(i, i); + } + pc = pc.concretize(declaringTypeForResolution, declaringTypeForResolution, arity); + validateAgainstSupportedPrimitives(pc,expression); // again, because we have now followed any ref'd pcuts + pcExpr = new PointcutExpressionImpl(pc,expression,formalParameters,world); + } catch (ParserException pEx) { + throw new IllegalArgumentException(buildUserMessageFromParserException(expression,pEx)); + } catch (ReflectionWorld.ReflectionWorldException rwEx) { + throw new IllegalArgumentException(rwEx.getMessage()); + } + return pcExpr; } /* for testing */ @@ -127,6 +192,38 @@ public class PointcutParser { return supportedPrimitives; } + /* for testing */ + IMessageHandler setCustomMessageHandler(IMessageHandler aHandler) { + IMessageHandler current = world.getMessageHandler(); + world.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(UnresolvedType.forName(formalParameters[i].getType().getName()),formalParameters[i].getName(),i); + } + if (inScope == null) { + return new SimpleScope(world,formalBindings); + } else { + ResolvedType inType = world.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; + } + }; + return new AtAjAttributes.BindingScope(inType,sourceContext,formalBindings); + } + } + private void validateAgainstSupportedPrimitives(Pointcut pc, String expression) { switch(pc.getPointcutKind()) { case Pointcut.AND: @@ -162,8 +259,6 @@ public class PointcutParser { validateAgainstSupportedPrimitives(((OrPointcut)pc).getLeft(),expression); validateAgainstSupportedPrimitives(((OrPointcut)pc).getRight(),expression); break; - case Pointcut.REFERENCE: - throw new UnsupportedPointcutPrimitiveException(expression, PointcutPrimitive.REFERENCE); case Pointcut.THIS_OR_TARGET: boolean isThis = ((ThisOrTargetPointcut)pc).isThis(); if (isThis && !supportedPrimitives.contains(PointcutPrimitive.THIS)) { @@ -180,6 +275,34 @@ public class PointcutParser { 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.NONE: // deliberate fall-through default: throw new IllegalArgumentException("Unknown pointcut kind: " + pc.getPointcutKind()); diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java b/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java index cd357e743..a4f96888c 100644 --- a/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java +++ b/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java @@ -36,6 +36,12 @@ public class PointcutPrimitive extends TypeSafeEnum { public static final PointcutPrimitive TARGET = new PointcutPrimitive("target",16); public static final PointcutPrimitive ARGS = new PointcutPrimitive("args",17); public static final PointcutPrimitive REFERENCE = new PointcutPrimitive("reference pointcut",18); + public static final PointcutPrimitive AT_ANNOTATION = new PointcutPrimitive("@annotation",19); + public static final PointcutPrimitive AT_THIS = new PointcutPrimitive("@this",20); + public static final PointcutPrimitive AT_TARGET = new PointcutPrimitive("@target",21); + public static final PointcutPrimitive AT_ARGS = new PointcutPrimitive("@args",22); + public static final PointcutPrimitive AT_WITHIN = new PointcutPrimitive("@within",23); + public static final PointcutPrimitive AT_WITHINCODE = new PointcutPrimitive("@withincode",24); private PointcutPrimitive(String name, int key) { super(name, key); diff --git a/weaver/src/org/aspectj/weaver/tools/ShadowMatch.java b/weaver/src/org/aspectj/weaver/tools/ShadowMatch.java new file mode 100644 index 000000000..85170f451 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/tools/ShadowMatch.java @@ -0,0 +1,51 @@ +/* ******************************************************************* + * 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.tools; + +/** + * The result of asking a PointcutExpression to match at a shadow (method execution, + * handler, constructor call, and so on). + * + */ +public interface ShadowMatch { + + /** + * True iff the pointcut expression will match any join point at this + * shadow (for example, any call to the given method). + */ + boolean alwaysMatches(); + + /** + * True if the pointcut expression may match some join points at this + * shadow (for example, some calls to the given method may match, depending + * on the type of the caller). + * <p>If alwaysMatches is true, then maybeMatches is always true.</p> + */ + boolean maybeMatches(); + + /** + * True iff the pointcut expression can never match any join point at this + * shadow (for example, the pointcut will never match a call to the given + * method). + */ + boolean neverMatches(); + + /** + * Return the result of matching a join point at this shadow with the given + * this, target, and args. + * @param thisObject the object bound to this at the join point + * @param targetObject the object bound to target at the join point + * @param args the arguments at the join point + * @return + */ + JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args); +} diff --git a/weaver/testsrc/BcweaverModuleTests15.java b/weaver/testsrc/BcweaverModuleTests15.java index dce28d325..4ca66cc11 100644 --- a/weaver/testsrc/BcweaverModuleTests15.java +++ b/weaver/testsrc/BcweaverModuleTests15.java @@ -20,6 +20,7 @@ import org.aspectj.weaver.TypeVariableReferenceTypeTestCase; import org.aspectj.weaver.TypeVariableTestCase; import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXTestCase; import org.aspectj.weaver.patterns.WildTypePatternResolutionTestCase; +import org.aspectj.weaver.tools.Java15PointcutExpressionTest; public class BcweaverModuleTests15 extends TestCase { public static Test suite() { @@ -31,6 +32,7 @@ public class BcweaverModuleTests15 extends TestCase { suite.addTestSuite(MemberTestCase15.class); suite.addTestSuite(BcelGenericSignatureToTypeXTestCase.class); suite.addTestSuite(WildTypePatternResolutionTestCase.class); + suite.addTestSuite(Java15PointcutExpressionTest.class); return suite; } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java index ddb00a318..1e6176714 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java @@ -70,31 +70,6 @@ public class AndOrNotTestCase extends TestCase { } - public void testJoinPointMatch() { - Pointcut foo = makePointcut("this(org.aspectj.weaver.patterns.AndOrNotTestCase.Foo)").resolve(); - Pointcut bar = makePointcut("this(org.aspectj.weaver.patterns.AndOrNotTestCase.Bar)").resolve(); - Pointcut c = makePointcut("this(org.aspectj.weaver.patterns.AndOrNotTestCase.C)").resolve(); - - Factory f = new Factory("AndOrNotTestCase.java",AndOrNotTestCase.class); - - Signature methodSig = f.makeMethodSig("void aMethod()"); - JoinPoint.StaticPart jpsp = f.makeSJP(JoinPoint.METHOD_EXECUTION,methodSig,1); - JoinPoint jp = Factory.makeJP(jpsp,new Foo(),new Foo()); - - checkMatches(new AndPointcut(foo,bar),jp,null,FuzzyBoolean.NO); - checkMatches(new AndPointcut(foo,foo),jp,null,FuzzyBoolean.YES); - checkMatches(new AndPointcut(bar,foo),jp,null,FuzzyBoolean.NO); - checkMatches(new AndPointcut(bar,c),jp,null,FuzzyBoolean.NO); - - checkMatches(new OrPointcut(foo,bar),jp,null,FuzzyBoolean.YES); - checkMatches(new OrPointcut(foo,foo),jp,null,FuzzyBoolean.YES); - checkMatches(new OrPointcut(bar,foo),jp,null,FuzzyBoolean.YES); - checkMatches(new OrPointcut(bar,c),jp,null,FuzzyBoolean.NO); - - checkMatches(new NotPointcut(foo),jp,null,FuzzyBoolean.NO); - checkMatches(new NotPointcut(bar),jp,null,FuzzyBoolean.YES); - } - private Pointcut makePointcut(String pattern) { return new PatternParser(pattern).parsePointcut(); } @@ -104,32 +79,6 @@ public class AndOrNotTestCase extends TestCase { checkSerialization(pattern); } - private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(jp,jpsp)); - } - -// private void checkMatch(Pointcut p, Signature[] matches, boolean shouldMatch) { -// for (int i=0; i<matches.length; i++) { -// boolean result = p.matches(matches[i]); -// String msg = "matches " + p + " to " + matches[i] + " expected "; -// if (shouldMatch) { -// assertTrue(msg + shouldMatch, result); -// } else { -// assertTrue(msg + shouldMatch, !result); -// } -// } -// } -// -// public void testSerialization() throws IOException { -// String[] patterns = new String[] { -// "public * *(..)", "void *.foo(A, B)", "A b()" -// }; -// -// for (int i=0, len=patterns.length; i < len; i++) { -// checkSerialization(patterns[i]); -// } -// } - /** * Method checkSerialization. * @param string diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java index fd1bc3700..31313556f 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java @@ -10,11 +10,16 @@ *******************************************************************************/ package org.aspectj.weaver.patterns; +import java.lang.reflect.Method; + import junit.framework.TestCase; -import org.aspectj.lang.JoinPoint; -import org.aspectj.runtime.reflect.Factory; -import org.aspectj.util.FuzzyBoolean; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.tools.JoinPointMatch; +import org.aspectj.weaver.tools.PointcutExpression; +import org.aspectj.weaver.tools.PointcutParameter; +import org.aspectj.weaver.tools.PointcutParser; +import org.aspectj.weaver.tools.ShadowMatch; /** * @author colyer @@ -22,92 +27,135 @@ import org.aspectj.util.FuzzyBoolean; */ public class ArgsTestCase extends TestCase { - Pointcut wildcardArgs; - Pointcut oneA; - Pointcut oneAandaC; - Pointcut BthenAnything; - Pointcut singleArg; + PointcutExpression wildcardArgs; + PointcutExpression oneA; + PointcutExpression oneAandaC; + PointcutExpression BthenAnything; + PointcutExpression singleArg; - public void testMatchJP() { - Factory f = new Factory("ArgsTestCase.java",ArgsTestCase.A.class); - - JoinPoint.StaticPart jpsp1 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {A.class},new String[] {"a"},new Class[] {},null) ,1); - JoinPoint.StaticPart jpsp2 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {B.class},new String[] {"b"},new Class[] {},null),1); - JoinPoint.StaticPart jpsp3 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {A.class,C.class},new String[] {"a","c"},new Class[] {},null),1); - JoinPoint.StaticPart jpsp4 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {A.class,A.class},new String[] {"a","a2"},new Class[] {},null),1); - JoinPoint oneAArg = Factory.makeJP(jpsp1,new A(),new A(),new A()); - JoinPoint oneBArg = Factory.makeJP(jpsp2,new A(), new A(), new B()); - JoinPoint acArgs = Factory.makeJP(jpsp3,new A(), new A(), new A(), new C()); - JoinPoint baArgs = Factory.makeJP(jpsp4,new A(), new A(), new B(), new A()); + public void testMatchJP() throws Exception { - checkMatches(wildcardArgs,oneAArg,null,FuzzyBoolean.YES); - checkMatches(wildcardArgs,oneBArg,null,FuzzyBoolean.YES); - checkMatches(wildcardArgs,acArgs,null,FuzzyBoolean.YES); - checkMatches(wildcardArgs,baArgs,null,FuzzyBoolean.YES); + Method oneAArg = B.class.getMethod("x", new Class[] {A.class}); + Method oneBArg = B.class.getMethod("y",new Class[] {B.class}); + Method acArgs = C.class.getMethod("z",new Class[] {A.class,C.class}); + Method baArgs = C.class.getMethod("t",new Class[] {B.class, A.class}); - checkMatches(oneA,oneAArg,null,FuzzyBoolean.YES); - checkMatches(oneA,oneBArg,null,FuzzyBoolean.YES); - checkMatches(oneA,acArgs,null,FuzzyBoolean.NO); - checkMatches(oneA,baArgs,null,FuzzyBoolean.NO); + checkMatches(wildcardArgs.matchesMethodExecution(oneAArg),new B(), new B(), new Object[] {new A()} ); + checkMatches(wildcardArgs.matchesMethodExecution(oneBArg),new B(), new B(), new Object[] {new B()} ); + checkMatches(wildcardArgs.matchesMethodExecution(acArgs),new C(), new C(), new Object[] {new B(), new C()} ); + checkMatches(wildcardArgs.matchesMethodExecution(baArgs),new C(), new C(), new Object[] {new B(), new B()} ); - checkMatches(oneAandaC,oneAArg,null,FuzzyBoolean.NO); - checkMatches(oneAandaC,oneBArg,null,FuzzyBoolean.NO); - checkMatches(oneAandaC,acArgs,null,FuzzyBoolean.YES); - checkMatches(oneAandaC,baArgs,null,FuzzyBoolean.NO); - - checkMatches(BthenAnything,oneAArg,null,FuzzyBoolean.NO); - checkMatches(BthenAnything,oneBArg,null,FuzzyBoolean.YES); - checkMatches(BthenAnything,acArgs,null,FuzzyBoolean.NO); - checkMatches(BthenAnything,baArgs,null,FuzzyBoolean.YES); + checkMatches(oneA.matchesMethodExecution(oneAArg),new B(), new B(), new Object[] {new A()} ); + checkMatches(oneA.matchesMethodExecution(oneBArg),new B(), new B(), new Object[] {new B()} ); + checkNoMatch(oneA.matchesMethodExecution(acArgs),new C(), new C(), new Object[] {new B(), new C()}); + checkNoMatch(oneA.matchesMethodExecution(baArgs),new C(), new C(), new Object[] {new B(), new B()}); + + checkNoMatch(oneAandaC.matchesMethodExecution(oneAArg),new B(), new B(), new Object[] {new A()} ); + checkNoMatch(oneAandaC.matchesMethodExecution(oneBArg),new B(), new B(), new Object[] {new B()} ); + checkMatches(oneAandaC.matchesMethodExecution(acArgs),new C(), new C(), new Object[] {new B(), new C()}); + checkNoMatch(oneAandaC.matchesMethodExecution(baArgs),new C(), new C(), new Object[] {new B(), new B()}); - checkMatches(singleArg,oneAArg,null,FuzzyBoolean.YES); - checkMatches(singleArg,oneBArg,null,FuzzyBoolean.YES); - checkMatches(singleArg,acArgs,null,FuzzyBoolean.NO); - checkMatches(singleArg,baArgs,null,FuzzyBoolean.NO); + checkNoMatch(BthenAnything.matchesMethodExecution(oneAArg),new B(), new B(), new Object[] {new A()} ); + checkMatches(BthenAnything.matchesMethodExecution(oneBArg),new B(), new B(), new Object[] {new B()} ); + checkNoMatch(BthenAnything.matchesMethodExecution(acArgs),new C(), new C(), new Object[] {new A(), new C()}); + checkMatches(BthenAnything.matchesMethodExecution(baArgs),new C(), new C(), new Object[] {new B(), new B()}); + + checkMatches(singleArg.matchesMethodExecution(oneAArg),new B(), new B(), new Object[] {new A()} ); + checkMatches(singleArg.matchesMethodExecution(oneBArg),new B(), new B(), new Object[] {new B()} ); + checkNoMatch(singleArg.matchesMethodExecution(acArgs),new C(), new C(), new Object[] {new B(), new C()}); + checkNoMatch(singleArg.matchesMethodExecution(baArgs),new C(), new C(), new Object[] {new B(), new B()}); + + } + + public void testBinding() throws Exception { + + PointcutParser parser = new PointcutParser(); + PointcutParameter a = parser.createPointcutParameter("a",A.class); + A theParameter = new A(); + PointcutExpression bindA = parser.parsePointcutExpression("args(a,*)",A.class,new PointcutParameter[] {a}); + Method acArgs = C.class.getMethod("z",new Class[] {A.class,C.class}); + ShadowMatch sMatch = bindA.matchesMethodExecution(acArgs); + JoinPointMatch jpMatch = sMatch.matchesJoinPoint(new A(),new A(), new Object[] {theParameter}); + assertTrue("should match", jpMatch.matches()); + PointcutParameter[] bindings = jpMatch.getParameterBindings(); + assertTrue("one parameter",bindings.length == 1); + assertEquals("should be bound to the arg value",theParameter, bindings[0].getBinding()); + + PointcutParameter c = parser.createPointcutParameter("c", C.class); + C cParameter = new C(); + PointcutExpression bindAandC = parser.parsePointcutExpression("args(a,c)",A.class,new PointcutParameter[] {a,c}); + sMatch = bindAandC.matchesMethodExecution(acArgs); + jpMatch = sMatch.matchesJoinPoint(new A(),new A(), new Object[] {theParameter,cParameter}); + assertTrue("should match", jpMatch.matches()); + bindings = jpMatch.getParameterBindings(); + assertTrue("two parameters",bindings.length == 2); + assertEquals("should be bound to the a arg value",theParameter, bindings[0].getBinding()); + assertEquals("should be bound to the c arg value",cParameter, bindings[1].getBinding()); + assertEquals("a",bindings[0].getName()); + assertEquals("c",bindings[1].getName()); } - public void testMatchJPWithPrimitiveTypes() { + public void testMatchJPWithPrimitiveTypes() throws Exception { try { - Factory f = new Factory("ArgsTestCase.java",ArgsTestCase.A.class); - - Pointcut oneInt = new PatternParser("args(int)").parsePointcut().resolve(); - Pointcut oneInteger = new PatternParser("args(Integer)").parsePointcut().resolve(); - JoinPoint.StaticPart oneIntjp = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {int.class},new String[] {"i"},new Class[] {},null) ,1); - JoinPoint.StaticPart oneIntegerjp = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {Integer.class},new String[] {"i"},new Class[] {},null),1); + PointcutParser parser = new PointcutParser(); + PointcutExpression oneInt = parser.parsePointcutExpression("args(int)"); + PointcutExpression oneInteger = parser.parsePointcutExpression("args(Integer)"); - JoinPoint oneIntArg = Factory.makeJP(oneIntjp,new A(),new A(),new Integer(3)); - JoinPoint oneIntegerArg = Factory.makeJP(oneIntegerjp,new A(), new A(), new Integer(7)); + Method oneIntM = A.class.getMethod("anInt",new Class[] {int.class}); + Method oneIntegerM = A.class.getMethod("anInteger",new Class[] {Integer.class}); - checkMatches(oneInt,oneIntArg,null,FuzzyBoolean.YES); - checkMatches(oneInt,oneIntegerArg,null,FuzzyBoolean.NO); - checkMatches(oneInteger,oneIntArg,null,FuzzyBoolean.NO); - checkMatches(oneInteger,oneIntegerArg,null,FuzzyBoolean.YES); + if (LangUtil.is15VMOrGreater()) { + checkMatches(oneInt.matchesMethodExecution(oneIntM),new A(), new A(), new Object[] {new Integer(5)}); + checkMatches(oneInt.matchesMethodExecution(oneIntegerM),new A(), new A(), new Object[] {new Integer(5)}); + checkMatches(oneInteger.matchesMethodExecution(oneIntM),new A(), new A(), new Object[] {new Integer(5)}); + checkMatches(oneInteger.matchesMethodExecution(oneIntegerM),new A(), new A(), new Object[] {new Integer(5)}); + } else { + checkMatches(oneInt.matchesMethodExecution(oneIntM),new A(), new A(), new Object[] {new Integer(5)}); + checkNoMatch(oneInt.matchesMethodExecution(oneIntegerM),new A(), new A(), new Object[] {new Integer(5)}); + checkNoMatch(oneInteger.matchesMethodExecution(oneIntM),new A(), new A(), new Object[] {new Integer(5)}); + checkMatches(oneInteger.matchesMethodExecution(oneIntegerM),new A(), new A(), new Object[] {new Integer(5)}); + } } catch( Exception ex) { fail("Unexpected exception " + ex); } } + + private void checkMatches(ShadowMatch sMatch,Object thisOjb, Object targetObj, Object[] args) { + assertTrue("match expected",sMatch.matchesJoinPoint(thisOjb, targetObj, args).matches()); + } - private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(jp,jpsp)); + private void checkNoMatch(ShadowMatch sMatch,Object thisOjb, Object targetObj, Object[] args) { + assertFalse("no match expected",sMatch.matchesJoinPoint(thisOjb, targetObj, args).matches()); } - private static class A {}; - private static class B extends A {}; - private static class C {}; + private static class A { + public void anInt(int i) {} + public void anInteger(Integer i) {} + + }; + private static class B extends A { + public void x(A a) {} + public void y(B b) {} + }; + private static class C { + public void z(A a, C c) {} + public void t(B b, A a) {} + }; /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); - wildcardArgs = new PatternParser("args(..)").parsePointcut().resolve(); - oneA = new PatternParser("args(org.aspectj.weaver.patterns.ArgsTestCase.A)").parsePointcut().resolve(); - oneAandaC = new PatternParser("args(org.aspectj.weaver.patterns.ArgsTestCase.A,org.aspectj.weaver.patterns.ArgsTestCase.C)").parsePointcut().resolve(); - BthenAnything = new PatternParser("args(org.aspectj.weaver.patterns.ArgsTestCase.B,..)").parsePointcut().resolve(); - singleArg = new PatternParser("args(*)").parsePointcut().resolve(); + PointcutParser parser = new PointcutParser(); + wildcardArgs = parser.parsePointcutExpression("args(..)"); + oneA = parser.parsePointcutExpression("args(org.aspectj.weaver.patterns.ArgsTestCase.A)"); + oneAandaC = parser.parsePointcutExpression("args(org.aspectj.weaver.patterns.ArgsTestCase.A,org.aspectj.weaver.patterns.ArgsTestCase.C)"); + BthenAnything = parser.parsePointcutExpression("args(org.aspectj.weaver.patterns.ArgsTestCase.B,..)"); + singleArg = parser.parsePointcutExpression("args(*)"); } } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/HandlerTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/HandlerTestCase.java deleted file mode 100644 index 9238f8bc9..000000000 --- a/weaver/testsrc/org/aspectj/weaver/patterns/HandlerTestCase.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.aspectj.weaver.patterns; - -import java.io.IOException; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.runtime.reflect.Factory; -import org.aspectj.util.FuzzyBoolean; - -import junit.framework.TestCase; - - -public class HandlerTestCase extends TestCase { - - private Pointcut hEx; - private Pointcut hExPlus; - private Pointcut hIOEx; - - public void testHandlerMatch() { - Factory f = new Factory("HandlerTestCase.java",HandlerTestCase.class); - - JoinPoint.StaticPart jpsp1 = f.makeSJP(JoinPoint.EXCEPTION_HANDLER,f.makeCatchClauseSig(HandlerTestCase.class,Exception.class,"ex"),1); - JoinPoint ex = Factory.makeJP(jpsp1,this,this,new Exception()); - JoinPoint ioex = Factory.makeJP(jpsp1,this,this,new IOException()); - JoinPoint myex = Factory.makeJP(jpsp1,this,this,new MyException()); - - checkMatches(hEx,ex,null,FuzzyBoolean.YES); - checkMatches(hEx,ioex,null,FuzzyBoolean.NO); - checkMatches(hEx,myex,null,FuzzyBoolean.NO); - - checkMatches(hExPlus,ex,null,FuzzyBoolean.YES); - checkMatches(hExPlus,ioex,null,FuzzyBoolean.YES); - checkMatches(hExPlus,myex,null,FuzzyBoolean.YES); - - checkMatches(hIOEx,ex,null,FuzzyBoolean.NO); - checkMatches(hIOEx,ioex,null,FuzzyBoolean.YES); - checkMatches(hIOEx,myex,null,FuzzyBoolean.NO); - - } - - private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(jp,jpsp)); - } - - private static class MyException extends Exception {} - - /* (non-Javadoc) - * @see junit.framework.TestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - hEx = new PatternParser("handler(Exception)").parsePointcut().resolve(); - hExPlus = new PatternParser("handler(Exception+)").parsePointcut().resolve(); - hIOEx = new PatternParser("handler(java.io.IOException)").parsePointcut().resolve(); - } -} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java deleted file mode 100644 index 4313c10d7..000000000 --- a/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.aspectj.weaver.patterns; - -import java.lang.reflect.Modifier; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.runtime.reflect.Factory; -import org.aspectj.util.FuzzyBoolean; - -import junit.framework.TestCase; - -/** - * @author colyer - * - */ -public class KindedTestCase extends TestCase { - - Pointcut callpc; - Pointcut exepc; - Pointcut exepcplus; - Pointcut exepcCons; - Pointcut adviceexepc; - Pointcut initpc; - Pointcut preinitpc; - Pointcut staticinitpc; - Pointcut getpc; - Pointcut setpc; - - public void testKindedMatch() { - Factory f = new Factory("KindedTestCase.java",KindedTestCase.class); - - // JoinPoints to match against... - JoinPoint.StaticPart calljp1 = f.makeSJP(JoinPoint.METHOD_CALL,f.makeMethodSig(0,"main",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],String.class),1); - JoinPoint.StaticPart calljp2 = f.makeSJP(JoinPoint.METHOD_CALL,f.makeMethodSig(0,"sayHi",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],String.class),1); - JoinPoint.StaticPart exejp1 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"main",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],String.class),1); - JoinPoint.StaticPart exejp2 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"sayHi",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],void.class),1); - JoinPoint.StaticPart execonsjp1 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Hello.class,new Class[0],new String[0],new Class[0]),1); - JoinPoint.StaticPart execonsjp2 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1); - JoinPoint.StaticPart initjp1 = f.makeSJP(JoinPoint.INITIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[0],new String[0],new Class[0]),1); - JoinPoint.StaticPart initjp2 = f.makeSJP(JoinPoint.PREINTIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[]{int.class, int.class},new String[]{"a","b"},new Class[0]),1); - JoinPoint.StaticPart initjp3 = f.makeSJP(JoinPoint.PREINTIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[]{Integer.class, Integer.class},new String[]{"a","b"},new Class[0]),1); - JoinPoint.StaticPart sinitjp1 = f.makeSJP(JoinPoint.STATICINITIALIZATION,f.makeInitializerSig(Modifier.STATIC,Hello.class),1); - JoinPoint.StaticPart sinitjp2 = f.makeSJP(JoinPoint.STATICINITIALIZATION,f.makeInitializerSig(Modifier.STATIC,String.class),1); - JoinPoint.StaticPart getjp1 = f.makeSJP(JoinPoint.FIELD_GET,f.makeFieldSig(0,"x",Hello.class,int.class),1); - JoinPoint.StaticPart getjp2 = f.makeSJP(JoinPoint.FIELD_GET,f.makeFieldSig(0,"y",String.class,String.class),1); - JoinPoint.StaticPart setjp1 = f.makeSJP(JoinPoint.FIELD_SET,f.makeFieldSig(0,"x",Hello.class,int.class),1); - JoinPoint.StaticPart setjp2 = f.makeSJP(JoinPoint.FIELD_SET,f.makeFieldSig(0,"y",String.class,String.class),1); - JoinPoint.StaticPart advjp = f.makeSJP(JoinPoint.ADVICE_EXECUTION,f.makeAdviceSig(0,"foo",Hello.class,new Class[0],new String[0],new Class[0],void.class),1); - - checkMatches(callpc,calljp1,FuzzyBoolean.YES); - checkMatches(callpc,calljp2,FuzzyBoolean.NO); - checkMatches(callpc,exejp1,FuzzyBoolean.NO); - checkMatches(exepc,exejp1,FuzzyBoolean.NO); - checkMatches(exepc,exejp2,FuzzyBoolean.YES); - checkMatches(exepcplus,exejp1,FuzzyBoolean.NO); - checkMatches(exepcplus,exejp2,FuzzyBoolean.YES); - checkMatches(exepcCons,execonsjp1,FuzzyBoolean.YES); - checkMatches(exepcCons,execonsjp2,FuzzyBoolean.NO); - checkMatches(exepcCons,exejp1,FuzzyBoolean.NO); - checkMatches(initpc,initjp1,FuzzyBoolean.YES); - checkMatches(initpc,initjp2,FuzzyBoolean.NO); - checkMatches(preinitpc,initjp1,FuzzyBoolean.NO); - checkMatches(preinitpc,initjp2,FuzzyBoolean.YES); - checkMatches(preinitpc,initjp3,FuzzyBoolean.NO); - checkMatches(staticinitpc,sinitjp1,FuzzyBoolean.YES); - checkMatches(staticinitpc,sinitjp2,FuzzyBoolean.NO); - checkMatches(getpc,getjp1,FuzzyBoolean.YES); - checkMatches(getpc,getjp2,FuzzyBoolean.YES); - checkMatches(setpc,setjp1,FuzzyBoolean.YES); - checkMatches(setpc,setjp2,FuzzyBoolean.NO); - checkMatches(adviceexepc,advjp,FuzzyBoolean.YES); - } - - private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(jpsp)); - } - - protected void setUp() throws Exception { - super.setUp(); - callpc = new PatternParser("call(* main(..))").parsePointcut().resolve(); - exepc = new PatternParser("execution(void org.aspectj.weaver.patterns.KindedTestCase.Hello.sayHi(String))").parsePointcut().resolve(); - exepcplus = new PatternParser("execution(void Object+.sayHi(String))").parsePointcut().resolve(); - exepcCons = new PatternParser("execution(org.aspectj.weaver.patterns.KindedTestCase.Hello.new(..))").parsePointcut().resolve(); - initpc = new PatternParser("initialization(new(..))").parsePointcut().resolve(); - preinitpc = new PatternParser("preinitialization(*..H*.new(int,int))").parsePointcut().resolve(); - staticinitpc = new PatternParser("staticinitialization(org.aspectj.weaver.patterns.KindedTestCase.Hello)").parsePointcut().resolve(); - getpc = new PatternParser("get(* *)").parsePointcut().resolve(); - setpc = new PatternParser("set(int x)").parsePointcut().resolve(); - adviceexepc = new PatternParser("adviceexecution()").parsePointcut().resolve(); - } - - private static class Hello {}; -} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java b/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java index db80087ef..171fc4044 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java @@ -32,11 +32,7 @@ public class PatternsTests extends TestCase { suite.addTestSuite(TypePatternListTestCase.class); suite.addTestSuite(TypePatternTestCase.class); suite.addTestSuite(WithinTestCase.class); - suite.addTestSuite(PointcutTestCase.class); suite.addTestSuite(ArgsTestCase.class); - suite.addTestSuite(HandlerTestCase.class); - suite.addTestSuite(KindedTestCase.class); - suite.addTestSuite(WithinCodeTestCase.class); suite.addTestSuite(AnnotationPatternTestCase.class); suite.addTestSuite(AnnotationPatternMatchingTestCase.class); suite.addTestSuite(PointcutRewriterTest.class); diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java deleted file mode 100644 index 3a4477f9c..000000000 --- a/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.aspectj.weaver.patterns; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Map; -import java.util.Set; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.Signature; -import org.aspectj.runtime.reflect.Factory; -import org.aspectj.util.FuzzyBoolean; -import org.aspectj.weaver.IntMap; -import org.aspectj.weaver.ResolvedType; -import org.aspectj.weaver.Shadow; -import org.aspectj.weaver.ast.Test; - -import junit.framework.TestCase; - - -public class PointcutTestCase extends TestCase { - - public void testMatchJP() { - Pointcut p = new Pointcut() { - - public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); - } - - public Set couldMatchKinds() { - return null; - } - - public FuzzyBoolean fastMatch(FastMatchInfo info) { - return null; - } - - public FuzzyBoolean fastMatch(Class targetClass) { - return null; - } - - protected FuzzyBoolean matchInternal(Shadow shadow) { - return null; - } - - protected void resolveBindings(IScope scope, Bindings bindings) { - } - - protected void resolveBindingsFromRTTI() {} - - protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) { - return null; - } - - public Pointcut parameterizeWith(Map typeVariableMap) { - return null; - } - - protected Test findResidueInternal(Shadow shadow, ExposedState state) { - return null; - } - - public void write(DataOutputStream s) throws IOException { - }}; - - Factory f = new Factory("PointcutTestCase.java",PointcutTestCase.class); - - Signature methodSig = f.makeMethodSig("void aMethod()"); - JoinPoint.StaticPart jpsp = f.makeSJP(JoinPoint.METHOD_EXECUTION,methodSig,1); - JoinPoint jp = Factory.makeJP(jpsp,this,this); - - try { - p.match(jp,null); - fail("Expected UnsupportedOperationException to be thrown"); - } catch (UnsupportedOperationException unEx) { - // ok - } - - try { - p.match(jpsp); - fail("Expected UnsupportedOperationException to be thrown"); - } catch (UnsupportedOperationException unEx) { - // ok - } - - } - -} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java index 31794bcfe..532e93e9e 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java @@ -1,5 +1,6 @@ /* ******************************************************************* * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 2005 Contributors * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Common Public License v1.0 @@ -7,21 +8,25 @@ * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: - * PARC initial implementation + * PARC initial implementation + * Adrian Colyer, runtime reflection extensions * ******************************************************************/ package org.aspectj.weaver.patterns; -import java.io.*; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.runtime.reflect.Factory; -import org.aspectj.util.FuzzyBoolean; -import org.aspectj.weaver.bcel.*; +import java.io.IOException; +import java.lang.reflect.Method; import junit.framework.TestCase; -import org.aspectj.weaver.*; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.tools.JoinPointMatch; +import org.aspectj.weaver.tools.PointcutExpression; +import org.aspectj.weaver.tools.PointcutParameter; +import org.aspectj.weaver.tools.PointcutParser; +import org.aspectj.weaver.tools.ShadowMatch; /** * @author hugunin @@ -50,77 +55,71 @@ public class ThisOrTargetTestCase extends TestCase { } - public void testMatchJP() { - Factory f = new Factory("ThisOrTargetTestCase.java",ThisOrTargetTestCase.class); - - Pointcut thisEx = new PatternParser("this(Exception)").parsePointcut().resolve(); - Pointcut thisIOEx = new PatternParser("this(java.io.IOException)").parsePointcut().resolve(); + public void testMatchJP() throws Exception { + PointcutParser parser = new PointcutParser(); + PointcutExpression thisEx = parser.parsePointcutExpression("this(Exception)"); + PointcutExpression thisIOEx = parser.parsePointcutExpression("this(java.io.IOException)"); - Pointcut targetEx = new PatternParser("target(Exception)").parsePointcut().resolve(); - Pointcut targetIOEx = new PatternParser("target(java.io.IOException)").parsePointcut().resolve(); + PointcutExpression targetEx = parser.parsePointcutExpression("target(Exception)"); + PointcutExpression targetIOEx = parser.parsePointcutExpression("target(java.io.IOException)"); - JoinPoint.StaticPart jpsp1 = f.makeSJP(JoinPoint.EXCEPTION_HANDLER,f.makeCatchClauseSig(HandlerTestCase.class,Exception.class,"ex"),1); - JoinPoint thisExJP = Factory.makeJP(jpsp1,new Exception(),this); - JoinPoint thisIOExJP = Factory.makeJP(jpsp1,new IOException(),this); - JoinPoint targetExJP = Factory.makeJP(jpsp1,this,new Exception()); - JoinPoint targetIOExJP = Factory.makeJP(jpsp1,this,new IOException()); + Method toString = Object.class.getMethod("toString",new Class[0]); - checkMatches(thisEx,thisExJP,null,FuzzyBoolean.YES); - checkMatches(thisIOEx,thisExJP,null,FuzzyBoolean.NO); - checkMatches(targetEx,thisExJP,null,FuzzyBoolean.NO); - checkMatches(targetIOEx,thisExJP,null,FuzzyBoolean.NO); - - checkMatches(thisEx,thisIOExJP,null,FuzzyBoolean.YES); - checkMatches(thisIOEx,thisIOExJP,null,FuzzyBoolean.YES); - checkMatches(targetEx,thisIOExJP,null,FuzzyBoolean.NO); - checkMatches(targetIOEx,thisIOExJP,null,FuzzyBoolean.NO); - - checkMatches(thisEx,targetExJP,null,FuzzyBoolean.NO); - checkMatches(thisIOEx,targetExJP,null,FuzzyBoolean.NO); - checkMatches(targetEx,targetExJP,null,FuzzyBoolean.YES); - checkMatches(targetIOEx,targetExJP,null,FuzzyBoolean.NO); - - checkMatches(thisEx,targetIOExJP,null,FuzzyBoolean.NO); - checkMatches(thisIOEx,targetIOExJP,null,FuzzyBoolean.NO); - checkMatches(targetEx,targetIOExJP,null,FuzzyBoolean.YES); - checkMatches(targetIOEx,targetIOExJP,null,FuzzyBoolean.YES); + checkMatches(thisEx.matchesMethodCall(toString, toString),new Exception(),null,null); + checkNoMatch(thisIOEx.matchesMethodCall(toString, toString),new Exception(),null,null); + checkNoMatch(targetEx.matchesMethodCall(toString, toString),new Exception(),new Object(),null); + checkNoMatch(targetIOEx.matchesMethodCall(toString, toString),new Exception(),new Exception(),null); + + checkMatches(thisEx.matchesMethodCall(toString, toString),new IOException(),null,null); + checkMatches(thisIOEx.matchesMethodCall(toString, toString),new IOException(),null,null); + + checkNoMatch(thisEx.matchesMethodCall(toString, toString),new Object(),null,null); + checkNoMatch(thisIOEx.matchesMethodCall(toString, toString),new Exception(),null,null); + checkMatches(targetEx.matchesMethodCall(toString, toString),new Exception(),new Exception(),null); + checkNoMatch(targetIOEx.matchesMethodCall(toString, toString),new Exception(),new Exception(),null); + + checkMatches(targetIOEx.matchesMethodCall(toString, toString),new Exception(),new IOException(),null); } - private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(jp,jpsp)); - } + public void testBinding() throws Exception { + PointcutParser parser = new PointcutParser(); + PointcutParameter ex = parser.createPointcutParameter("ex", Exception.class); + PointcutParameter ioEx = parser.createPointcutParameter("ioEx", IOException.class); -// private Pointcut makePointcut(String pattern) { -// return new PatternParser(pattern).parsePointcut(); -// } - -// private void checkEquals(String pattern, Pointcut p) throws IOException { -// assertEquals(pattern, p, makePointcut(pattern)); -// checkSerialization(pattern); -// } + PointcutExpression thisEx = parser.parsePointcutExpression("this(ex)",Exception.class,new PointcutParameter[] {ex}); + + PointcutExpression targetIOEx = parser.parsePointcutExpression("target(ioEx)",Exception.class,new PointcutParameter[] {ioEx}); + Method toString = Object.class.getMethod("toString",new Class[0]); + + ShadowMatch sMatch = thisEx.matchesMethodCall(toString, toString); + Exception exceptionParameter = new Exception(); + IOException ioExceptionParameter = new IOException(); + JoinPointMatch jpMatch = sMatch.matchesJoinPoint(exceptionParameter, null, null); + assertTrue("should match",jpMatch.matches()); + PointcutParameter[] bindings = jpMatch.getParameterBindings(); + assertEquals("one binding",1,bindings.length); + assertEquals("should be exceptionParameter",exceptionParameter,bindings[0].getBinding()); + assertEquals("ex",bindings[0].getName()); + + sMatch = targetIOEx.matchesMethodCall(toString,toString); + jpMatch = sMatch.matchesJoinPoint(exceptionParameter, ioExceptionParameter, null); + assertTrue("should match",jpMatch.matches()); + bindings = jpMatch.getParameterBindings(); + assertEquals("one binding",1,bindings.length); + assertEquals("should be ioExceptionParameter",ioExceptionParameter,bindings[0].getBinding()); + assertEquals("ioEx",bindings[0].getName()); + + + } -// private void checkMatch(Pointcut p, Signature[] matches, boolean shouldMatch) { -// for (int i=0; i<matches.length; i++) { -// boolean result = p.matches(matches[i]); -// String msg = "matches " + p + " to " + matches[i] + " expected "; -// if (shouldMatch) { -// assertTrue(msg + shouldMatch, result); -// } else { -// assertTrue(msg + shouldMatch, !result); -// } -// } -// } -// -// public void testSerialization() throws IOException { -// String[] patterns = new String[] { -// "public * *(..)", "void *.foo(A, B)", "A b()" -// }; -// -// for (int i=0, len=patterns.length; i < len; i++) { -// checkSerialization(patterns[i]); -// } -// } + private void checkMatches(ShadowMatch sMatch, Object thisObj, Object targetObj, Object[] args) { + assertTrue("match expected",sMatch.matchesJoinPoint(thisObj, targetObj, args).matches()); + } + + private void checkNoMatch(ShadowMatch sMatch, Object thisObj, Object targetObj, Object[] args) { + assertFalse("no match expected",sMatch.matchesJoinPoint(thisObj, targetObj, args).matches()); + } /** * Method checkSerialization. diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/WithinCodeTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/WithinCodeTestCase.java deleted file mode 100644 index 1f81a0db3..000000000 --- a/weaver/testsrc/org/aspectj/weaver/patterns/WithinCodeTestCase.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.aspectj.weaver.patterns; - -import org.aspectj.lang.JoinPoint; -import org.aspectj.runtime.reflect.Factory; -import org.aspectj.util.FuzzyBoolean; - -import junit.framework.TestCase; - - -public class WithinCodeTestCase extends TestCase { - Pointcut withinCode1; - Pointcut withinCode2; - Pointcut withinCode3; - - public void testMatchJP() { - Factory f = new Factory("WithinCodeTestCase.java",WithinCodeTestCase.class); - - // JoinPoints to match against... - JoinPoint.StaticPart exejp1 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"toString",Object.class,new Class[] {},new String[] {},new Class[0],String.class),1); - JoinPoint.StaticPart exejp2 = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"sayHi",Hello.class,new Class[] {String.class},new String[] {"s"},new Class[0],void.class),1); - JoinPoint.StaticPart execonsjp1 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Object.class,new Class[0],new String[0],new Class[0]),1); - JoinPoint.StaticPart execonsjp2 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1); - - checkMatches(withinCode1,exejp1,FuzzyBoolean.YES); - checkMatches(withinCode1,exejp2,FuzzyBoolean.NO); - checkMatches(withinCode1,execonsjp1,FuzzyBoolean.NO); - checkMatches(withinCode1,execonsjp2,FuzzyBoolean.NO); - - checkMatches(withinCode2,exejp1,FuzzyBoolean.NO); - checkMatches(withinCode2,exejp2,FuzzyBoolean.NO); - checkMatches(withinCode2,execonsjp1,FuzzyBoolean.YES); - checkMatches(withinCode2,execonsjp2,FuzzyBoolean.YES); - - checkMatches(withinCode3,exejp1,FuzzyBoolean.NO); - checkMatches(withinCode3,exejp2,FuzzyBoolean.NO); - checkMatches(withinCode3,execonsjp1,FuzzyBoolean.NO); - checkMatches(withinCode3,execonsjp2,FuzzyBoolean.YES); - - } - - private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(null,jpsp)); - } - - protected void setUp() throws Exception { - super.setUp(); - withinCode1 = new PatternParser("withincode(String Object.toString())").parsePointcut().resolve(); - withinCode2 = new PatternParser("withincode(new(..))").parsePointcut().resolve(); - withinCode3 = new PatternParser("withincode(String.new(..))").parsePointcut().resolve(); - } - - private static class Hello {}; -} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java index 92283c5e6..cde6578ba 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java @@ -70,28 +70,28 @@ public class WithinTestCase extends TestCase { } - public void testMatchJP() { - Factory f = new Factory("WithinTestCase.java",WithinTestCase.class); - - JoinPoint.StaticPart inString = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1); - JoinPoint.StaticPart inObject = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Object.class,new Class[] {},new String[]{},new Class[0]),1); - - Pointcut withinString = new PatternParser("within(String)").parsePointcut().resolve(); - Pointcut withinObject = new PatternParser("within(Object)").parsePointcut().resolve(); - Pointcut withinObjectPlus = new PatternParser("within(Object+)").parsePointcut().resolve(); - - checkMatches(withinString,inString,FuzzyBoolean.YES); - checkMatches(withinString,inObject,FuzzyBoolean.NO); - checkMatches(withinObject,inString,FuzzyBoolean.NO); - checkMatches(withinObject,inObject, FuzzyBoolean.YES); - checkMatches(withinObjectPlus,inString,FuzzyBoolean.YES); - checkMatches(withinObjectPlus,inObject,FuzzyBoolean.YES); - } - - private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { - assertEquals(expected,p.match(null,jpsp)); - } - +// public void testMatchJP() { +// Factory f = new Factory("WithinTestCase.java",WithinTestCase.class); +// +// JoinPoint.StaticPart inString = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1); +// JoinPoint.StaticPart inObject = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,Object.class,new Class[] {},new String[]{},new Class[0]),1); +// +// Pointcut withinString = new PatternParser("within(String)").parsePointcut().resolve(); +// Pointcut withinObject = new PatternParser("within(Object)").parsePointcut().resolve(); +// Pointcut withinObjectPlus = new PatternParser("within(Object+)").parsePointcut().resolve(); +// +// checkMatches(withinString,inString,FuzzyBoolean.YES); +// checkMatches(withinString,inObject,FuzzyBoolean.NO); +// checkMatches(withinObject,inString,FuzzyBoolean.NO); +// checkMatches(withinObject,inObject, FuzzyBoolean.YES); +// checkMatches(withinObjectPlus,inString,FuzzyBoolean.YES); +// checkMatches(withinObjectPlus,inObject,FuzzyBoolean.YES); +// } +// +// private void checkMatches(Pointcut p, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { +// assertEquals(expected,p.match(null,jpsp)); +// } +// public Pointcut makePointcut(String pattern) { Pointcut pointcut0 = Pointcut.fromString(pattern); diff --git a/weaver/testsrc/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java b/weaver/testsrc/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java new file mode 100644 index 000000000..739f7841a --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java @@ -0,0 +1,149 @@ +/* ******************************************************************* + * 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 org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; + +import junit.framework.TestCase; + +public class ReflectionBasedReferenceTypeDelegateTest extends TestCase { + + private World world; + private ResolvedType objectType; + + public void testIsAspect() { + assertFalse(objectType.isAspect()); + } + + public void testIsAnnotationStyleAspect() { + assertFalse(objectType.isAnnotationStyleAspect()); + } + + public void testIsInterface() { + assertFalse(objectType.isInterface()); + assertTrue(world.resolve("java.io.Serializable").isInterface()); + } + + public void testIsEnum() { + assertFalse(objectType.isEnum()); + } + + public void testIsAnnotation() { + assertFalse(objectType.isAnnotation()); + } + + public void testIsAnnotationWithRuntimeRetention() { + assertFalse(objectType.isAnnotationWithRuntimeRetention()); + } + + public void testIsClass() { + assertTrue(objectType.isClass()); + assertFalse(world.resolve("java.io.Serializable").isClass()); + } + + public void testIsGeneric() { + assertFalse(objectType.isGenericType()); + } + + public void testIsExposedToWeaver() { + assertFalse(objectType.isExposedToWeaver()); + } + + public void testHasAnnotation() { + assertFalse(objectType.hasAnnotation(UnresolvedType.forName("Foo"))); + } + + public void testGetAnnotations() { + assertEquals("no entries",0,objectType.getAnnotations().length); + } + + public void testGetAnnotationTypes() { + assertEquals("no entries",0,objectType.getAnnotationTypes().length); + } + + public void testGetTypeVariables() { + assertEquals("no entries",0,objectType.getTypeVariables().length); + } + + public void testGetPerClause() { + assertNull(objectType.getPerClause()); + } + + public void testGetModifiers() { + assertEquals(Object.class.getModifiers(),objectType.getModifiers()); + } + + public void testGetSuperclass() { + assertNull(objectType.getSuperclass()); + assertEquals(objectType,world.resolve("java.lang.Class").getSuperclass()); + ResolvedType d = world.resolve("reflect.tests.D"); + assertEquals(world.resolve("reflect.tests.C"),d.getSuperclass()); + } + + public void testGetDeclaredMethods() { + ResolvedMember[] methods = objectType.getDeclaredMethods(); + assertEquals(13,methods.length); + + ResolvedType c = world.resolve("reflect.tests.C"); + methods = c.getDeclaredMethods(); + assertEquals(3,methods.length); + assertEquals("foo",methods[0].getName()); + assertEquals(world.resolve("java.lang.String"),methods[0].getReturnType()); + assertEquals(1, methods[0].getParameterTypes().length); + assertEquals(objectType,methods[0].getParameterTypes()[0]); + assertEquals(1,methods[0].getExceptions().length); + assertEquals(world.resolve("java.lang.Exception"),methods[0].getExceptions()[0]); + assertEquals("bar",methods[1].getName()); + assertEquals("init",methods[2].getName()); + + ResolvedType d = world.resolve("reflect.tests.D"); + methods = d.getDeclaredMethods(); + assertEquals(2,methods.length); + } + + public void testGetDeclaredFields() { + ResolvedMember[] fields = objectType.getDeclaredFields(); + assertEquals(0,fields.length); + + ResolvedType c = world.resolve("reflect.tests.C"); + fields = c.getDeclaredFields(); + + assertEquals(2,fields.length); + assertEquals("f",fields[0].getName()); + assertEquals("s",fields[1].getName()); + assertEquals(ResolvedType.INT,fields[0].getReturnType()); + assertEquals(world.resolve("java.lang.String"),fields[1].getReturnType()); + } + + public void testGetDeclaredInterfaces() { + ResolvedType[] interfaces = objectType.getDeclaredInterfaces(); + assertEquals(0,interfaces.length); + + ResolvedType d = world.resolve("reflect.tests.D"); + interfaces = d.getDeclaredInterfaces(); + assertEquals(1,interfaces.length); + assertEquals(world.resolve("java.io.Serializable"),interfaces[0]); +} + + public void testGetDeclaredPointcuts() { + ResolvedMember[] pointcuts = objectType.getDeclaredPointcuts(); + assertEquals(0,pointcuts.length); + } + + protected void setUp() throws Exception { + world = new ReflectionWorld(); + objectType = world.resolve("java.lang.Object"); + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java b/weaver/testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java new file mode 100644 index 000000000..8f0942725 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/reflect/ReflectionWorldTest.java @@ -0,0 +1,28 @@ +/* ******************************************************************* + * 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 org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.World; + +import junit.framework.TestCase; + +public class ReflectionWorldTest extends TestCase { + + public void testDelegateCreation() { + World world = new ReflectionWorld(); + ResolvedType rt = world.resolve("java.lang.Object"); + assertNotNull(rt); + assertEquals("Ljava/lang/Object;",rt.getSignature()); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java b/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java index 6e3e3d35e..8dc6418f2 100644 --- a/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java +++ b/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java @@ -14,6 +14,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import org.aspectj.util.LangUtil; + import junit.framework.TestCase; public class PointcutExpressionTest extends TestCase { @@ -22,6 +24,7 @@ public class PointcutExpressionTest extends TestCase { Constructor asCons; Constructor bsCons; Constructor bsStringCons; + Constructor clientCons; Method a; Method aa; Method aaa; @@ -35,434 +38,467 @@ public class PointcutExpressionTest extends TestCase { public void testMatchesMethodCall() { PointcutExpression ex = p.parsePointcutExpression("call(* *..A.a*(..))"); - assertEquals("Should match call to A.a()",FuzzyBoolean.YES,ex.matchesMethodCall(a,Client.class,A.class,null)); - assertEquals("Should match call to A.aaa()",FuzzyBoolean.YES,ex.matchesMethodCall(aaa,Client.class,A.class,null)); - assertEquals("Should match call to B.aa()",FuzzyBoolean.YES,ex.matchesMethodCall(bsaa,Client.class,A.class,null)); - assertEquals("Should not match call to B.b()",FuzzyBoolean.NO,ex.matchesMethodCall(b,Client.class,A.class,null)); + 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))"); - assertEquals("Should match call to A.aa()",FuzzyBoolean.YES,ex.matchesMethodCall(aa,Client.class,A.class,null)); - assertEquals("Should not match call to A.a()",FuzzyBoolean.NO,ex.matchesMethodCall(a,Client.class,A.class,null)); + 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)"); - assertEquals("Should match call to A.aaa() from Client",FuzzyBoolean.YES,ex.matchesMethodCall(aaa,Client.class,A.class,null)); + 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)"); - assertEquals("Should match call to A.aaa() from B",FuzzyBoolean.YES,ex.matchesMethodCall(aaa,B.class,A.class,null)); - assertEquals("May match call to A.aaa() from A",FuzzyBoolean.MAYBE,ex.matchesMethodCall(aaa,A.class,A.class,null)); + 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(* *.*(..))"); - assertEquals("Should not match call to A.aa",FuzzyBoolean.NO,ex.matchesMethodCall(aa,A.class,A.class,null)); + assertTrue("Should not match call to A.aa",ex.matchesMethodCall(aa,a).neverMatches()); // this ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); - assertEquals("Should match Client",FuzzyBoolean.YES,ex.matchesMethodCall(a,Client.class,A.class,null)); - assertEquals("Should not match A",FuzzyBoolean.NO,ex.matchesMethodCall(a,A.class,A.class,null)); + 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)"); - assertEquals("Should maybe match B",FuzzyBoolean.MAYBE,ex.matchesMethodCall(bsaa,A.class,B.class,null)); + 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)"); - assertEquals("Should not match Client",FuzzyBoolean.NO,ex.matchesMethodCall(a,Client.class,A.class,null)); + assertTrue("Should not match Client",ex.matchesMethodCall(a,a).neverMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesMethodCall(a,Client.class,A.class,null)); + assertTrue("Should match A",ex.matchesMethodCall(a,a).alwaysMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Should maybe match A",FuzzyBoolean.MAYBE,ex.matchesMethodCall(aa,A.class,A.class,null)); + 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)"); - assertEquals("Should match A.aa",FuzzyBoolean.YES,ex.matchesMethodCall(aa,A.class,A.class,null)); - assertEquals("Should match A.aaa",FuzzyBoolean.YES,ex.matchesMethodCall(aaa,A.class,A.class,null)); - assertEquals("Should not match A.a",FuzzyBoolean.NO,ex.matchesMethodCall(a,A.class,A.class,null)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesMethodCall(a,A.class,A.class,null)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesMethodCall(a,B.class,A.class,null)); + 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*(..))"); - assertEquals("Should match",FuzzyBoolean.YES,ex.matchesMethodCall(b,B.class,B.class,bsaa)); - assertEquals("Should not match",FuzzyBoolean.NO,ex.matchesMethodCall(b,B.class,B.class,b)); + assertTrue("Should match",ex.matchesMethodCall(b,bsaa).alwaysMatches()); + assertTrue("Should not match",ex.matchesMethodCall(b,b).neverMatches()); } public void testMatchesMethodExecution() { PointcutExpression ex = p.parsePointcutExpression("execution(* *..A.aa(..))"); - assertEquals("Should match execution of A.aa",FuzzyBoolean.YES,ex.matchesMethodExecution(aa,A.class)); - assertEquals("Should match execution of B.aa",FuzzyBoolean.YES,ex.matchesMethodExecution(bsaa,B.class)); - assertEquals("Should not match execution of A.a",FuzzyBoolean.NO,ex.matchesMethodExecution(a,B.class)); + 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))"); - assertEquals("Should not match execution of A.a",FuzzyBoolean.NO,ex.matchesMethodExecution(a,B.class)); + assertTrue("Should not match execution of A.a",ex.matchesMethodExecution(a).neverMatches()); + // test this ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesMethodExecution(a,A.class)); + assertTrue("Should match A",ex.matchesMethodExecution(a).alwaysMatches()); ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesMethodExecution(a,A.class)); - assertEquals("Should match B",FuzzyBoolean.YES,ex.matchesMethodExecution(a,B.class)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesMethodExecution(a,Client.class)); + 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)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesMethodExecution(a,A.class)); + assertTrue("Should match A",ex.matchesMethodExecution(a).alwaysMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesMethodExecution(a,A.class)); - assertEquals("Should match B",FuzzyBoolean.YES,ex.matchesMethodExecution(a,B.class)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesMethodExecution(a,Client.class)); + assertTrue("Maybe matches B",ex.matchesMethodExecution(a).maybeMatches()); + assertFalse("Maybe matches B",ex.matchesMethodExecution(a).alwaysMatches()); + // test args ex = p.parsePointcutExpression("args(..,int)"); - assertEquals("Should match A.aa",FuzzyBoolean.YES,ex.matchesMethodExecution(aa,A.class)); - assertEquals("Should match A.aaa",FuzzyBoolean.YES,ex.matchesMethodExecution(aaa,A.class)); - assertEquals("Should not match A.a",FuzzyBoolean.NO,ex.matchesMethodExecution(a,A.class)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesMethodExecution(a,A.class)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesMethodExecution(bsaa,B.class)); + 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*(..))"); - assertEquals("Should not match",FuzzyBoolean.NO,ex.matchesMethodExecution(a,A.class)); + assertTrue("Should not match",ex.matchesMethodExecution(a).neverMatches()); } public void testMatchesConstructorCall() { PointcutExpression ex = p.parsePointcutExpression("call(new(String))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesConstructorCall(asCons,A.class,null)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesConstructorCall(bsStringCons,Client.class,null)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesConstructorCall(bsCons,Client.class,null)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesConstructorCall(asCons,A.class,null)); - assertEquals("Should not match B(String)", FuzzyBoolean.NO, ex.matchesConstructorCall(bsStringCons,Client.class,null)); + 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)"); - assertEquals("Should match Client",FuzzyBoolean.YES,ex.matchesConstructorCall(asCons,Client.class,null)); - assertEquals("Should not match A",FuzzyBoolean.NO,ex.matchesConstructorCall(asCons,A.class,null)); + 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)"); - assertEquals("Should maybe match B",FuzzyBoolean.MAYBE,ex.matchesConstructorCall(asCons,A.class,null)); + 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)"); - assertEquals("Should not match Client",FuzzyBoolean.NO,ex.matchesConstructorCall(asCons,Client.class,null)); + assertTrue("Should not match Client",ex.matchesConstructorCall(asCons,foo).neverMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesConstructorCall(asCons,A.class,null)); - ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Should maybe match A",FuzzyBoolean.MAYBE,ex.matchesConstructorCall(asCons,A.class,null)); + assertTrue("Should not match A (no target)",ex.matchesConstructorCall(asCons,a).neverMatches()); // args ex = p.parsePointcutExpression("args(String)"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesConstructorCall(asCons,A.class,null)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesConstructorCall(bsStringCons,Client.class,null)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesConstructorCall(bsCons,Client.class,null)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesConstructorCall(asCons,A.class,null)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesConstructorCall(asCons,B.class,null)); + 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*(..))"); - assertEquals("Should match",FuzzyBoolean.YES,ex.matchesConstructorCall(bsCons,B.class,aa)); - assertEquals("Should not match",FuzzyBoolean.NO,ex.matchesConstructorCall(bsCons,B.class,b)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesConstructorExecution(asCons,A.class)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesConstructorExecution(bsStringCons,Client.class)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesConstructorExecution(bsCons,Client.class)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesConstructorExecution(asCons,A.class)); - assertEquals("Should not match B(String)", FuzzyBoolean.NO, ex.matchesConstructorExecution(bsStringCons,Client.class)); + 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)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesConstructorExecution(asCons,A.class)); + assertTrue("Should match A",ex.matchesConstructorExecution(asCons).alwaysMatches()); ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesConstructorExecution(asCons,A.class)); - assertEquals("Should match B",FuzzyBoolean.YES,ex.matchesConstructorExecution(asCons,B.class)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesConstructorExecution(asCons,Client.class)); + 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)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesConstructorExecution(asCons,A.class)); + assertTrue("Should match A",ex.matchesConstructorExecution(asCons).alwaysMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesConstructorExecution(asCons,A.class)); - assertEquals("Should match B",FuzzyBoolean.YES,ex.matchesConstructorExecution(asCons,B.class)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesConstructorExecution(asCons,Client.class)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesConstructorExecution(asCons,B.class)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesConstructorExecution(bsCons,B.class)); + 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*(..))"); - assertEquals("Does not match",FuzzyBoolean.NO,ex.matchesConstructorExecution(bsCons,B.class)); + assertTrue("Does not match",ex.matchesConstructorExecution(bsCons).neverMatches()); + // args ex = p.parsePointcutExpression("args(String)"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesConstructorExecution(asCons,A.class)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesConstructorExecution(bsStringCons,Client.class)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesConstructorExecution(bsCons,Client.class)); + 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()"); - assertEquals("Should match (advice) A.a",FuzzyBoolean.YES,ex.matchesAdviceExecution(a,A.class)); + assertTrue("Should match (advice) A.a",ex.matchesAdviceExecution(a).alwaysMatches()); // test this ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); - assertEquals("Should match Client",FuzzyBoolean.YES,ex.matchesAdviceExecution(a,Client.class)); + assertTrue("Should match Client",ex.matchesAdviceExecution(foo).alwaysMatches()); ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesAdviceExecution(a,A.class)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesAdviceExecution(a,Client.class)); + 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)"); - assertEquals("Should match Client",FuzzyBoolean.YES,ex.matchesAdviceExecution(a,Client.class)); + assertTrue("Should match Client",ex.matchesAdviceExecution(foo).alwaysMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesAdviceExecution(a,A.class)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesAdviceExecution(a,Client.class)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesAdviceExecution(a,A.class)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesAdviceExecution(b,B.class)); + 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*(..))"); - assertEquals("Does not match",FuzzyBoolean.NO,ex.matchesAdviceExecution(a,A.class)); + assertTrue("Does not match",ex.matchesAdviceExecution(a).neverMatches()); + // test args ex = p.parsePointcutExpression("args(..,int)"); - assertEquals("Should match A.aa",FuzzyBoolean.YES,ex.matchesAdviceExecution(aa,A.class)); - assertEquals("Should match A.aaa",FuzzyBoolean.YES,ex.matchesAdviceExecution(aaa,A.class)); - assertEquals("Should not match A.a",FuzzyBoolean.NO,ex.matchesAdviceExecution(a,A.class)); + 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)"); - assertEquals("Should match catch(Exception)",FuzzyBoolean.YES,ex.matchesHandler(Exception.class,Client.class,null)); - assertEquals("Should not match catch(Throwable)",FuzzyBoolean.NO,ex.matchesHandler(Throwable.class,Client.class,null)); + 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)"); - assertEquals("Should match Client",FuzzyBoolean.YES,ex.matchesHandler(Exception.class,Client.class,null)); + assertTrue("Should match Client",ex.matchesHandler(Exception.class,foo).alwaysMatches()); ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesHandler(Exception.class,A.class,null)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesHandler(Exception.class,Client.class,null)); - // target + 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)"); - assertEquals("Should match Client",FuzzyBoolean.YES,ex.matchesHandler(Exception.class,Client.class,null)); - ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesHandler(Exception.class,A.class,null)); - assertEquals("Does not match client",FuzzyBoolean.NO,ex.matchesHandler(Exception.class,Client.class,null)); + assertTrue("Should match Client",ex.matchesHandler(Exception.class,foo).neverMatches()); // args ex = p.parsePointcutExpression("args(Exception)"); - assertEquals("Should match Exception",FuzzyBoolean.YES, ex.matchesHandler(Exception.class,Client.class,null)); - assertEquals("Should match RuntimeException",FuzzyBoolean.YES, ex.matchesHandler(RuntimeException.class,Client.class,null)); - assertEquals("Should not match String",FuzzyBoolean.NO,ex.matchesHandler(String.class,Client.class,null)); - assertEquals("Maybe matches Throwable",FuzzyBoolean.MAYBE,ex.matchesHandler(Throwable.class,Client.class,null)); + 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)"); - assertEquals("Matches in class Client",FuzzyBoolean.YES,ex.matchesHandler(Exception.class,Client.class,null)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesHandler(Exception.class,B.class,null)); + 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*(..))"); - assertEquals("Matches within aa",FuzzyBoolean.YES,ex.matchesHandler(Exception.class,Client.class,aa)); - assertEquals("Does not match within b",FuzzyBoolean.NO,ex.matchesHandler(Exception.class,Client.class,b)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesInitialization(asCons)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesInitialization(bsStringCons)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesInitialization(bsCons)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesInitialization(asCons)); - assertEquals("Should not match B(String)", FuzzyBoolean.NO, ex.matchesInitialization(bsStringCons)); + 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)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesInitialization(asCons)); + assertTrue("Should match A",ex.matchesInitialization(asCons).alwaysMatches()); ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesInitialization(asCons)); + 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)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesInitialization(asCons)); + assertTrue("Should match A",ex.matchesInitialization(asCons).alwaysMatches()); ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesInitialization(asCons)); + assertTrue("Maybe matches B",ex.matchesInitialization(asCons).maybeMatches()); + assertFalse("Maybe matches B",ex.matchesInitialization(asCons).alwaysMatches()); // within ex = p.parsePointcutExpression("within(*..A)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesInitialization(asCons)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesInitialization(bsCons)); + 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*(..))"); - assertEquals("Does not match",FuzzyBoolean.NO,ex.matchesInitialization(bsCons)); + assertTrue("Does not match",ex.matchesInitialization(bsCons).neverMatches()); // args ex = p.parsePointcutExpression("args(String)"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesInitialization(asCons)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesInitialization(bsStringCons)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesInitialization(bsCons)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesPreInitialization(asCons)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesPreInitialization(bsStringCons)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesPreInitialization(bsCons)); + 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))"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesPreInitialization(asCons)); - assertEquals("Should not match B(String)", FuzzyBoolean.NO, ex.matchesPreInitialization(bsStringCons)); + 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)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesPreInitialization(asCons)); - ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesPreInitialization(asCons)); + assertTrue("No match, no this at preinit",ex.matchesPreInitialization(asCons).neverMatches()); + // test target ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); - assertEquals("Should match A",FuzzyBoolean.YES,ex.matchesPreInitialization(asCons)); - ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); - assertEquals("Maybe matches B",FuzzyBoolean.MAYBE,ex.matchesPreInitialization(asCons)); + assertTrue("No match, no target at preinit",ex.matchesPreInitialization(asCons).neverMatches()); + // within ex = p.parsePointcutExpression("within(*..A)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesPreInitialization(asCons)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesPreInitialization(bsCons)); + 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*(..))"); - assertEquals("Does not match",FuzzyBoolean.NO,ex.matchesPreInitialization(bsCons)); + assertTrue("Does not match",ex.matchesPreInitialization(bsCons).neverMatches()); // args ex = p.parsePointcutExpression("args(String)"); - assertEquals("Should match A(String)",FuzzyBoolean.YES, ex.matchesPreInitialization(asCons)); - assertEquals("Should match B(String)", FuzzyBoolean.YES, ex.matchesPreInitialization(bsStringCons)); - assertEquals("Should not match B()", FuzzyBoolean.NO,ex.matchesPreInitialization(bsCons)); } + 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+)"); - assertEquals("Matches A",FuzzyBoolean.YES,ex.matchesStaticInitialization(A.class)); - assertEquals("Matches B",FuzzyBoolean.YES,ex.matchesStaticInitialization(B.class)); - assertEquals("Doesn't match Client",FuzzyBoolean.NO,ex.matchesStaticInitialization(Client.class)); + 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)"); - assertEquals("No this",FuzzyBoolean.NO,ex.matchesStaticInitialization(A.class)); + assertTrue("No this",ex.matchesStaticInitialization(A.class).neverMatches()); // target ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); - assertEquals("No target",FuzzyBoolean.NO,ex.matchesStaticInitialization(A.class)); + assertTrue("No target",ex.matchesStaticInitialization(A.class).neverMatches()); + // args ex = p.parsePointcutExpression("args()"); - assertEquals("No args",FuzzyBoolean.NO,ex.matchesStaticInitialization(A.class)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesStaticInitialization(A.class)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesStaticInitialization(B.class)); + 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*(..))"); - assertEquals("Does not match",FuzzyBoolean.NO,ex.matchesStaticInitialization(A.class)); + assertTrue("Does not match",ex.matchesStaticInitialization(A.class).neverMatches()); } public void testMatchesFieldSet() { PointcutExpression ex = p.parsePointcutExpression("set(* *..A+.*)"); - assertEquals("matches x",FuzzyBoolean.YES,ex.matchesFieldSet(x,Client.class,A.class,null)); - assertEquals("matches y",FuzzyBoolean.YES,ex.matchesFieldSet(y,Client.class,B.class,null)); - assertEquals("does not match n",FuzzyBoolean.NO,ex.matchesFieldSet(n,A.class,Client.class,null)); + 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)"); - assertEquals("matches Client",FuzzyBoolean.YES,ex.matchesFieldSet(x,Client.class,A.class,null)); - assertEquals("does not match A",FuzzyBoolean.NO,ex.matchesFieldSet(n,A.class,Client.class,null)); + 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)"); - assertEquals("maybe matches A",FuzzyBoolean.MAYBE,ex.matchesFieldSet(x,A.class,A.class,null)); + 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)"); - assertEquals("matches B",FuzzyBoolean.YES,ex.matchesFieldSet(y,Client.class,B.class,null)); - assertEquals("maybe matches A",FuzzyBoolean.MAYBE,ex.matchesFieldSet(x,Client.class,A.class,null)); + 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)"); - assertEquals("matches x",FuzzyBoolean.YES,ex.matchesFieldSet(x,Client.class,A.class,null)); - assertEquals("matches y",FuzzyBoolean.YES,ex.matchesFieldSet(y,Client.class,B.class,null)); - assertEquals("does not match n",FuzzyBoolean.NO,ex.matchesFieldSet(n,A.class,Client.class,null)); + 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)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesFieldSet(x,A.class,A.class,null)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesFieldSet(x,B.class,A.class,null)); + 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*(..))"); - assertEquals("Should match",FuzzyBoolean.YES,ex.matchesFieldSet(x,A.class,A.class,aa)); - assertEquals("Should not match",FuzzyBoolean.NO,ex.matchesFieldSet(x,A.class,A.class,b)); + 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+.*)"); - assertEquals("matches x",FuzzyBoolean.YES,ex.matchesFieldGet(x,Client.class,A.class,null)); - assertEquals("matches y",FuzzyBoolean.YES,ex.matchesFieldGet(y,Client.class,B.class,null)); - assertEquals("does not match n",FuzzyBoolean.NO,ex.matchesFieldGet(n,A.class,Client.class,null)); + 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)"); - assertEquals("matches Client",FuzzyBoolean.YES,ex.matchesFieldGet(x,Client.class,A.class,null)); - assertEquals("does not match A",FuzzyBoolean.NO,ex.matchesFieldGet(n,A.class,Client.class,null)); + 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)"); - assertEquals("maybe matches A",FuzzyBoolean.MAYBE,ex.matchesFieldGet(x,A.class,A.class,null)); + 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)"); - assertEquals("matches B",FuzzyBoolean.YES,ex.matchesFieldGet(y,Client.class,B.class,null)); - assertEquals("maybe matches A",FuzzyBoolean.MAYBE,ex.matchesFieldGet(x,Client.class,A.class,null)); - // args + 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)"); - assertEquals("matches x",FuzzyBoolean.NO,ex.matchesFieldGet(x,Client.class,A.class,null)); - assertEquals("matches y",FuzzyBoolean.NO,ex.matchesFieldGet(y,Client.class,B.class,null)); - assertEquals("does not match n",FuzzyBoolean.NO,ex.matchesFieldGet(n,A.class,Client.class,null)); + assertTrue("matches x",ex.matchesFieldGet(x,a).neverMatches()); // within ex = p.parsePointcutExpression("within(*..A)"); - assertEquals("Matches in class A",FuzzyBoolean.YES,ex.matchesFieldGet(x,A.class,A.class,null)); - assertEquals("Does not match in class B",FuzzyBoolean.NO,ex.matchesFieldGet(x,B.class,A.class,null)); + 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*(..))"); - assertEquals("Should match",FuzzyBoolean.YES,ex.matchesFieldGet(x,A.class,A.class,aa)); - assertEquals("Should not match",FuzzyBoolean.NO,ex.matchesFieldGet(x,A.class,A.class,b)); + 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(*,*,*,*)"); - assertEquals("Too few args",FuzzyBoolean.NO,ex.matchesMethodExecution(foo,Client.class)); - assertEquals("Matching #args",FuzzyBoolean.YES,ex.matchesMethodExecution(bar,Client.class)); + assertTrue("Too few args",ex.matchesMethodExecution(foo).neverMatches()); + assertTrue("Matching #args",ex.matchesMethodExecution(bar).alwaysMatches()); // one too few + ellipsis ex = p.parsePointcutExpression("args(*,*,*,..)"); - assertEquals("Matches with ellipsis",FuzzyBoolean.YES,ex.matchesMethodExecution(foo,Client.class)); + assertTrue("Matches with ellipsis",ex.matchesMethodExecution(foo).alwaysMatches()); // exact number + ellipsis - assertEquals("Matches with ellipsis",FuzzyBoolean.YES,ex.matchesMethodExecution(bar,Client.class)); - assertEquals("Does not match with ellipsis",FuzzyBoolean.NO,ex.matchesMethodExecution(a,A.class)); + 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(*,..,*)"); - assertEquals("Matches with ellipsis",FuzzyBoolean.YES,ex.matchesMethodExecution(bar,Client.class)); - assertEquals("Does not match with ellipsis",FuzzyBoolean.NO,ex.matchesMethodExecution(a,A.class)); - assertEquals("Matches with ellipsis",FuzzyBoolean.YES,ex.matchesMethodExecution(aaa,A.class)); + 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)"); - assertEquals("Matches exactly",FuzzyBoolean.YES,ex.matchesMethodExecution(foo,Client.class)); + assertTrue("Matches exactly",ex.matchesMethodExecution(foo).alwaysMatches()); // maybe match ex = p.parsePointcutExpression("args(String,int,Double)"); - assertEquals("Matches maybe",FuzzyBoolean.MAYBE,ex.matchesMethodExecution(foo,Client.class)); + assertTrue("Matches maybe",ex.matchesMethodExecution(foo).maybeMatches()); + assertFalse("Matches maybe",ex.matchesMethodExecution(foo).alwaysMatches()); // never match ex = p.parsePointcutExpression("args(String,Integer,Number)"); - assertEquals("Does not match",FuzzyBoolean.NO,ex.matchesMethodExecution(foo,Client.class)); + 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 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+)"); @@ -471,15 +507,17 @@ public class PointcutExpressionTest extends TestCase { public void testCouldMatchJoinPointsInType() { PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))"); - assertFalse("Could never match String",ex.couldMatchJoinPointsInType(String.class)); + 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)); - assertFalse("Does not match A",ex.couldMatchJoinPointsInType(A.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(X)"); + ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..)) && args(org.aspectj.weaver.tools.PointcutExpressionTest.X)"); assertTrue("Dynamic test needed",ex.mayNeedDynamicTest()); } @@ -496,6 +534,7 @@ public class PointcutExpressionTest extends TestCase { y = B.class.getDeclaredField("y"); b = B.class.getMethod("b",new Class[0]); bsaa = B.class.getMethod("aa",new Class[]{int.class}); + clientCons = Client.class.getConstructor(new Class[0]); n = Client.class.getDeclaredField("n"); foo = Client.class.getDeclaredMethod("foo",new Class[]{String.class,int.class,Number.class}); bar = Client.class.getDeclaredMethod("bar",new Class[]{String.class,int.class,Integer.class,Number.class}); @@ -518,8 +557,11 @@ public class PointcutExpressionTest extends TestCase { } 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 {} } diff --git a/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java b/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java index 92bb6ea55..131ec1975 100644 --- a/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java +++ b/weaver/testsrc/org/aspectj/weaver/tools/PointcutParserTest.java @@ -12,6 +12,11 @@ package org.aspectj.weaver.tools; import java.util.HashSet; import java.util.Set; +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.IMessage.Kind; + import junit.framework.TestCase; /** @@ -21,7 +26,7 @@ public class PointcutParserTest extends TestCase { public void testGetAllSupportedPointcutPrimitives() { Set s = PointcutParser.getAllSupportedPointcutPrimitives(); - assertEquals("Should be 14 elements in the set",14,s.size()); + assertEquals("Should be 21 elements in the set",21,s.size()); assertFalse("Should not contain if pcd",s.contains(PointcutPrimitive.IF)); assertFalse("Should not contain cflow pcd",s.contains(PointcutPrimitive.CFLOW)); assertFalse("Should not contain cflowbelow pcd",s.contains(PointcutPrimitive.CFLOW_BELOW)); @@ -30,7 +35,7 @@ public class PointcutParserTest extends TestCase { public void testEmptyConstructor() { PointcutParser parser = new PointcutParser(); Set s = parser.getSupportedPrimitives(); - assertEquals("Should be 14 elements in the set",14,s.size()); + assertEquals("Should be 21 elements in the set",21,s.size()); assertFalse("Should not contain if pcd",s.contains(PointcutPrimitive.IF)); assertFalse("Should not contain cflow pcd",s.contains(PointcutPrimitive.CFLOW)); assertFalse("Should not contain cflowbelow pcd",s.contains(PointcutPrimitive.CFLOW_BELOW)); @@ -50,14 +55,19 @@ public class PointcutParserTest extends TestCase { public void testParsePointcutExpression() { PointcutParser p = new PointcutParser(); - PointcutExpression pEx = p.parsePointcutExpression( - "(adviceexecution() || execution(* *.*(..)) || handler(Exception) || " + - "call(Foo Bar+.*(Goo)) || get(* foo) || set(Foo+ (Goo||Moo).s*) || " + - "initialization(Foo.new(..)) || preinitialization(*.new(Foo,..)) || " + - "staticinitialization(org.xzy.abc..*)) && (this(Foo) || target(Boo) ||" + - "args(A,B,C)) && !handler(X)"); - try { - pEx = p.parsePointcutExpression("gobble-de-gook()"); + IMessageHandler current = p.setCustomMessageHandler(new IgnoreWarningsMessageHandler()); + try { + p.parsePointcutExpression( + "(adviceexecution() || execution(* *.*(..)) || handler(Exception) || " + + "call(Foo Bar+.*(Goo)) || get(* foo) || set(Foo+ (Goo||Moo).s*) || " + + "initialization(Foo.new(..)) || preinitialization(*.new(Foo,..)) || " + + "staticinitialization(org.xzy.abc..*)) && (this(Foo) || target(Boo) ||" + + "args(A,B,C)) && !handler(X)"); + } finally { + p.setCustomMessageHandler(current); + } + try { + p.parsePointcutExpression("gobble-de-gook()"); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ex) {} } @@ -65,7 +75,7 @@ public class PointcutParserTest extends TestCase { public void testParseExceptionErrorMessages() { PointcutParser p = new PointcutParser(); try { - PointcutExpression pEx = p.parsePointcutExpression("execution(int Foo.*(..) && args(Double)"); + p.parsePointcutExpression("execution(int Foo.*(..) && args(Double)"); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException ex) { assertTrue("Pointcut is not well-formed message",ex.getMessage().startsWith("Pointcut is not well-formed: expecting ')' at character position 24")); @@ -99,9 +109,11 @@ public class PointcutParserTest extends TestCase { } public void testParseReferencePCDs() { - PointcutParser p = new PointcutParser(); + Set pcKinds = PointcutParser.getAllSupportedPointcutPrimitives(); + pcKinds.remove(PointcutPrimitive.REFERENCE); + PointcutParser p = new PointcutParser(pcKinds); try { - p.parsePointcutExpression("bananas(x)"); + p.parsePointcutExpression("bananas(String)"); fail("Expected UnsupportedPointcutPrimitiveException"); } catch(UnsupportedPointcutPrimitiveException ex) { assertTrue(ex.getUnsupportedPrimitive() == PointcutPrimitive.REFERENCE); @@ -208,4 +220,42 @@ public class PointcutParserTest extends TestCase { assertEquals("Staticinit",PointcutPrimitive.STATIC_INITIALIZATION,ex.getUnsupportedPrimitive()); } } + + public void testFormals() { + PointcutParser parser = new PointcutParser(); + PointcutParameter param = parser.createPointcutParameter("x",String.class); + PointcutExpression pc = parser.parsePointcutExpression("args(x)", null, new PointcutParameter[] {param} ); + assertEquals("args(x)",pc.getPointcutExpression()); + + try { + pc = parser.parsePointcutExpression("args(String)", null, new PointcutParameter[] {param} ); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + assertTrue("formal unbound",ex.getMessage().indexOf("formal unbound") != -1); + } + + try { + pc = parser.parsePointcutExpression("args(y)"); + fail("Expecting IllegalArgumentException"); + } catch(IllegalArgumentException ex) { + assertTrue("no match for type name",ex.getMessage().indexOf("warning no match for this type name: y") != -1); + } + } + + private static class IgnoreWarningsMessageHandler implements IMessageHandler { + + public boolean handleMessage(IMessage message) throws AbortException { + if (message.getKind() != IMessage.WARNING) throw new RuntimeException("unexpected message: " + message.toString()); + return true; + } + + public boolean isIgnoring(Kind kind) { + if (kind != IMessage.ERROR) return true; + return false; + } + + public void dontIgnore(Kind kind) { + } + + } } diff --git a/weaver/testsrc/reflect/tests/C.java b/weaver/testsrc/reflect/tests/C.java new file mode 100644 index 000000000..f52043b5a --- /dev/null +++ b/weaver/testsrc/reflect/tests/C.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * 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 reflect.tests; + +/** + * @author colyer + * Part of the testdata for the org.aspectj.weaver.reflect tests + */ +public class C { + + public String foo(Object a) throws Exception { + return null; + } + + private void bar() {} + + public int f; + private String s; +} + +class D extends C implements java.io.Serializable { + public int getNumberOfThingies() { return 0; } + private Object o; +}
\ No newline at end of file |