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 8039916 27 * @summary Test that a call to getType() on an AnnotatedType returned from an 28 * Executable.getAnnotated* returns the same type as the corresponding 29 * Executable.getGeneric* call. 30 * @run testng TestExecutableGetAnnotatedType 31 */ 32 33 import org.testng.annotations.DataProvider; 34 import org.testng.annotations.Test; 35 36 import java.lang.annotation.*; 37 import java.lang.reflect.*; 38 import java.util.Arrays; 39 import java.util.List; 40 import java.util.stream.Collectors; 41 import java.util.stream.Stream; 42 43 import static org.testng.Assert.*; 44 45 public class TestExecutableGetAnnotatedType { 46 @Test(dataProvider = "genericExecutableData") 47 public void testGenericMethodExceptions(Executable e) throws Exception { 48 testExceptions(e); 49 } 50 51 @Test(dataProvider = "executableData") 52 public void testMethodExceptions(Executable e) throws Exception { 53 testExceptions(e); 54 } 55 56 @Test(dataProvider = "genericExecutableData") 57 public void testGenericMethodParameterTypes(Executable e) throws Exception { 58 testMethodParameters(e); 59 } 60 61 @Test(dataProvider = "executableData") 62 public void testMethodParameterTypes(Executable e) throws Exception { 63 testMethodParameters(e); 64 } 65 66 @Test(dataProvider = "genericExecutableData") 67 public void testGenericParameterTypes(Executable e) throws Exception { 68 testParameters(e.getParameters()); 69 } 70 71 @Test(dataProvider = "executableData") 72 public void testParameterTypes(Executable e) throws Exception { 73 testParameters(e.getParameters()); 74 } 75 76 // should test constructors as well, see JDK-8044629 77 @Test(dataProvider = "genericMethodData") 78 public void testGenericReceiverType(Executable e) throws Exception { 79 testReceiverType0(e); 80 } 81 82 // should test constructors as well, see JDK-8044629 83 @Test(dataProvider = "methodData") 84 public void testReceiverType(Executable e) throws Exception { 85 testReceiverType0(e); 86 } 87 88 @Test(dataProvider = "genericMethodData") 89 public void testGenericMethodReturnType(Object o) throws Exception { 90 // testng gets confused if the param to this method has type Method 91 Method m = (Method)o; 92 testReturnType(m); 93 } 94 95 @Test(dataProvider = "methodData") 96 public void testMethodReturnType(Object o) throws Exception { 97 // testng gets confused if the param to this method has type Method 98 Method m = (Method)o; 99 testReturnType(m); 100 } 101 102 private void testExceptions(Executable e) { 103 Type[] ts = e.getGenericExceptionTypes(); 104 AnnotatedType[] ats = e.getAnnotatedExceptionTypes(); 105 assertEquals(ts.length, ats.length); 106 107 for (int i = 0; i < ts.length; i++) { 108 Type t = ts[i]; 109 AnnotatedType at = ats[i]; 110 assertSame(at.getType(), t, e.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); 111 } 112 } 113 114 private void testMethodParameters(Executable e) { 115 Type[] ts = e.getGenericParameterTypes(); 116 AnnotatedType[] ats = e.getAnnotatedParameterTypes(); 117 assertEquals(ts.length, ats.length); 118 119 for (int i = 0; i < ts.length; i++) { 120 Type t = ts[i]; 121 AnnotatedType at = ats[i]; 122 assertSame(at.getType(), t, e.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); 123 } 124 } 125 126 private void testParameters(Parameter[] params) { 127 for (Parameter p : params) { 128 Type t = p.getParameterizedType(); 129 AnnotatedType at = p.getAnnotatedType(); 130 assertSame(at.getType(), t, p.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); 131 } 132 } 133 134 private void testReceiverType0(Executable e) { 135 if (Modifier.isStatic(e.getModifiers())) 136 assertNull(e.getAnnotatedReceiverType()); 137 else 138 assertSame(e.getAnnotatedReceiverType().getType(), e.getDeclaringClass()); 139 } 140 141 private void testReturnType(Method m) { 142 Type t = m.getGenericReturnType(); 143 AnnotatedType at = m.getAnnotatedReturnType(); 144 assertSame(at.getType(), t, m.toString() + ": T: " + t + ", AT: " + at + ", AT.getType(): " + at.getType() + "\n"); 145 } 146 147 @DataProvider 148 public Object[][] methodData() throws Exception { 149 return filterData(Arrays.stream(Methods1.class.getMethods()), Methods1.class) 150 .toArray(new Object[0][0]); 151 } 152 153 @DataProvider 154 public Object[][] genericMethodData() throws Exception { 155 return filterData(Arrays.stream(GenericMethods1.class.getMethods()), GenericMethods1.class) 156 .toArray(new Object[0][0]); 157 } 158 159 @DataProvider 160 public Object[][] executableData() throws Exception { 161 @SuppressWarnings("raw") 162 List l = filterData(Arrays.stream(Methods1.class.getMethods()), Methods1.class); 163 l.addAll(filterData(Arrays.stream(Methods1.class.getConstructors()), Methods1.class)); 164 l.addAll(filterData(Arrays.stream(Ctors1.class.getConstructors()), Ctors1.class)); 165 return ((List<Object[][]>)l).toArray(new Object[0][0]); 166 } 167 168 @DataProvider 169 public Object[][] genericExecutableData() throws Exception { 170 @SuppressWarnings("raw") 171 List l = filterData(Arrays.stream(GenericMethods1.class.getMethods()), GenericMethods1.class); 172 l.addAll(filterData(Arrays.stream(GenericMethods1.class.getConstructors()), GenericMethods1.class)); 173 l.addAll(filterData(Arrays.stream(GenericCtors1.class.getConstructors()), GenericCtors1.class)); 174 return ((List<Object[][]>)l).toArray(new Object[0][0]); 175 } 176 177 private List<?> filterData(Stream<? extends Executable> l, Class<?> c) { 178 return l.filter(m -> (m.getDeclaringClass() == c)) // remove object methods 179 .map(m -> { Object[] o = new Object[1]; o[0] = m; return o; }) 180 .collect(Collectors.toList()); 181 } 182 183 @Retention(RetentionPolicy.RUNTIME) 184 @Target(ElementType.TYPE_USE) 185 public @interface TA {} 186 187 @Retention(RetentionPolicy.RUNTIME) 188 @Target(ElementType.TYPE_USE) 189 public @interface TB {} 190 191 @Retention(RetentionPolicy.RUNTIME) 192 @Target(ElementType.TYPE_USE) 193 public @interface TC {} 194 195 public static class Methods1 { 196 public static void m1() throws Error, RuntimeException {;} 197 public static long m2(int a, double b) throws Error, RuntimeException { return 0L; } 198 public static Object m3(String s, List l) throws Error, RuntimeException { return null; } 199 public static Object m4(String s, List<String> l) { return null; } 200 public static Object m4(String s, List<String> l, boolean ... b){ return null; } 201 202 public static void m10() throws @TA Error, @TB @TC RuntimeException {;} 203 public static @TB long m20(@TC int a, @TA double b) throws @TA Error, @TB @TC RuntimeException { return 0L; } 204 public static @TC Object m30(@TA String s, @TB List l) throws @TA Error, @TB @TC RuntimeException { return null; } 205 public static @TA Object m40(@TB String s, @TC List<@TA String> l) { return null; } 206 public static @TA Object m40(@TB String s, @TC List<@TA String> l, @TB boolean ... b) { return null; } 207 208 public Methods1(int a, double b) {} 209 public Methods1(String s, List<String> l, boolean ... b) {} 210 public Methods1(@TC long a, @TA float b) {} 211 public Methods1(@TA int i, @TB String s, @TC List<@TA String> l, @TB boolean ... b) {} 212 } 213 214 // test default ctor 215 public static class Ctors1 { 216 } 217 218 public static class GenericMethods1<E> { 219 public E m1(E e, Object o) throws Error, RuntimeException { return null; } 220 public E m2(List<? extends List> e, int i) throws Error, RuntimeException { return null; } 221 public E m3(double d, List<E> e) throws Error, RuntimeException { return null; } 222 public <E extends List> E m4(byte[] b, GenericMethods1<? extends E> e) { return null; } 223 public <E extends List> E m5(GenericMethods1<? super Number> e) { return null; } 224 public <E extends List & Cloneable> E m6(char c, E e) { return null; } 225 public <E extends List & Cloneable> E m7(char c, E e, byte ... b) { return null; } 226 227 public static <M> M n1(M e) { return null; } 228 public static <M> M n2(List<? extends List> e) { return null; } 229 public static <M extends RuntimeException> M n3(List<M> e) throws Error, M { return null; } 230 public static <M extends Number> M n4(GenericMethods1<? extends M> e) throws Error, RuntimeException { return null; } 231 public static <M extends Object> M n5(GenericMethods1<? super Number> e) { return null; } 232 public static <M extends List & Cloneable> M n6(M e) { return null; } 233 234 public <M> E o1(E e) { return null; } 235 public <M> E o2(List<? extends List> e) { return null; } 236 public <M extends Error, N extends RuntimeException> E o3(GenericMethods1<E> this, List<E> e) throws M, N { return null; } 237 public <M extends Number> E o4(GenericMethods1<? extends E> e) throws Error, RuntimeException { return null; } 238 public <M extends Object> E o5(GenericMethods1<? super Number> e) { return null; } 239 public <M extends List & Cloneable> E o6(E e) { return null; } 240 241 242 // with annotations 243 public @TA E m10(E e, @TC Object o) throws @TA Error, @TB @TC RuntimeException { return null; } 244 public @TB E m20(@TA List<@TA ? extends @TA List> e, @TC int i) throws @TA Error, @TB @TC RuntimeException { return null; } 245 public @TB E m30(@TC double d, List<E> e) throws @TA Error, @TB @TC RuntimeException { return null; } 246 public <@TA E extends @TA List> @TA E m40(@TA byte @TB [] b, GenericMethods1<@TA ? extends E> e) { return null; } 247 public <@TB E extends @TB List> E m50(@TA GenericMethods1<? super Number> e) { return null; } 248 public <@TB E extends @TA List & Cloneable> E m60(@TC char c, E e) { return null; } 249 public <@TB E extends @TA List & Cloneable> E m70(@TC char c, E e, @TA @TB byte ... b) { return null; } 250 251 public static <@TA M> @TA M n10(M e) { return null; } 252 public static <@TA @TB @TC M> M n20(List<@TA ? extends List> e) { return null; } 253 @TA @TB @TC public static <M extends RuntimeException> M n30(List<@TB M> e) throws @TA Error, @TB @TC M { return null; } 254 public static <@TC M extends Number> M n40(GenericMethods1<? extends @TA M> e) throws @TA Error, @TB @TC RuntimeException { return null; } 255 @TA public static <M extends @TB Object> M n50(GenericMethods1<? super Number> e) { return null; } 256 public static <@TA M extends @TB List & @TC @TB Cloneable> M n60(M e) { return null; } 257 258 public <@TC M> E o10(@TA E e) { return null; } 259 public <M> @TA E o20(@TB List<@TB ? extends @TB List> e) { return null; } 260 @TC public <M extends Error, N extends RuntimeException> @TB E o30(@TA @TB @TC GenericMethods1<E> this, List<E> e) throws @TA M, @TB @TC N { return null; } 261 public <@TA M extends Number> E o40(GenericMethods1<? extends @TA E> e) throws @TA Error, @TB @TC RuntimeException { return null; } 262 public <M extends @TA Object> E o50(GenericMethods1<@TA ? super Number> e) { return null; } 263 public <@TA M extends @TB List & @TC Cloneable> E o60(@TA E e) { return null; } 264 265 266 // ctors 267 public GenericMethods1(List<? extends List> e, int i) throws Error, RuntimeException { } 268 public <E extends List & Cloneable> GenericMethods1(char c, E e, byte ... b) { } 269 @TC public <M extends Error, N extends RuntimeException> GenericMethods1(List<@TC E> e) throws @TA M, @TB @TC N { } 270 public <@TA M extends @TB List & @TC Cloneable> GenericMethods1(@TA E e, @TB M m) throws @TA Exception { } 271 public <@TA M extends @TB List & @TC Cloneable> GenericMethods1(@TA E e, @TB M m, @TC byte ... b) throws Exception { } 272 } 273 274 // test default ctor 275 public static class GenericCtors1<T> { 276 } 277 }