diff options
author | 2016-01-14 16:05:47 -0800 | |
---|---|---|
committer | 2016-01-27 13:14:10 -0800 | |
commit | c167ee9b65f05f7c6f007d587fd1655388edaee9 (patch) | |
tree | 57e846f6aaad969020972f55a082e3e22884592e /test/048-reflect-v8/src/AnnotationTest.java | |
parent | 2aaf58e90c9229610b2a16644e9866b6741ce9ca (diff) |
reflection: Add new 1.8 AnnotatedElement methods and tests
Also:
* Bump the size of the Class vtable size since 3 new virtuals were
added to java.lang.Class
* Refactor Method#isDefault test into a separate file within 048 test.
Change-Id: I8420a4d208bb60874a9cf996766313c7d5058c45
Diffstat (limited to 'test/048-reflect-v8/src/AnnotationTest.java')
-rw-r--r-- | test/048-reflect-v8/src/AnnotationTest.java | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/test/048-reflect-v8/src/AnnotationTest.java b/test/048-reflect-v8/src/AnnotationTest.java new file mode 100644 index 0000000000..75e684557c --- /dev/null +++ b/test/048-reflect-v8/src/AnnotationTest.java @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +public class AnnotationTest extends AnnotationTestHelpers { + public static void testAnnotationsByType() { + System.out.println("=============================="); + System.out.println("Class annotations by type:"); + System.out.println("=============================="); + + // Print associated annotations: + // * A is directly present or repeatably present on an element E; + // * No annotation of A is directly/repeatably present on an element + // AND E is a class AND A's type is inheritable, AND A is associated with its superclass. + // (Looks through subtypes recursively only if there's 0 result at each level, + // and the annotation is @Inheritable). + printAnnotationsByType(Calendar.class, SingleUser.class); + printAnnotationsByType(Calendars.class, SingleUser.class); + + printAnnotationsByType(Calendar.class, User.class); + printAnnotationsByType(Calendars.class, User.class); + + printAnnotationsByType(Calendar.class, User2.class); // Enforce ordering 'z,x,y' + printAnnotationsByType(Calendars.class, User2.class); + + // NOTE: + // Order of outer-most annotations Calendars[C,C],S vs C,Calendars[C,C] is unspecified. + // In particular it's the order of #getDeclaredAnnotations which is completely unmentioned. + // The only requirement for #getAnnotationsByType is to have same ordering as + // #getDeclaredAnnotations. + // (Calendars[] itself has to maintain value() order). + printAnnotationsByType(Calendar.class, UserComplex.class); // Cs(C,C),C collapses into C,C,C. + printAnnotationsByType(Calendars.class, UserComplex.class); + + printAnnotationsByType(Calendar.class, UserSub.class); + printAnnotationsByType(Calendars.class, UserSub.class); + + printAnnotationsByType(Calendar.class, UserSub2.class); + // The directly present "Calendar" annotation masks all the repeatably present + // "Calendar" annotations coming from User. + printAnnotationsByType(Calendars.class, UserSub2.class); + // Edge case: UserSub2 doesn't directly have a Calendars annotation, + // so it doesn't mask the "User" Calendars annotation. + + System.out.println("-----------------------------"); + System.out.println("-----------------------------"); + + } + + public static void testDeclaredAnnotation() { + System.out.println("=============================="); + System.out.println("Class declared annotation:"); + System.out.println("=============================="); + + // Print directly present annotations: + // + // The element E has an annotation_item for it (accessible through an + // annotations_directory_item) corresponding to an annotation A, + // and A's type_idx must match that on the encoded_annotation (from the annotation_item). + // (Does not look through the subtypes recursively) + printDeclaredAnnotation(SingleUser.class, Calendar.class); + printDeclaredAnnotation(SingleUser.class, Calendars.class); + + printDeclaredAnnotation(User.class, Calendar.class); + printDeclaredAnnotation(User.class, Calendars.class); + + printDeclaredAnnotation(UserComplex.class, Calendar.class); + printDeclaredAnnotation(UserComplex.class, Calendars.class); + + printDeclaredAnnotation(UserSub.class, Calendar.class); + printDeclaredAnnotation(UserSub.class, Calendars.class); + + printDeclaredAnnotation(UserSub2.class, Calendar.class); + printDeclaredAnnotation(UserSub2.class, Calendars.class); + + System.out.println("-----------------------------"); + System.out.println("-----------------------------"); + } + + public static void testDeclaredAnnotationsByType() { + System.out.println("=============================="); + System.out.println("Declared class annotations by type:"); + System.out.println("=============================="); + + // A is directly present or repeatably present on an element E; + // -- (does not do any recursion for classes regardless of @Inherited) + printDeclaredAnnotationsByType(Calendar.class, SingleUser.class); + printDeclaredAnnotationsByType(Calendars.class, SingleUser.class); + + printDeclaredAnnotationsByType(Calendar.class, User.class); + printDeclaredAnnotationsByType(Calendars.class, User.class); + + printDeclaredAnnotationsByType(Calendar.class, User2.class); // Enforce ordering 'z,x,y' + printDeclaredAnnotationsByType(Calendars.class, User2.class); + + printDeclaredAnnotationsByType(Calendar.class, UserComplex.class); + printDeclaredAnnotationsByType(Calendars.class, UserComplex.class); + + printDeclaredAnnotationsByType(Calendar.class, UserSub.class); + printDeclaredAnnotationsByType(Calendars.class, UserSub.class); + + printDeclaredAnnotationsByType(Calendar.class, UserSub2.class); + // The directly present "Calendar" annotation masks all the repeatably present "Calendar" + // annotations coming from User. + printDeclaredAnnotationsByType(Calendars.class, UserSub2.class); + // Edge case: UserSub2 doesn't directly have a Calendars annotation, + // so it doesn't mask the "User" Calendars annotation. + + System.out.println("-----------------------------"); + System.out.println("-----------------------------"); + } + + // Print the annotation "annotationClass" that is associated with an element denoted by + // "annotationUseClass." + private static <A extends Annotation> void printAnnotationsByType(Class<A> annotationClass, + Class<?> annotationUseClass) { + A[] annotationsByType = annotationUseClass.getAnnotationsByType(annotationClass); + + String msg = "Annotations by type, defined by class " + + annotationUseClass.getName() + " with annotation " + annotationClass.getName() + ": " + + asString(annotationsByType); + + + System.out.println(msg); + } + + private static <A extends Annotation> void printDeclaredAnnotation(Class<?> annotationUseClass, + Class<A> annotationDefClass) { + A anno = annotationUseClass.getDeclaredAnnotation(annotationDefClass); + + String msg = asString(anno); + + System.out.println("Declared annotations by class " + annotationUseClass + + ", annotation " + annotationDefClass + ": " + msg); + } + + // Print the annotation "annotationClass" that is directly/indirectly present with an element + // denoted by "annotationUseClass." + private static <A extends Annotation> void printDeclaredAnnotationsByType( + Class<A> annotationClass, Class<?> annotationUseClass) { + A[] annotationsByType = annotationUseClass.getDeclaredAnnotationsByType(annotationClass); + + String msg = "Declared annnotations by type, defined by class " + annotationUseClass.getName() + + " with annotation " + annotationClass.getName() + ": " + + asString(annotationsByType); + + System.out.println(msg); + } + + public static void testMethodAnnotationsByType() { + System.out.println("=============================="); + System.out.println("Method annotations by type:"); + System.out.println("=============================="); + + // Print associated annotations: + // * A is directly present or repeatably present on an element E; + // * No annotation of A is directly/repeatably present on an element AND E is a class + // AND A's type is inheritable, AND A is associated with its superclass. + // (Looks through subtypes recursively only if there's 0 result at each level, + // and the annotation is @Inheritable). + printMethodAnnotationsByType(Calendar.class, "singleUser", AnnotationTestFixture.class); + printMethodAnnotationsByType(Calendars.class, "singleUser", AnnotationTestFixture.class); + + printMethodAnnotationsByType(Calendar.class, "user", AnnotationTestFixture.class); + printMethodAnnotationsByType(Calendars.class, "user", AnnotationTestFixture.class); + + printMethodAnnotationsByType(Calendar.class, "user2", AnnotationTestFixture.class); + printMethodAnnotationsByType(Calendars.class, "user2", AnnotationTestFixture.class); + + printMethodAnnotationsByType(Calendar.class, "userComplex", AnnotationTestFixture.class); + printMethodAnnotationsByType(Calendars.class, "userComplex", AnnotationTestFixture.class); + + System.out.println("-----------------------------"); + System.out.println("-----------------------------"); + } + + // Print the annotation "annotationClass" that is associated with an element denoted by + // "annotationUseClass" method methodName. + private static <A extends Annotation> void printMethodAnnotationsByType(Class<A> annotationClass, + String methodName, Class<?> annotationUseClass) { + Method m = null; + try { + m = annotationUseClass.getDeclaredMethod(methodName); + } catch (Throwable t) { + throw new AssertionError(t); + } + A[] annotationsByType = m.getAnnotationsByType(annotationClass); + + String msg = "Annotations by type, defined by method " + m.getName() + " with annotation " + + annotationClass.getName() + ": " + + asString(annotationsByType); + + System.out.println(msg); + } + + public static void testMethodDeclaredAnnotations() { + System.out.println("=============================="); + System.out.println("Declared method annotations:"); + System.out.println("=============================="); + + printMethodDeclaredAnnotation(Calendar.class, "singleUser", AnnotationTestFixture.class); + printMethodDeclaredAnnotation(Calendars.class, "singleUser", AnnotationTestFixture.class); + + printMethodDeclaredAnnotation(Calendar.class, "user", AnnotationTestFixture.class); + printMethodDeclaredAnnotation(Calendars.class, "user", AnnotationTestFixture.class); + + printMethodDeclaredAnnotation(Calendar.class, "user2", AnnotationTestFixture.class); + printMethodDeclaredAnnotation(Calendars.class, "user2", AnnotationTestFixture.class); + + printMethodDeclaredAnnotation(Calendar.class, "userComplex", AnnotationTestFixture.class); + printMethodDeclaredAnnotation(Calendars.class, "userComplex", AnnotationTestFixture.class); + + System.out.println("-----------------------------"); + System.out.println("-----------------------------"); + } + + // Print the annotation "annotationClass" that is associated with an element denoted by + // methodName in annotationUseClass. + private static <A extends Annotation> void printMethodDeclaredAnnotation(Class<A> annotationClass, + String methodName, Class<?> annotationUseClass) { + Method m = null; + try { + m = annotationUseClass.getDeclaredMethod(methodName); + } catch (Throwable t) { + throw new AssertionError(t); + } + Annotation annotationsByType = m.getDeclaredAnnotation(annotationClass); + + String msg = "Annotations declared by method " + m.getName() + " with annotation " + + annotationClass.getName() + ": " + + asString(annotationsByType); + + System.out.println(msg); + } + + public static void testMethodDeclaredAnnotationsByType() { + System.out.println("=============================="); + System.out.println("Declared method annotations by type:"); + System.out.println("=============================="); + + printMethodDeclaredAnnotationByType(Calendar.class, "singleUser", AnnotationTestFixture.class); + printMethodDeclaredAnnotationByType(Calendars.class, "singleUser", AnnotationTestFixture.class); + + printMethodDeclaredAnnotationByType(Calendar.class, "user", AnnotationTestFixture.class); + printMethodDeclaredAnnotationByType(Calendars.class, "user", AnnotationTestFixture.class); + + printMethodDeclaredAnnotationByType(Calendar.class, "user2", AnnotationTestFixture.class); + printMethodDeclaredAnnotationByType(Calendars.class, "user2", AnnotationTestFixture.class); + + printMethodDeclaredAnnotationByType(Calendar.class, "userComplex", AnnotationTestFixture.class); + printMethodDeclaredAnnotationByType(Calendars.class, "userComplex", + AnnotationTestFixture.class); + + System.out.println("-----------------------------"); + System.out.println("-----------------------------"); + } + + // Print the annotation "annotationClass" that is associated with an element denoted by + // methodName in annotationUseClass. + private static <A extends Annotation> void printMethodDeclaredAnnotationByType( + Class<A> annotationClass, String methodName, Class<?> annotationUseClass) { + Method m = null; + try { + m = annotationUseClass.getDeclaredMethod(methodName); + } catch (Throwable t) { + throw new AssertionError(t); + } + A[] annotationsByType = m.getDeclaredAnnotationsByType(annotationClass); + + String msg = "Annotations by type, defined by method " + m.getName() + " with annotation " + + annotationClass.getName() + ": " + + asString(annotationsByType); + + System.out.println(msg); + } +} |