I integrated the tests into the jtreg bits (to me it looks like they are running ok but since this is my first time, please double-check).
I have already signed the OCA a few years ago when I did some work on Glassfish. Let me know if anything else is missing or if I need to do anything else. Here comes the inline changeset including the additional jtreg tests: Index: test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationParameterizedNonInterfaceBound.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationParameterizedNonInterfaceBound.java (revision 55752+:8ae33203d600+) +++ test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationParameterizedNonInterfaceBound.java (revision 55752+:8ae33203d600+) @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8202473 + * @summary Make sure a type variable bound on a parameterized non-interface bound does not receive a type path offset + */ + +import java.lang.annotation.Target; +import java.lang.annotation.*; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; + +public class TestTypeAnnotationParameterizedNonInterfaceBound<U extends @TestTypeAnnotationParameterizedNonInterfaceBound.TypeAnnotation ArrayList<?>> { + + public static void main(String[] args) { + TypeVariable<?>[] variables = TestTypeAnnotationParameterizedNonInterfaceBound.class.getTypeParameters(); + TypeVariable<?> variable = variables[0]; + AnnotatedType[] bounds = variable.getAnnotatedBounds(); + AnnotatedType bound = bounds[0]; + Annotation[] annotations = bound.getAnnotations(); + if (annotations.length != 1) { + throw new AssertionError(); + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + @interface TypeAnnotation { } +} Index: test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationTwoVariables.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationTwoVariables.java (revision 55752+:8ae33203d600+) +++ test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationTwoVariables.java (revision 55752+:8ae33203d600+) @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8202473 + * @summary Make sure a type path for a type variable's bound is filtered by variable index + */ + +import java.lang.annotation.Target; +import java.lang.annotation.*; +import java.lang.reflect.AnnotatedParameterizedType; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.TypeVariable; +import java.util.concurrent.Callable; + +public class TestTypeAnnotationTwoVariables< + U extends Callable<@TestTypeAnnotationTwoVariables.TypeAnnotation(0) ?>, + V extends Callable<@TestTypeAnnotationTwoVariables.TypeAnnotation(1) ?>> { + + public static void main(String[] args) { + TypeVariable<?>[] variables = TestTypeAnnotationTwoVariables.class.getTypeParameters(); + for (int i = 0; i < 2; i++) { + TypeVariable<?> variable = variables[i]; + AnnotatedType[] bounds = variable.getAnnotatedBounds(); + AnnotatedType bound = bounds[0]; + AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) bound; + AnnotatedType[] actualTypeArguments = parameterizedType.getAnnotatedActualTypeArguments(); + Annotation[] annotations = actualTypeArguments[0].getAnnotations(); + if (annotations.length != 1 || ((TypeAnnotation) annotations[0]).value() != i) { + throw new AssertionError(); + } + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + @interface TypeAnnotation { + int value(); + } +} Index: test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationTypeVariableBound.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationTypeVariableBound.java (revision 55752+:8ae33203d600+) +++ test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationTypeVariableBound.java (revision 55752+:8ae33203d600+) @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8202469 + * @summary Make sure a type variable that has another type variable as its bound receives the correct type annotation + */ + +import java.lang.annotation.Target; +import java.lang.annotation.*; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.TypeVariable; + +public class TestTypeAnnotationTypeVariableBound<U, V extends @TestTypeAnnotationTypeVariableBound.TypeAnnotation U> { + + public static void main(String[] args) { + TypeVariable<?>[] variables = TestTypeAnnotationTypeVariableBound.class.getTypeParameters(); + TypeVariable<?> variable = variables[1]; + AnnotatedType[] bounds = variable.getAnnotatedBounds(); + AnnotatedType bound = bounds[0]; + Annotation[] annotations = bound.getAnnotations(); + if (annotations.length != 1) { + throw new AssertionError(); + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + @interface TypeAnnotation { } +} Index: test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationUnionBound.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationUnionBound.java (revision 55752+:8ae33203d600+) +++ test/jdk/java/lang/reflect/AnnotatedElement/TestTypeAnnotationUnionBound.java (revision 55752+:8ae33203d600+) @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8202473 + * @summary Make sure that the union bounds of a type variable receive the correct type annotations + */ + +import java.lang.annotation.Target; +import java.lang.annotation.*; +import java.lang.reflect.AnnotatedParameterizedType; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.TypeVariable; +import java.util.List; +import java.util.concurrent.Callable; + +public class TestTypeAnnotationUnionBound< + U extends Callable<@TestTypeAnnotationUnionBound.TypeAnnotation(0) ?> & List<@TestTypeAnnotationUnionBound.TypeAnnotation(1) ?>> { + + public static void main(String[] args) { + TypeVariable<?>[] variables = TestTypeAnnotationUnionBound.class.getTypeParameters(); + TypeVariable<?> variable = variables[0]; + if (variable.getAnnotations().length > 0) { + throw new AssertionError(); + } + AnnotatedType[] bounds = variable.getAnnotatedBounds(); + for (int i = 0; i < 2; i++) { + AnnotatedType bound = bounds[i]; + AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) bound; + AnnotatedType[] actualTypeArguments = parameterizedType.getAnnotatedActualTypeArguments(); + Annotation[] annotations = actualTypeArguments[0].getAnnotations(); + if (annotations.length != 1 || ((TypeAnnotation) annotations[0]).value() != i) { + throw new AssertionError(); + } + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.TYPE_USE) + @interface TypeAnnotation { + int value(); + } +} Index: src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java (revision 55752:8ae33203d600a7c9f9b2be9b31a0eb8197270ab1) +++ src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java (revision 55752+:8ae33203d600+) @@ -276,11 +276,21 @@ // index 1. if (bounds.length > 0) { Type b0 = bounds[0]; - if (!(b0 instanceof Class<?>)) { - startIndex = 1; - } else { - Class<?> c = (Class<?>)b0; - if (c.isInterface()) { + if (!(b0 instanceof TypeVariable<?>)) { + if (b0 instanceof Class<?>) { + Class<?> c = (Class<?>) b0; + if (c.isInterface()) { + startIndex = 1; + } + } else if (b0 instanceof ParameterizedType) { + ParameterizedType p = (ParameterizedType) b0; + Type r = p.getRawType(); + if (!(r instanceof Class<?>)) { + throw new AnnotationFormatError("Unexpected raw type: " + r); + } else if (((Class<?>) r).isInterface()) { + startIndex = 1; + } + } else { startIndex = 1; } } @@ -295,10 +305,11 @@ l.add(t); } } + TypeAnnotation[] annon = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY); res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], AnnotatedTypeFactory.nestingForType(bounds[i], loc), - l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), - candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), + annon, + annon, (AnnotatedElement)decl); } return res;