diff options
author | Andy Clement <aclement@pivotal.io> | 2016-12-02 10:32:17 -0800 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2016-12-02 10:32:17 -0800 |
commit | d10618d25a9e995ffeb8080b3b9468ad241a163c (patch) | |
tree | e6d7392533635926c055048deb040e778fe92e20 /weaver5 | |
parent | b6f2b6337fbaf95b78c20862cd90f0e027509531 (diff) | |
download | aspectj-paramAnnotationBinding.tar.gz aspectj-paramAnnotationBinding.zip |
259416: preliminary workparamAnnotationBinding
Diffstat (limited to 'weaver5')
3 files changed, 225 insertions, 3 deletions
diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java index a978d9605..5de589f15 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java @@ -26,6 +26,7 @@ import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.LocalVariable; import org.aspectj.apache.bcel.classfile.LocalVariableTable; +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository; import org.aspectj.apache.bcel.util.Repository; import org.aspectj.weaver.AnnotationAJ; @@ -321,8 +322,7 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { // 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. + // don't hog memory. try { JavaClass jc = bcelRepository.loadClass(onMember.getDeclaringClass()); org.aspectj.apache.bcel.classfile.annotation.AnnotationGen[][] anns = null; @@ -386,5 +386,72 @@ public class Java15AnnotationFinder implements AnnotationFinder, ArgNameFinder { } return result; } + + public Object getParamAnnotation(Member onMember, int argsIndex, int paramAnnoIndex) { + if (!(onMember instanceof AccessibleObject)) + return null; + // 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.AnnotationGen[][] anns = null; +// if (onMember instanceof Method) { +// org.aspectj.apache.bcel.classfile.Method bcelMethod = jc.getMethod((Method) onMember); +// if (bcelMethod == null) { +// // pr220430 +// // System.err.println( +// // "Unexpected problem in Java15AnnotationFinder: cannot retrieve annotations on method '" +// // + onMember.getName()+"' in class '"+jc.getClassName()+"'"); +// } else { +// anns = bcelMethod.getParameterAnnotations(); +// } +// } else if (onMember instanceof Constructor) { +// org.aspectj.apache.bcel.classfile.Method bcelCons = jc.getMethod((Constructor) onMember); +// anns = bcelCons.getParameterAnnotations(); +// } else if (onMember instanceof Field) { +// // anns = null; +// } +// // the answer is cached and we don't want to hold on to memory +// bcelRepository.clear(); +// if (anns == null) +// return null; +// +// if (argsIndex>=anns.length) { +// return null; +// } +// AnnotationGen[] parameterAnnotationsOnParticularArg = anns[argsIndex]; +// if (parameterAnnotationsOnParticularArg==null || paramAnnoIndex>=parameterAnnotationsOnParticularArg.length) { +// return null; +// } +// AnnotationGen parameterAnnotation = parameterAnnotationsOnParticularArg[paramAnnoIndex]; +//// if (parameterAnnotation.getTypeSignature().equals(ofType.getSignature())) { +// return new BcelAnnotation(parameterAnnotation, world); +//// } else { +//// return null; +//// } +// } catch (ClassNotFoundException cnfEx) { +// // just use reflection then +// } + + // reflection... + AccessibleObject ao = (AccessibleObject) onMember; + Annotation[][] anns = null; + if (onMember instanceof Method) { + anns = ((Method) ao).getParameterAnnotations(); + } else if (onMember instanceof Constructor) { + anns = ((Constructor) ao).getParameterAnnotations(); + } else if (onMember instanceof Field) { + // anns = null; + } + if (anns == null || argsIndex>=anns.length) { + return null; + } + Annotation[] parameterAnnotationsOnParticularArg = anns[argsIndex]; + if (parameterAnnotationsOnParticularArg==null || paramAnnoIndex>=parameterAnnotationsOnParticularArg.length) { + return null; + } + return parameterAnnotationsOnParticularArg[paramAnnoIndex]; + } } diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/ReflectiveAnnotationAJ.java b/weaver5/java5-src/org/aspectj/weaver/reflect/ReflectiveAnnotationAJ.java new file mode 100644 index 000000000..0b486b7ed --- /dev/null +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/ReflectiveAnnotationAJ.java @@ -0,0 +1,103 @@ +/* ******************************************************************* + * Copyright (c) 2016 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: + * Andy Clement Initial implementation + * ******************************************************************/ +package org.aspectj.weaver.reflect; + +import java.lang.annotation.Annotation; +import java.util.Set; + +import org.aspectj.weaver.AnnotationAJ; +import org.aspectj.weaver.ResolvedType; + +/** + * An AnnotationAJ that wraps a java.lang.reflect Annotation. + * + * @author Andy Clement + */ +public class ReflectiveAnnotationAJ implements AnnotationAJ { + + private Annotation anno; + + public ReflectiveAnnotationAJ(Annotation anno) { + this.anno = anno; + } + + public String getTypeSignature() { + // TODO Auto-generated method stub + return null; + } + + public String getTypeName() { + // TODO Auto-generated method stub + return null; + } + + public ResolvedType getType() { + // TODO Auto-generated method stub + return null; + } + + public boolean allowedOnAnnotationType() { + // TODO Auto-generated method stub + return false; + } + + public boolean allowedOnField() { + // TODO Auto-generated method stub + return false; + } + + public boolean allowedOnRegularType() { + // TODO Auto-generated method stub + return false; + } + + public Set<String> getTargets() { + // TODO Auto-generated method stub + return null; + } + + public boolean hasNamedValue(String name) { + // TODO Auto-generated method stub + return false; + } + + public boolean hasNameValuePair(String name, String value) { + // TODO Auto-generated method stub + return false; + } + + public String getValidTargets() { + // TODO Auto-generated method stub + return null; + } + + public String stringify() { + // TODO Auto-generated method stub + return null; + } + + public boolean specifiesTarget() { + // TODO Auto-generated method stub + return false; + } + + public boolean isRuntimeVisible() { + // TODO Auto-generated method stub + return false; + } + + public String getStringFormOfValue(String name) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java b/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java index 9b155df3e..e3a4981c1 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java @@ -11,6 +11,7 @@ * ******************************************************************/ package org.aspectj.weaver.tools; +import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; @@ -63,6 +64,9 @@ public class Java15PointcutExpressionTest extends TestCase { private Method b; private Method c; private Method d; + private Method e; + private Method f; + /** * Parse some expressions and ensure we capture the parameter annotations and parameter type annotations correctly. @@ -508,6 +512,43 @@ public class Java15PointcutExpressionTest extends TestCase { assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[1].getBinding()); } + public void testAtArgsWithParamBinding() throws Exception { + // B class contains: public void e(@MyAnnotation A anA, B aB) {} + PointcutParameter pp = parser.createPointcutParameter("a", MyAnnotation.class); + PointcutExpression atArgs = parser.parsePointcutExpression("@args(a (*),..)",A.class,new PointcutParameter[] {pp}); + ShadowMatch shadowMatch = atArgs.matchesMethodExecution(e); + assertTrue(shadowMatch.alwaysMatches()); + JoinPointMatch jpm = shadowMatch.matchesJoinPoint(new B(), new B(), new Object[] {new A(), new B()}); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation expectedAnnotation = (MyAnnotation)B.class.getDeclaredMethod("e", A.class,B.class).getParameterAnnotations()[0][0]; + Object boundAnnotation = jpm.getParameterBindings()[0].getBinding(); + assertEquals(expectedAnnotation,boundAnnotation); + + pp = parser.createPointcutParameter("a", MyAnnotationWithValue.class); + PointcutParameter pp2 = parser.createPointcutParameter("b", MyAnnotationWithValue.class); + atArgs = parser.parsePointcutExpression("@args(a,b)",A.class,new PointcutParameter[] {pp,pp2}); + shadowMatch = atArgs.matchesMethodExecution(f); + assertTrue(shadowMatch.alwaysMatches()); + jpm = shadowMatch.matchesJoinPoint(new B(), new B(), new Object[] {new A(), new B()}); + assertEquals(2,jpm.getParameterBindings().length); + MyAnnotationWithValue expectedAnnotation1 = (MyAnnotationWithValue)B.class.getDeclaredMethod("e", A.class,B.class).getParameterAnnotations()[0][0]; + MyAnnotationWithValue expectedAnnotation2 = (MyAnnotationWithValue)B.class.getDeclaredMethod("e", A.class,B.class).getParameterAnnotations()[1][0]; + Object boundAnnotation1 = jpm.getParameterBindings()[0].getBinding(); + assertEquals(expectedAnnotation1,boundAnnotation1); + Object boundAnnotation2 = jpm.getParameterBindings()[1].getBinding(); + assertEquals(expectedAnnotation2,boundAnnotation1); + +// +// 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); @@ -670,11 +711,18 @@ public class Java15PointcutExpressionTest extends TestCase { b = B.class.getMethod("b"); c = B.class.getMethod("c",new Class[] {A.class,B.class}); d = B.class.getMethod("d",new Class[] {A.class,A.class}); + e = B.class.getMethod("e", new Class[] {A.class, B.class}); + f = B.class.getMethod("f", A.class, B.class); } @Retention(RetentionPolicy.RUNTIME) private @interface MyAnnotation {} - + + @Retention(RetentionPolicy.RUNTIME) + private @interface MyAnnotationWithValue { + String value(); + } + private @interface MyClassFileRetentionAnnotation {} private static class A { @@ -687,6 +735,10 @@ public class Java15PointcutExpressionTest extends TestCase { public void c(A anA, B aB) {} public void d(A anA, A anotherA) {} + + public void e(@MyAnnotation A anA, B aB) {} + + public void f(@MyAnnotationWithValue("abc") A anA, @MyAnnotationWithValue("def") B aB) {} } private static class C { |