21 * questions.
22 */
23
24
25 /*
26 * @test
27 * @summary test reflection on inline types
28 * @compile -XDallowWithFieldOperator Point.java Line.java NonFlattenValue.java
29 * @run main/othervm -XX:+EnableValhalla Reflection
30 */
31
32 import java.lang.reflect.*;
33 import java.util.Arrays;
34 import java.util.stream.Collectors;
35
36 public class Reflection {
37 public static void main(String... args) throws Exception {
38 testPointClass();
39 testLineClass();
40 testNonFlattenValue();
41 }
42
43 static void testPointClass() throws Exception {
44 Point o = Point.makePoint(10, 20);
45 Reflection test = new Reflection(Point.class, "Point", o);
46 test.newInstance();
47 test.constructor();
48 test.accessFieldX(o.x);
49 test.setAccessible();
50 test.trySetAccessible();
51 test.staticField();
52 }
53
54 static void testLineClass() throws Exception {
55 Line l = Line.makeLine(10, 20, 30, 40);
56 Reflection test = new Reflection(Line.class, "Line", l);
57 test.checkField("p1", Point.class.asValueType());
58 test.checkField("p2", Point.class.asValueType());
59 test.checkMethod("p1", Point.class.asValueType());
60 test.checkMethod("p2", Point.class.asValueType());
61 }
62
63 static void testNonFlattenValue() throws Exception {
64 NonFlattenValue nfv = NonFlattenValue.make(10, 20);
65 Reflection test = new Reflection(NonFlattenValue.class, "NonFlattenValue", nfv);
66 test.checkField("nfp", Point.class.asBoxType());
67 test.checkMethod("point", Point.class.asBoxType());
68 test.checkMethod("pointValue", Point.class.asValueType());
69 test.checkMethod("has", void.class, Point.class.asValueType(), Point.class.asBoxType());
70 }
71
72 private final Class<?> c;
73 private final Constructor<?> ctor;
74 private final Object o;
75 Reflection(Class<?> type, String cn, Object o) throws Exception {
76 this.c = Class.forName(cn);
77 if (!c.isValue() || c != type) {
78 throw new RuntimeException(cn + " is not an inline class");
79 }
80
81 // the box type is the primary mirror
82 assertEquals(type, o.getClass());
83 assertEquals(type, c.asBoxType());
84
85 this.ctor = c.getDeclaredConstructor();
86 this.o = o;
87
88 // TODO: what should Object::getClass return?
89 // assertEquals(o.getClass(), c.asValueType());
90
91 // test the box type and value type
92 testBoxAndValueType(this.c);
93 // test array of Q-type
94 // TODO: array of L-type support
95 testArrayOfQType();
96 }
97
98 private static void testBoxAndValueType(Class<?> c) {
99 Class<?> box = c.asBoxType();
100 Class<?> val = c.asValueType();
101 assertTrue(val != null);
102 assertEquals(box.getTypeName(), c.getTypeName());
103 assertEquals(val.getTypeName(), c.getTypeName() + "/val");
104 assertEquals(box, c);
105 assertEquals(val.asBoxType(), box);
106 assertEquals(box.asValueType(), val);
107 }
108
109 void testArrayOfQType() {
110 Class<?> elementType = c.asValueType();
111 Object array = Array.newInstance(elementType, 1);
112 Class<?> arrayType = array.getClass();
113 assertTrue(arrayType.isArray());
114 Class<?> componentType = arrayType.getComponentType();
115 assertTrue(componentType.isValue());
116 assertEquals(componentType, elementType);
117 // Array is a reference type
118 assertEquals(arrayType.asBoxType(), arrayType);
119 }
120
121 void accessFieldX(int x) throws Exception {
122 Field field = c.getField("x");
123 if (field.getInt(o) != x) {
124 throw new RuntimeException("Unexpected Point.x value: " + field.getInt(o));
125 }
126
127 try {
128 field.setInt(o, 100);
129 throw new RuntimeException("IllegalAccessException not thrown");
130 } catch (IllegalAccessException e) {}
131 }
132
133 void newInstance() throws Exception {
134 try {
135 Object o = c.newInstance();
136 throw new RuntimeException("newInstance expected to be unsupported on inline class");
137 } catch (IllegalAccessException e) {}
138 }
160 if (ctor.trySetAccessible()) {
161 throw new RuntimeException("trySetAccessible should not succeed");
162 }
163 Field field = c.getField("x");
164 if (field.trySetAccessible()) {
165 throw new RuntimeException("trySetAccessible should not succeed");
166 }
167 }
168
169 void staticField() throws Exception {
170 Field f = c.getDeclaredField("STATIC_FIELD");
171 if (f.trySetAccessible()) {
172 throw new RuntimeException("trySetAccessible should not succeed");
173 }
174 try {
175 f.setAccessible(true);
176 throw new RuntimeException("IllegalAccessException not thrown");
177 } catch (InaccessibleObjectException e) { }
178 }
179
180 void checkField(String name, Class<?> type) throws Exception {
181 Field f = c.getDeclaredField(name);
182 System.out.format("Field %s::%s of type %s = %s%n",
183 f.getDeclaringClass().getTypeName(), f.getName(),
184 f.getType().getTypeName(), f.get(o));
185 assertEquals(f.getType(), type);
186 }
187
188 void checkMethod(String name, Class<?> returnType, Class<?>... params) throws Exception {
189 Method m = c.getDeclaredMethod(name, params);
190
191 String paramDesc = (params == null || params.length == 0) ? "" :
192 Arrays.stream(params).map(Class::getTypeName).collect(Collectors.joining(", "));
193 System.out.format("Method %s::%s(%s)%s%n",
194 m.getDeclaringClass().getTypeName(), m.getName(),
195 paramDesc, returnType.getTypeName());
196 }
197
198 static void assertEquals(Object o1, Object o2) {
199 if (o1 == o2 || o1.equals(o2))
200 return;
201
202 throw new AssertionError(o1 + " != " + o2);
203 }
204
205 static void assertTrue(boolean value) {
206 if (!value)
207 throw new AssertionError("expected true");
208
209 }
210 }
|
21 * questions.
22 */
23
24
25 /*
26 * @test
27 * @summary test reflection on inline types
28 * @compile -XDallowWithFieldOperator Point.java Line.java NonFlattenValue.java
29 * @run main/othervm -XX:+EnableValhalla Reflection
30 */
31
32 import java.lang.reflect.*;
33 import java.util.Arrays;
34 import java.util.stream.Collectors;
35
36 public class Reflection {
37 public static void main(String... args) throws Exception {
38 testPointClass();
39 testLineClass();
40 testNonFlattenValue();
41 testMirrors();
42 testClassName();
43 }
44
45 static void testPointClass() throws Exception {
46 Point o = Point.makePoint(10, 20);
47 Reflection test = new Reflection(Point.class, "Point", o);
48 test.newInstance();
49 test.constructor();
50 test.accessFieldX(o.x);
51 test.setAccessible();
52 test.trySetAccessible();
53 test.staticField();
54 }
55
56 static void testLineClass() throws Exception {
57 Line l = Line.makeLine(10, 20, 30, 40);
58 Reflection test = new Reflection(Line.class, "Line", l);
59 test.checkField("public final Point Line.p1", "p1", Point.class);
60 test.checkField("public final Point Line.p2", "p2", Point.class);
61 test.checkMethod("public Point Line.p1()", "p1", Point.class);
62 test.checkMethod("public Point Line.p2()", "p2", Point.class);
63 }
64
65 static void testNonFlattenValue() throws Exception {
66 NonFlattenValue nfv = NonFlattenValue.make(10, 20);
67 Reflection test = new Reflection(NonFlattenValue.class, "NonFlattenValue", nfv);
68 test.checkField("final Point? NonFlattenValue.nfp", "nfp", Point.class.asNullableType());
69 test.checkMethod("public Point NonFlattenValue.pointValue()", "pointValue", Point.class);
70 test.checkMethod("public Point? NonFlattenValue.point()", "point", Point.class.asNullableType());
71 test.checkMethod("public boolean NonFlattenValue.has(Point,Point?)", "has", boolean.class, Point.class, Point.class.asNullableType());
72 }
73
74 /*
75 * Tests reflection APIs with the primary and nullable mirror
76 */
77 static void testMirrors() throws Exception {
78 Class<?> primary = Point.class;
79 Class<?> nullable = Point.class.asNullableType();
80
81 assertEquals(primary, Point.class);
82 assertTrue(primary.isInlineClass());
83 assertTrue(nullable.isInlineClass());
84
85 Point o = Point.makePoint(10, 20);
86 assertTrue(primary.isInstance(o));
87 assertTrue(nullable.isInstance(o));
88
89 // V <: V? and V <: Object
90 assertTrue(nullable.isAssignableFrom(primary));
91 assertTrue(Object.class.isAssignableFrom(primary));
92 assertFalse(primary.isAssignableFrom(nullable));
93 assertTrue(Object.class.isAssignableFrom(nullable));
94
95 assertEquals(primary, primary.asSubclass(nullable));
96 try {
97 Class<?> c = nullable.asSubclass(primary);
98 assertTrue(false);
99 } catch (ClassCastException e) { }
100 }
101
102 static void testClassName() {
103 assertEquals(Point.class.getName(), "Point");
104 assertEquals(Point.class.asNullableType().getName(), "Point");
105 assertEquals(Line.class.getName(), "Line");
106 assertEquals((new Point[0]).getClass().getName(), "[QPoint;");
107 assertEquals((new Point?[0][0]).getClass().getName(), "[[LPoint;");
108 }
109
110 private final Class<?> c;
111 private final Constructor<?> ctor;
112 private final Object o;
113 Reflection(Class<?> type, String cn, Object o) throws Exception {
114 this.c = Class.forName(cn);
115 if (!c.isInlineClass() || c != type) {
116 throw new RuntimeException(cn + " is not an inline class");
117 }
118
119 // V.class, Class.forName, and the type of the object return the primary mirror
120 assertEquals(type, o.getClass());
121 assertEquals(type, c.asPrimaryType());
122 assertEquals(c, c.asPrimaryType());
123
124 this.ctor = c.getDeclaredConstructor();
125 this.o = o;
126
127
128 // test the primary mirror and secondary mirror
129 testMirrors(this.c);
130 // test array of Q-type and L-type
131 testArray(c.asPrimaryType());
132 testArray(c.asNullableType());
133 }
134
135 private static void testMirrors(Class<?> c) {
136 Class<?> inlineType = c.asPrimaryType();
137 Class<?> nullableType = c.asNullableType();
138
139 assertTrue(inlineType != null);
140 assertEquals(nullableType.getTypeName(), c.getTypeName() + "?");
141
142 assertEquals(nullableType.getName(), inlineType.getName());
143 assertEquals(nullableType.getTypeName(), inlineType.getTypeName() + "?");
144 assertEquals(inlineType.asNullableType(), nullableType);
145 assertEquals(nullableType.asPrimaryType(), inlineType);
146 }
147
148 void testArray(Class<?> elementType) {
149 Object[] array = (Object[])Array.newInstance(elementType, 1);
150 Class<?> arrayType = array.getClass();
151 assertTrue(arrayType.isArray());
152 Class<?> componentType = arrayType.getComponentType();
153 assertTrue(componentType.isInlineClass());
154 assertEquals(componentType, elementType);
155 // Array is a reference type
156 assertEquals(arrayType.asNullableType(), arrayType);
157 if (array[0] == null) {
158 System.out.println("array[0] = null");
159 } else {
160 System.out.println("array[0] = " + array[0]);
161 }
162 }
163
164 void accessFieldX(int x) throws Exception {
165 Field field = c.getField("x");
166 if (field.getInt(o) != x) {
167 throw new RuntimeException("Unexpected Point.x value: " + field.getInt(o));
168 }
169
170 try {
171 field.setInt(o, 100);
172 throw new RuntimeException("IllegalAccessException not thrown");
173 } catch (IllegalAccessException e) {}
174 }
175
176 void newInstance() throws Exception {
177 try {
178 Object o = c.newInstance();
179 throw new RuntimeException("newInstance expected to be unsupported on inline class");
180 } catch (IllegalAccessException e) {}
181 }
203 if (ctor.trySetAccessible()) {
204 throw new RuntimeException("trySetAccessible should not succeed");
205 }
206 Field field = c.getField("x");
207 if (field.trySetAccessible()) {
208 throw new RuntimeException("trySetAccessible should not succeed");
209 }
210 }
211
212 void staticField() throws Exception {
213 Field f = c.getDeclaredField("STATIC_FIELD");
214 if (f.trySetAccessible()) {
215 throw new RuntimeException("trySetAccessible should not succeed");
216 }
217 try {
218 f.setAccessible(true);
219 throw new RuntimeException("IllegalAccessException not thrown");
220 } catch (InaccessibleObjectException e) { }
221 }
222
223 void checkField(String source, String name, Class<?> type) throws Exception {
224 Field f = c.getDeclaredField(name);
225 assertEquals(f.getType(), type);
226 assertEquals(f.toString(), source);
227 }
228
229 void checkMethod(String source, String name, Class<?> returnType, Class<?>... params) throws Exception {
230 Method m = c.getDeclaredMethod(name, params);
231 assertEquals(m.toString(), source);
232 }
233
234 static void assertEquals(Object o1, Object o2) {
235 if (o1 == o2 || o1.equals(o2))
236 return;
237
238 throw new AssertionError(o1 + " != " + o2);
239 }
240
241 static void assertTrue(boolean value) {
242 if (!value)
243 throw new AssertionError("expected true");
244 }
245
246 static void assertFalse(boolean value) {
247 if (value)
248 throw new AssertionError("expected false");
249 }
250 }
|