Path: blob/master/test/jdk/java/lang/annotation/TestConstructorParameterAnnotations.java
41149 views
/*1* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 807497726* @summary Test consistency of annotations on constructor parameters27* @compile TestConstructorParameterAnnotations.java28* @run main TestConstructorParameterAnnotations29* @compile -parameters TestConstructorParameterAnnotations.java30* @run main TestConstructorParameterAnnotations31*/3233import java.lang.annotation.*;34import java.lang.reflect.*;35import java.util.*;3637/*38* Some constructor parameters are <em>mandated</em>; that is, they39* are not explicitly present in the source code, but required to be40* present by the Java Language Specification. In other cases, some41* constructor parameters are not present in the source, but are42* synthesized by the compiler as an implementation artifact. There is43* not a reliable mechanism to consistently determine whether or not44* a parameter is implicit or not.45*46* (Using the "-parameters" option to javac does emit the information47* needed to make a reliably determination, but the information is not48* present by default.)49*50* The lack of such a mechanism causes complications reading parameter51* annotations in some cases since annotations for parameters are52* written out for the parameters in the source code, but when reading53* annotations at runtime all the parameters, including implicit ones,54* are present.55*/56public class TestConstructorParameterAnnotations {57public static void main(String... args) {58int errors = 0;59Class<?>[] classes = {NestedClass0.class,60NestedClass1.class,61NestedClass2.class,62NestedClass3.class,63NestedClass4.class,64StaticNestedClass0.class,65StaticNestedClass1.class,66StaticNestedClass2.class,67StaticNestedClass3.class,68StaticNestedClass4.class};6970for (Class<?> clazz : classes) {71for (Constructor<?> ctor : clazz.getConstructors()) {72System.out.println(ctor);73errors += checkGetParameterAnnotations(clazz, ctor);74errors += checkGetParametersGetAnnotation(clazz, ctor);75}76}7778if (errors > 0)79throw new RuntimeException(errors + " errors.");80return;81}8283private static int checkGetParameterAnnotations(Class<?> clazz,84Constructor<?> ctor) {85String annotationString =86Arrays.deepToString(ctor.getParameterAnnotations());87String expectedString =88clazz.getAnnotation(ExpectedGetParameterAnnotations.class).value();8990if (!Objects.equals(annotationString, expectedString)) {91System.err.println("Annotation mismatch on " + ctor +92"\n\tExpected:" + expectedString +93"\n\tActual: " + annotationString);94return 1;95}96return 0;97}9899private static int checkGetParametersGetAnnotation(Class<?> clazz,100Constructor<?> ctor) {101int errors = 0;102int i = 0;103ExpectedParameterAnnotations epa =104clazz.getAnnotation(ExpectedParameterAnnotations.class);105106for (Parameter param : ctor.getParameters() ) {107String annotationString =108Objects.toString(param.getAnnotation(MarkerAnnotation.class));109String expectedString = epa.value()[i];110111if (!Objects.equals(annotationString, expectedString)) {112System.err.println("Annotation mismatch on " + ctor +113" on param " + param +114"\n\tExpected:" + expectedString +115"\n\tActual: " + annotationString);116errors++;117}118i++;119}120return errors;121}122123@ExpectedGetParameterAnnotations("[[]]")124@ExpectedParameterAnnotations({"null"})125public class NestedClass0 {126public NestedClass0() {}127}128129@ExpectedGetParameterAnnotations(130"[[], " +131"[@TestConstructorParameterAnnotations$MarkerAnnotation(1)]]")132@ExpectedParameterAnnotations({133"null",134"@TestConstructorParameterAnnotations$MarkerAnnotation(1)"})135public class NestedClass1 {136public NestedClass1(@MarkerAnnotation(1) int parameter) {}137}138139@ExpectedGetParameterAnnotations(140"[[], " +141"[@TestConstructorParameterAnnotations$MarkerAnnotation(2)], " +142"[]]")143@ExpectedParameterAnnotations({144"null",145"@TestConstructorParameterAnnotations$MarkerAnnotation(2)",146"null"})147public class NestedClass2 {148public NestedClass2(@MarkerAnnotation(2) int parameter1,149int parameter2) {}150}151152@ExpectedGetParameterAnnotations(153"[[], " +154"[@TestConstructorParameterAnnotations$MarkerAnnotation(3)], " +155"[]]")156@ExpectedParameterAnnotations({157"null",158"@TestConstructorParameterAnnotations$MarkerAnnotation(3)",159"null"})160public class NestedClass3 {161public <P> NestedClass3(@MarkerAnnotation(3) P parameter1,162int parameter2) {}163}164165@ExpectedGetParameterAnnotations(166"[[], " +167"[@TestConstructorParameterAnnotations$MarkerAnnotation(4)], " +168"[]]")169@ExpectedParameterAnnotations({170"null",171"@TestConstructorParameterAnnotations$MarkerAnnotation(4)",172"null"})173public class NestedClass4 {174public <P, Q> NestedClass4(@MarkerAnnotation(4) P parameter1,175Q parameter2) {}176}177178@ExpectedGetParameterAnnotations("[]")179@ExpectedParameterAnnotations({"null"})180public static class StaticNestedClass0 {181public StaticNestedClass0() {}182}183184@ExpectedGetParameterAnnotations(185"[[@TestConstructorParameterAnnotations$MarkerAnnotation(1)]]")186@ExpectedParameterAnnotations({187"@TestConstructorParameterAnnotations$MarkerAnnotation(1)"})188public static class StaticNestedClass1 {189public StaticNestedClass1(@MarkerAnnotation(1) int parameter) {}190}191192@ExpectedGetParameterAnnotations(193"[[@TestConstructorParameterAnnotations$MarkerAnnotation(2)], " +194"[]]")195@ExpectedParameterAnnotations({196"@TestConstructorParameterAnnotations$MarkerAnnotation(2)",197"null"})198public static class StaticNestedClass2 {199public StaticNestedClass2(@MarkerAnnotation(2) int parameter1,200int parameter2) {}201}202203@ExpectedGetParameterAnnotations(204"[[@TestConstructorParameterAnnotations$MarkerAnnotation(3)], " +205"[]]")206@ExpectedParameterAnnotations({207"@TestConstructorParameterAnnotations$MarkerAnnotation(3)",208"null"})209public static class StaticNestedClass3 {210public <P> StaticNestedClass3(@MarkerAnnotation(3) P parameter1,211int parameter2) {}212}213214@ExpectedGetParameterAnnotations(215"[[@TestConstructorParameterAnnotations$MarkerAnnotation(4)], " +216"[]]")217@ExpectedParameterAnnotations({218"@TestConstructorParameterAnnotations$MarkerAnnotation(4)",219"null"})220public static class StaticNestedClass4 {221public <P, Q> StaticNestedClass4(@MarkerAnnotation(4) P parameter1,222Q parameter2) {}223}224225@Target(ElementType.PARAMETER)226@Retention(RetentionPolicy.RUNTIME)227@interface MarkerAnnotation {228int value();229}230231/**232* String form of expected value of calling233* getParameterAnnotations on a constructor.234*/235@Target(ElementType.TYPE)236@Retention(RetentionPolicy.RUNTIME)237@interface ExpectedGetParameterAnnotations {238String value();239}240241/**242* String form of expected value of calling243* getAnnotation(MarkerAnnotation.class) on each element of the244* result of getParameters() on a constructor.245*/246@Target(ElementType.TYPE)247@Retention(RetentionPolicy.RUNTIME)248@interface ExpectedParameterAnnotations {249String[] value();250}251}252253254