diff options
author | acolyer <acolyer> | 2006-05-05 14:08:35 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2006-05-05 14:08:35 +0000 |
commit | b954b2664c25a74062a5a75b3d99a99e5ddf176d (patch) | |
tree | ab9e87b4bfe7dfcd225343abd2da99e336993f00 /weaver5 | |
parent | 299c3a4f2c5205102b89d63c4a8f1bccb158eef1 (diff) | |
download | aspectj-b954b2664c25a74062a5a75b3d99a99e5ddf176d.tar.gz aspectj-b954b2664c25a74062a5a75b3d99a99e5ddf176d.zip |
test and fix for pr140357, reference pointcuts that refer to other reference pointcuts in the same type, in a reflective world...
Diffstat (limited to 'weaver5')
4 files changed, 125 insertions, 14 deletions
diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/DeferredResolvedPointcutDefinition.java b/weaver5/java5-src/org/aspectj/weaver/reflect/DeferredResolvedPointcutDefinition.java new file mode 100644 index 000000000..2e1f5f7ee --- /dev/null +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/DeferredResolvedPointcutDefinition.java @@ -0,0 +1,29 @@ +package org.aspectj.weaver.reflect; + +import org.aspectj.weaver.ResolvedPointcutDefinition; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; + +/** + * When a Java15ReflectionBasedDelegate gets the pointcuts for a given class it + * tries to resolve them before returning. + * This can cause problems if the resolution of one pointcut in the type depends + * on another pointcut in the same type. + * Therefore the algorithm proceeds in two phases, first we create and store + * instances of this class in the pointcuts array, and once that is done, we + * come back round and resolve the actual pointcut expression. This means that + * if we recurse doing resolution, we will find the named pointcut we are + * looking for! + * + * @author adrian colyer + * + */ +public class DeferredResolvedPointcutDefinition extends ResolvedPointcutDefinition { + + public DeferredResolvedPointcutDefinition(UnresolvedType declaringType, + int modifiers, String name, UnresolvedType[] parameterTypes) { + super(declaringType, modifiers, name, parameterTypes, + ResolvedType.VOID, null); + } + +} diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/InternalUseOnlyPointcutParser.java b/weaver5/java5-src/org/aspectj/weaver/reflect/InternalUseOnlyPointcutParser.java new file mode 100644 index 000000000..8848f3059 --- /dev/null +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/InternalUseOnlyPointcutParser.java @@ -0,0 +1,31 @@ +package org.aspectj.weaver.reflect; + +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.tools.PointcutParameter; +import org.aspectj.weaver.tools.PointcutParser; + +public class InternalUseOnlyPointcutParser extends PointcutParser { + + public InternalUseOnlyPointcutParser(ClassLoader classLoader, ReflectionWorld world) { + super(); + setClassLoader(classLoader); + setWorld(world); + } + + public InternalUseOnlyPointcutParser(ClassLoader classLoader) { + super(); + setClassLoader(classLoader); + } + + public Pointcut resolvePointcutExpression( + String expression, + Class inScope, + PointcutParameter[] formalParameters) { + return super.resolvePointcutExpression(expression, inScope, formalParameters); + } + + public Pointcut concretizePointcutExpression(Pointcut pc, Class inScope, PointcutParameter[] formalParameters) { + return super.concretizePointcutExpression(pc, inScope, formalParameters); + } + +} diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java index a19457166..4a9152ac8 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java @@ -245,11 +245,26 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends if (pointcuts == null) { Pointcut[] pcs = this.myType.getDeclaredPointcuts(); pointcuts = new ResolvedMember[pcs.length]; - PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(classLoader); + InternalUseOnlyPointcutParser parser = null; World world = getWorld(); if (world instanceof ReflectionWorld) { - parser.setWorld((ReflectionWorld)getWorld()); + parser = new InternalUseOnlyPointcutParser(classLoader,(ReflectionWorld)getWorld()); + } else { + parser = new InternalUseOnlyPointcutParser(classLoader); } + + // phase 1, create legitimate entries in pointcuts[] before we attempt to resolve *any* of the pointcuts + // resolution can sometimes cause us to recurse, and this two stage process allows us to cope with that + for (int i = 0; i < pcs.length; i++) { + AjType<?>[] ptypes = pcs[i].getParameterTypes(); + UnresolvedType[] weaverPTypes = new UnresolvedType[ptypes.length]; + for (int j = 0; j < weaverPTypes.length; j++) { + weaverPTypes[j] = UnresolvedType.forName(ptypes[j].getName()); + } + pointcuts[i] = new DeferredResolvedPointcutDefinition(getResolvedTypeX(),pcs[i].getModifiers(),pcs[i].getName(),weaverPTypes); + } + // phase 2, now go back round and resolve in-place all of the pointcuts + PointcutParameter[][] parameters = new PointcutParameter[pcs.length][]; for (int i = 0; i < pcs.length; i++) { AjType<?>[] ptypes = pcs[i].getParameterTypes(); String[] pnames = pcs[i].getParameterNames(); @@ -259,18 +274,18 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends 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].getJavaClass()); - } - 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); + parameters[i] = new PointcutParameter[ptypes.length]; + for (int j = 0; j < parameters[i].length; j++) { + parameters[i][j] = parser.createPointcutParameter(pnames[j],ptypes[j].getJavaClass()); + } String pcExpr = pcs[i].getPointcutExpression().toString(); + org.aspectj.weaver.patterns.Pointcut pc = parser.resolvePointcutExpression(pcExpr,getBaseClass(),parameters[i]); + ((ResolvedPointcutDefinition)pointcuts[i]).setParameterNames(pnames); + ((ResolvedPointcutDefinition)pointcuts[i]).setPointcut(pc); + } + // phase 3, now concretize them all + for (int i = 0; i < pointcuts.length; i++) { + ResolvedPointcutDefinition rpd = (ResolvedPointcutDefinition) pointcuts[i]; + rpd.setPointcut(parser.concretizePointcutExpression(rpd.getPointcut(), getBaseClass(), parameters[i])); } } return pointcuts; diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java b/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java index 6127b2dd8..6e05580b9 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java @@ -283,6 +283,22 @@ public class Java15PointcutExpressionTest extends TestCase { assertTrue("should match",sm1.alwaysMatches()); } + public void testReferencePCsInSameType() throws Exception { + PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.c()",NamedPointcutResolution.class,new PointcutParameter[0]); + ShadowMatch sm = ex.matchesMethodExecution(a); + assertTrue("should match",sm.alwaysMatches()); + sm = ex.matchesMethodExecution(b); + assertTrue("does not match",sm.neverMatches()); + } + + public void testReferencePCsInOtherType() throws Exception { + PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.ExternalReferrer.d()",ExternalReferrer.class,new PointcutParameter[0]); + ShadowMatch sm = ex.matchesMethodExecution(a); + assertTrue("should match",sm.alwaysMatches()); + sm = ex.matchesMethodExecution(b); + assertTrue("does not match",sm.neverMatches()); + } + protected void setUp() throws Exception { super.setUp(); parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); @@ -334,6 +350,26 @@ public class Java15PointcutExpressionTest extends TestCase { static class GoldenOldie { public void foo() {} } + + private static class NamedPointcutResolution { + + @Pointcut("execution(* *(..))") + public void a() {} + + @Pointcut("this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.A)") + public void b() {} + + @Pointcut("a() && b()") + public void c() {} + } + + private static class ExternalReferrer { + + @Pointcut("org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.a() && " + + "org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.b())") + public void d() {} + + } } |