< 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


  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 }
< prev index next >