From 62024412b0efe3fe153cf02e460785d7137876ba Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Thu, 28 Sep 2017 16:05:13 -0700 Subject: [PATCH] Tests for smart annotation unpacking for reflection types --- ...5ReflectionBasedReferenceTypeDelegate.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java b/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java index 3eb59cad6..9474d63cd 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/TestJava5ReflectionBasedReferenceTypeDelegate.java @@ -15,6 +15,10 @@ package org.aspectj.weaver; import junit.framework.Test; import junit.framework.TestSuite; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; + import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegateTest; public class TestJava5ReflectionBasedReferenceTypeDelegate extends ReflectionBasedReferenceTypeDelegateTest { @@ -73,5 +77,72 @@ public class TestJava5ReflectionBasedReferenceTypeDelegate extends ReflectionBas ResolvedType rt2 = genericType.getSuperclass(); assertTrue("Superclass for Map generic type should be Object but was " + rt2, rt2.equals(UnresolvedType.OBJECT)); } + + + /** + * This is testing the optimization in the reflective annotation finder to verify that if you only want runtime + * annotation info then we use reflection and don't go digging through the classfile bytes. + */ + public void testAnnotationFinderClassRetention() throws Exception { + ResolvedType type = world.resolve(AnnoTesting.class.getName()); + ResolvedMember[] ms = type.getDeclaredMethods(); + int findMethod = findMethod("a", ms); + + ResolvedMember methodWithOnlyClassLevelAnnotation = ms[findMethod("a", ms)]; + ResolvedMember methodWithOnlyRuntimeLevelAnnotation = ms[findMethod("b", ms)]; + ResolvedMember methodWithClassAndRuntimeLevelAnnotations = ms[findMethod("c", ms)]; + ResolvedMember methodWithClassAndRuntimeLevelAnnotations2 = ms[findMethod("d", ms)]; + + assertTrue(methodWithOnlyClassLevelAnnotation.hasAnnotation(world.resolve(AnnoClass.class.getName()))); + assertTrue(methodWithOnlyRuntimeLevelAnnotation.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + + // This is the tricky scenario. + + // When asking about the runtime level annotations it should not go digging into bcel + assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + + Field annotationsField = ResolvedMemberImpl.class.getDeclaredField("annotationTypes"); + annotationsField.setAccessible(true); + ResolvedType[] annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations); + + // Should only be the runtime one here + assertEquals(1, annoTypes.length); + + // But when you do ask again and this time for class level, it should redo the unpack and pull both runtime and class out + assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoClass.class.getName()))); + + annotationsField.setAccessible(true); + annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations); + + // Now both should be there + assertEquals(2, annoTypes.length); + + assertTrue(methodWithClassAndRuntimeLevelAnnotations2.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + // now ask for 'all annotations' via another route, this should reunpack and get them all + ResolvedType[] annotations = methodWithClassAndRuntimeLevelAnnotations2.getAnnotationTypes(); + assertEquals(2,annotations.length); + } + + @Retention(RetentionPolicy.CLASS) + @interface AnnoClass {} + + @Retention(RetentionPolicy.RUNTIME) + @interface AnnoRuntime {} + + class AnnoTesting { + + @AnnoClass + public void a() {} + + @AnnoRuntime + public void b() {} + + @AnnoClass @AnnoRuntime + public void c() {} + + @AnnoClass @AnnoRuntime + public void d() {} + + } } \ No newline at end of file -- 2.39.5