< prev index next >

test/jdk/valhalla/valuetypes/Reflection.java

Print this page
rev 55127 : 8223351: [lworld] Primary mirror and nullable mirror for inline type
Reviewed-by: tbd

@@ -36,10 +36,12 @@
 public class Reflection {
     public static void main(String... args) throws Exception {
         testPointClass();
         testLineClass();
         testNonFlattenValue();
+        testMirrors();
+        testClassName();
     }
 
     static void testPointClass() throws Exception  {
         Point o = Point.makePoint(10, 20);
         Reflection test = new Reflection(Point.class, "Point", o);

@@ -52,72 +54,113 @@
     }
 
     static void testLineClass() throws Exception {
         Line l = Line.makeLine(10, 20, 30, 40);
         Reflection test = new Reflection(Line.class, "Line", l);
-        test.checkField("p1", Point.class.asValueType());
-        test.checkField("p2", Point.class.asValueType());
-        test.checkMethod("p1", Point.class.asValueType());
-        test.checkMethod("p2", Point.class.asValueType());
+        test.checkField("public final Point Line.p1", "p1", Point.class);
+        test.checkField("public final Point Line.p2", "p2", Point.class);
+        test.checkMethod("public Point Line.p1()",           "p1", Point.class);
+        test.checkMethod("public Point Line.p2()",           "p2", Point.class);
     }
 
     static void testNonFlattenValue() throws Exception {
         NonFlattenValue nfv = NonFlattenValue.make(10, 20);
         Reflection test = new Reflection(NonFlattenValue.class, "NonFlattenValue", nfv);
-        test.checkField("nfp", Point.class.asBoxType());
-        test.checkMethod("point", Point.class.asBoxType());
-        test.checkMethod("pointValue", Point.class.asValueType());
-        test.checkMethod("has", void.class, Point.class.asValueType(), Point.class.asBoxType());
+        test.checkField("final Point? NonFlattenValue.nfp", "nfp", Point.class.asNullableType());
+        test.checkMethod("public Point NonFlattenValue.pointValue()", "pointValue", Point.class);
+        test.checkMethod("public Point? NonFlattenValue.point()", "point", Point.class.asNullableType());
+        test.checkMethod("public boolean NonFlattenValue.has(Point,Point?)", "has", boolean.class, Point.class, Point.class.asNullableType());
+    }
+
+    /*
+     * Tests reflection APIs with the primary and nullable mirror
+     */
+    static void testMirrors() throws Exception {
+        Class<?> primary = Point.class;
+        Class<?> nullable = Point.class.asNullableType();
+
+        assertEquals(primary, Point.class);
+        assertTrue(primary.isInlineClass());
+        assertTrue(nullable.isInlineClass());
+
+        Point o = Point.makePoint(10, 20);
+        assertTrue(primary.isInstance(o));
+        assertTrue(nullable.isInstance(o));
+
+        // V <: V? and V <: Object
+        assertTrue(nullable.isAssignableFrom(primary));
+        assertTrue(Object.class.isAssignableFrom(primary));
+        assertFalse(primary.isAssignableFrom(nullable));
+        assertTrue(Object.class.isAssignableFrom(nullable));
+
+        assertEquals(primary, primary.asSubclass(nullable));
+        try {
+            Class<?> c = nullable.asSubclass(primary);
+            assertTrue(false);
+        } catch (ClassCastException e) { }
+    }
+
+    static void testClassName() {
+        assertEquals(Point.class.getName(), "Point");
+        assertEquals(Point.class.asNullableType().getName(), "Point");
+        assertEquals(Line.class.getName(), "Line");
+        assertEquals((new Point[0]).getClass().getName(), "[QPoint;");
+        assertEquals((new Point?[0][0]).getClass().getName(), "[[LPoint;");
     }
 
     private final Class<?> c;
     private final Constructor<?> ctor;
     private final Object o;
     Reflection(Class<?> type, String cn, Object o) throws Exception {
         this.c = Class.forName(cn);
-        if (!c.isValue() || c != type) {
+        if (!c.isInlineClass() || c != type) {
             throw new RuntimeException(cn + " is not an inline class");
         }
 
-        // the box type is the primary mirror
+        // V.class, Class.forName, and the type of the object return the primary mirror
         assertEquals(type, o.getClass());
-        assertEquals(type, c.asBoxType());
+        assertEquals(type, c.asPrimaryType());
+        assertEquals(c, c.asPrimaryType());
 
         this.ctor = c.getDeclaredConstructor();
         this.o = o;
 
-        // TODO: what should Object::getClass return?
-        // assertEquals(o.getClass(), c.asValueType());
 
-        // test the box type and value type
-        testBoxAndValueType(this.c);
-        // test array of Q-type
-        // TODO: array of L-type support
-        testArrayOfQType();
-    }
-
-    private static void testBoxAndValueType(Class<?> c) {
-        Class<?> box = c.asBoxType();
-        Class<?> val = c.asValueType();
-        assertTrue(val != null);
-        assertEquals(box.getTypeName(), c.getTypeName());
-        assertEquals(val.getTypeName(), c.getTypeName() + "/val");
-        assertEquals(box, c);
-        assertEquals(val.asBoxType(), box);
-        assertEquals(box.asValueType(), val);
-    }
-
-    void testArrayOfQType() {
-        Class<?> elementType = c.asValueType();
-        Object array = Array.newInstance(elementType, 1);
+        // test the primary mirror and secondary mirror
+        testMirrors(this.c);
+        // test array of Q-type and L-type
+        testArray(c.asPrimaryType());
+        testArray(c.asNullableType());
+    }
+
+    private static void testMirrors(Class<?> c) {
+        Class<?> inlineType = c.asPrimaryType();
+        Class<?> nullableType = c.asNullableType();
+
+        assertTrue(inlineType != null);
+        assertEquals(nullableType.getTypeName(), c.getTypeName() + "?");
+
+        assertEquals(nullableType.getName(), inlineType.getName());
+        assertEquals(nullableType.getTypeName(), inlineType.getTypeName() + "?");
+        assertEquals(inlineType.asNullableType(), nullableType);
+        assertEquals(nullableType.asPrimaryType(), inlineType);
+    }
+
+    void testArray(Class<?> elementType) {
+        Object[] array = (Object[])Array.newInstance(elementType, 1);
         Class<?> arrayType = array.getClass();
         assertTrue(arrayType.isArray());
         Class<?> componentType = arrayType.getComponentType();
-        assertTrue(componentType.isValue());
+        assertTrue(componentType.isInlineClass());
         assertEquals(componentType, elementType);
         // Array is a reference type
-        assertEquals(arrayType.asBoxType(), arrayType);
+        assertEquals(arrayType.asNullableType(), arrayType);
+        if (array[0] == null) {
+            System.out.println("array[0] = null");
+        } else {
+            System.out.println("array[0] = " + array[0]);
+        }
     }
 
     void accessFieldX(int x) throws Exception {
         Field field = c.getField("x");
         if (field.getInt(o) != x) {

@@ -175,26 +218,19 @@
             f.setAccessible(true);
             throw new RuntimeException("IllegalAccessException not thrown");
         } catch (InaccessibleObjectException e) { }
     }
 
-    void checkField(String name, Class<?> type) throws Exception {
+    void checkField(String source, String name, Class<?> type) throws Exception {
         Field f = c.getDeclaredField(name);
-        System.out.format("Field %s::%s of type %s = %s%n",
-                          f.getDeclaringClass().getTypeName(), f.getName(),
-                          f.getType().getTypeName(), f.get(o));
         assertEquals(f.getType(), type);
+        assertEquals(f.toString(), source);
     }
 
-    void checkMethod(String name, Class<?> returnType, Class<?>... params) throws Exception {
+    void checkMethod(String source, String name, Class<?> returnType, Class<?>... params) throws Exception {
         Method m = c.getDeclaredMethod(name, params);
-
-        String paramDesc = (params == null || params.length == 0) ? "" :
-            Arrays.stream(params).map(Class::getTypeName).collect(Collectors.joining(", "));
-        System.out.format("Method %s::%s(%s)%s%n",
-                          m.getDeclaringClass().getTypeName(), m.getName(),
-                          paramDesc, returnType.getTypeName());
+        assertEquals(m.toString(), source);
     }
 
     static void assertEquals(Object o1, Object o2) {
         if (o1 == o2 || o1.equals(o2))
             return;

@@ -203,8 +239,12 @@
     }
 
     static void assertTrue(boolean value) {
         if (!value)
             throw new AssertionError("expected true");
+    }
 
+    static void assertFalse(boolean value) {
+        if (value)
+            throw new AssertionError("expected false");
     }
 }
< prev index next >