1 /* 2 * Copyright (c) 2024, 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 import org.testng.Assert; 25 import org.testng.annotations.DataProvider; 26 import org.testng.annotations.Test; 27 28 import java.lang.constant.ClassDesc; 29 import java.lang.constant.ConstantDescs; 30 import java.lang.invoke.MethodHandles; 31 import java.lang.reflect.Field; 32 import java.lang.reflect.Type; 33 import java.lang.reflect.code.type.ArrayType; 34 import java.lang.reflect.code.type.ClassType; 35 import java.lang.reflect.code.type.JavaType; 36 import java.util.ArrayList; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.stream.Stream; 40 41 42 /* 43 * @test 44 * @run testng TestJavaType 45 */ 46 47 public class TestJavaType { 48 49 @DataProvider 50 public Object[][] JavaTypes() { 51 return new Object[][]{ 52 {"boolean", "Z"}, 53 {"byte", "B"}, 54 {"char", "C"}, 55 {"short", "S"}, 56 {"int", "I"}, 57 {"long", "J"}, 58 {"float", "F"}, 59 {"double", "D"}, 60 {"void", "V"}, 61 {"int[]", "[I"}, 62 {"int[][][][]", "[[[[I"}, 63 {"java.lang.String", "Ljava/lang/String;"}, 64 {"java.lang.String[][]", "[[Ljava/lang/String;"}, 65 {"a.b.C$D", "La/b/C$D;"}, 66 }; 67 } 68 69 @Test(dataProvider = "JavaTypes") 70 public void testJavaType(String tds, String bcd) { 71 JavaType jt = JavaType.ofString(tds); 72 Assert.assertEquals(jt.toString(), tds); 73 Assert.assertEquals(jt.toNominalDescriptor().descriptorString(), bcd); 74 Assert.assertEquals(jt, JavaType.type(ClassDesc.ofDescriptor(bcd))); 75 } 76 77 @DataProvider 78 public Object[][] classDescriptors() { 79 return new Object[][]{ 80 {"java.lang.String", "java.lang.String"}, 81 }; 82 } 83 84 @Test(dataProvider = "classDescriptors") 85 public void classDescriptor(String tds, String bcd) { 86 ClassType jt = (ClassType)JavaType.ofString(tds); 87 Assert.assertEquals(jt.toString(), tds); 88 Assert.assertEquals(jt.toClassName(), bcd); 89 } 90 91 92 @DataProvider 93 public Object[][] basicJavaTypes() { 94 return new Object[][]{ 95 {"boolean", "int"}, 96 {"byte", "int"}, 97 {"char", "int"}, 98 {"short", "int"}, 99 {"int", "int"}, 100 {"long", "long"}, 101 {"float", "float"}, 102 {"double", "double"}, 103 {"void", "void"}, 104 {"int[]", "java.lang.Object"}, 105 {"int[][][][]", "java.lang.Object"}, 106 {"java.lang.String", "java.lang.Object"}, 107 {"java.lang.String[][]", "java.lang.Object"}, 108 {"a.b.C$D", "java.lang.Object"}, 109 {"java.util.List<T>", "java.lang.Object"}, 110 {"java.util.List<T>[]", "java.lang.Object"}, 111 }; 112 } 113 114 @Test(dataProvider = "basicJavaTypes") 115 public void testBasicJavaType(String tds, String btds) { 116 JavaType jt = JavaType.ofString(tds); 117 Assert.assertEquals(jt.toString(), tds); 118 Assert.assertEquals(jt.toBasicType().toString(), btds); 119 } 120 121 122 @DataProvider 123 public Object[][] argumentJavaTypes() { 124 return new Object[][]{ 125 {"java.util.List<T>", "T"}, 126 {"java.util.List<T>[]", "T"}, 127 {"java.util.List<java.util.function.Supplier<T>>", "java.util.function.Supplier<T>"}, 128 {"java.util.List<java.util.function.Supplier<T>>[][]", "java.util.function.Supplier<T>"}, 129 {"java.util.Map<K, V>", "K", "V"}, 130 {"ab<cd<S<T, V>, N>>", "cd<S<T, V>, N>"}, 131 {"java.util.Consumer<java.util.Function<String, Number>>", "java.util.Function<String, Number>"}, 132 }; 133 } 134 135 @Test(dataProvider = "argumentJavaTypes") 136 public void testArgumentJavaType(String tds, String... argTypes) { 137 JavaType jt = JavaType.ofString(tds); 138 Assert.assertEquals(jt.toString(), tds); 139 140 while (jt instanceof ArrayType) { 141 jt = ((ArrayType)jt).componentType(); 142 } 143 ClassType ct = (ClassType)jt; 144 145 Assert.assertEquals(argTypes.length, ct.typeArguments().size()); 146 147 Assert.assertEquals(ct.typeArguments(), Stream.of(argTypes).map(JavaType::ofString).toList()); 148 } 149 150 @Test(dataProvider = "classDescs") 151 public void testClassDescRoundTrip(ClassDesc classDesc) { 152 Assert.assertEquals(classDesc, JavaType.type(classDesc).toNominalDescriptor()); 153 } 154 155 @DataProvider 156 public Object[][] classDescs() throws ReflectiveOperationException { 157 List<Object[]> classDescs = new ArrayList<>(); 158 for (Field f : ConstantDescs.class.getDeclaredFields()) { 159 if (f.getName().startsWith("CD_")) { 160 ClassDesc cd = (ClassDesc)f.get(null); 161 classDescs.add(new Object[] { cd }); 162 if (!cd.equals(ConstantDescs.CD_void)) { 163 classDescs.add(new Object[]{cd.arrayType()}); 164 classDescs.add(new Object[]{cd.arrayType().arrayType()}); 165 } 166 } 167 } 168 return classDescs.stream().toArray(Object[][]::new); 169 } 170 171 @Test(dataProvider = "types") 172 public void testTypeRoundTrip(Type type) throws ReflectiveOperationException { 173 Assert.assertEquals(type, JavaType.type(type).resolve(MethodHandles.lookup())); 174 } 175 176 @DataProvider 177 public Object[][] types() throws ReflectiveOperationException { 178 List<Object[]> types = new ArrayList<>(); 179 for (Field f : TypeHolder.class.getDeclaredFields()) { 180 types.add(new Object[] { f.getGenericType() }); 181 } 182 return types.stream().toArray(Object[][]::new); 183 } 184 185 static class TypeHolder<X extends Number> { 186 boolean p1; 187 char p2; 188 byte p3; 189 short p4; 190 int p5; 191 long p6; 192 float p7; 193 double p8; 194 195 boolean[] ap1; 196 char[] ap2; 197 byte[] ap3; 198 short[] ap4; 199 int[] ap5; 200 long[] ap6; 201 float[] ap7; 202 double[] ap8; 203 204 boolean[][] aap1; 205 char[][] aap2; 206 byte[][] aap3; 207 short[][] aap4; 208 int[][] aap5; 209 long[][] aap6; 210 float[][] aap7; 211 double[][] aap8; 212 213 String r1; 214 Map<String, String> r2; 215 Map<String, ? extends String> r3; 216 Map<? extends String, String> r4; 217 Map<? extends String, ? extends String> r5; 218 Map<? extends List<? extends String>, ? super List<? extends String>> r6; 219 Map<? extends List<? extends String>[], ? super List<? extends String>[]> r7; 220 List<boolean[]> r8; 221 List<char[]> r9; 222 List<byte[]> r10; 223 List<short[]> r11; 224 List<int[]> r12; 225 List<long[]> r13; 226 List<float[]> r14; 227 List<double[]> r15; 228 229 String[] ar1; 230 Map<String, String>[] ar2; 231 Map<String, ? extends String>[] ar3; 232 Map<? extends String, String>[] ar4; 233 Map<? extends String, ? extends String>[] ar5; 234 Map<? extends List<? extends String>, ? super List<? extends String>>[] ar6; 235 Map<? extends List<? extends String>[], ? super List<? extends String>[]>[] ar7; 236 List<boolean[]>[] ar8; 237 List<char[]>[] ar9; 238 List<byte[]>[] ar10; 239 List<short[]>[] ar11; 240 List<int[]>[] ar12; 241 List<long[]>[] ar13; 242 List<float[]>[] ar14; 243 List<double[]>[] ar15; 244 245 String[][] aar1; 246 Map<String, String>[][] aar2; 247 Map<String, ? extends String>[][] aar3; 248 Map<? extends String, String>[][] aar4; 249 Map<? extends String, ? extends String>[][] aar5; 250 Map<? extends List<? extends String>, ? super List<? extends String>>[][] aar6; 251 Map<? extends List<? extends String>[], ? super List<? extends String>[]>[][] aar7; 252 List<boolean[]>[][] aar8; 253 List<char[]>[][] aar9; 254 List<byte[]>[][] aar10; 255 List<short[]>[][] aar11; 256 List<int[]>[][] aar12; 257 List<long[]>[][] aar13; 258 List<float[]>[][] aar14; 259 List<double[]>[][] aar15; 260 261 X x1; 262 Map<X, X> x2; 263 Map<X, ? extends X> x3; 264 Map<? extends X, X> x4; 265 Map<? extends X, ? extends X> x5; 266 Map<? extends List<? extends X>, ? super List<? extends X>> x6; 267 Map<? extends List<? extends X>[], ? super List<? extends X>[]> x7; 268 List<X[]> x8; 269 270 X[] ax1; 271 Map<X, X>[] ax2; 272 Map<X, ? extends X>[] ax3; 273 Map<? extends X, X>[] ax4; 274 Map<? extends X, ? extends X>[] ax5; 275 Map<? extends List<? extends X>, ? super List<? extends X>>[] ax6; 276 Map<? extends List<? extends X>[], ? super List<? extends X>[]>[] ax7; 277 List<X[]>[] ax8; 278 279 X[][] aax1; 280 Map<X, X>[][] aax2; 281 Map<X, ? extends X>[][] aax3; 282 Map<? extends X, X>[][] aax4; 283 Map<? extends X, ? extends X>[][] aax5; 284 Map<? extends List<? extends X>, ? super List<? extends X>>[][] aax6; 285 Map<? extends List<? extends X>[], ? super List<? extends X>[]>[][] aax7; 286 List<X[]>[][] aax8; 287 } 288 }