summaryrefslogtreecommitdiffstats
path: root/weaver5
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2016-12-02 10:32:17 -0800
committerAndy Clement <aclement@pivotal.io>2016-12-02 10:32:17 -0800
commitd10618d25a9e995ffeb8080b3b9468ad241a163c (patch)
treee6d7392533635926c055048deb040e778fe92e20 /weaver5
parentb6f2b6337fbaf95b78c20862cd90f0e027509531 (diff)
downloadaspectj-paramAnnotationBinding.tar.gz
aspectj-paramAnnotationBinding.zip
259416: preliminary workparamAnnotationBinding
Diffstat (limited to 'weaver5')
-rw-r--r--weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java71
-rw-r--r--weaver5/java5-src/org/aspectj/weaver/reflect/ReflectiveAnnotationAJ.java103
-rw-r--r--weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java54
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 {