1 /*
2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8038994
27  * @summary Test that getAnnotatedBounds().getType() match getBounds()
28  * @run testng TypeVariableBounds
29  */
30 
31 import java.io.Serializable;
32 import java.lang.annotation.*;
33 import java.lang.reflect.*;
34 import java.util.concurrent.Callable;
35 import java.util.Arrays;
36 import java.util.List;
37 import java.util.Set;
38 import org.testng.annotations.DataProvider;
39 import org.testng.annotations.Test;
40 
41 import static org.testng.Assert.*;
42 
43 public class TypeVariableBounds {
44     @Test(dataProvider = "classData")
testClass(Class<?> c)45     public void testClass(Class<?> c) throws Exception {
46         assertNotEquals(c.getTypeParameters().length, 0);
47 
48         TypeVariable[] tv = c.getTypeParameters();
49 
50         for(TypeVariable t : tv)
51             testTv(t);
52 
53     }
54 
55     @Test(dataProvider = "methodData")
testMethod(Class<?>c)56     public void testMethod(Class<?>c) throws Exception {
57         Method m = c.getMethod("aMethod");
58         TypeVariable[] tv = m.getTypeParameters();
59 
60         for(TypeVariable t : tv)
61             testTv(t);
62 
63     }
64 
testTv(TypeVariable<?> tv)65     public void testTv(TypeVariable<?> tv) {
66         Type[] t = tv.getBounds();
67         AnnotatedType[] at = tv.getAnnotatedBounds();
68 
69         assertEquals(t.length, at.length, Arrays.asList(t) + " and " + Arrays.asList(at) + " should be the same length");
70 
71         for (int i = 0; i < t.length; i++)
72             assertSame(at[i].getType(), t[i], "T: " + t[i] + ", AT: " + at[i] + ", AT.getType(): " + at[i].getType() + "\n");
73     }
74 
75     @DataProvider
classData()76     public Object[][] classData() { return CLASS_TESTS; }
77 
78     @DataProvider
methodData()79     public Object[][] methodData() { return METHOD_TESTS; }
80 
81     public static final Object[][] CLASS_TESTS = {
82         { Case1.class, },
83         { Case2.class, },
84         { Case5.class, },
85         { Case6.class, },
86     };
87 
88     public static final Object[][] METHOD_TESTS = {
89         { Case3.class, },
90         { Case4.class, },
91         { Case5.class, },
92         { Case6.class, },
93     };
94 
95     // Class type var
96     public static class Case1<C1T1, C1T2 extends AnnotatedElement, C1T3 extends AnnotatedElement & Type & Serializable> {}
97     public static class Case2<C2T0, @TA C2T1 extends Type, C2T2 extends @TB AnnotatedElement, C2T3 extends AnnotatedElement & @TB Type & Serializable> {}
98 
99     // Method type var
aMethod()100     public static class Case3 { public <C3T1, C3T2 extends AnnotatedElement, C3T3 extends AnnotatedElement & Type & Serializable> void aMethod() {}}
aMethod()101     public static class Case4 { public <C4T0, @TA C4T1 extends List, C4T2 extends @TB Set, C4T3 extends Set & @TB Callable & Serializable> void aMethod() {}}
102 
103     // Both
104     public static class Case5 <C5CT1, C5CT2 extends Runnable> {
105         public <C5MT1,
106                C5MT2 extends AnnotatedElement,
107                C5MT3 extends AnnotatedElement & Type & Serializable,
108                C5MT4 extends C5CT2>
aMethod()109                    void aMethod() {}}
110 
111     public static class Case6 <@TA C6CT1, C6CT2 extends @TB Runnable> {
112         public <@TA C6MT1,
113                C6MT2 extends @TB AnnotatedElement,
114                C6MT3 extends @TB AnnotatedElement & @TB2 Type & Serializable,
115                C6MT4 extends @TB2 C6CT2>
aMethod()116                    void aMethod() {}}
117 
118     @Retention(RetentionPolicy.RUNTIME)
119     @Target(ElementType.TYPE_PARAMETER)
120     public @interface TA {}
121 
122     @Retention(RetentionPolicy.RUNTIME)
123     @Target(ElementType.TYPE_USE)
124     public @interface TB {}
125 
126     @Retention(RetentionPolicy.RUNTIME)
127     @Target(ElementType.TYPE_USE)
128     public @interface TB2 {}
129 }
130