8202469 / 8202473: Correct type annotation resolution for class type variables

Rafael Winterhalter rafael.wth at gmail.com
Tue Jul 23 18:51:22 UTC 2019


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;


More information about the core-libs-dev mailing list