1 /*
   2  * Copyright (c) 2018, 2019, 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  * @summary Basic test for Array::get, Array::set, Arrays::setAll on inline class array
  27  * @compile -XDallowWithFieldOperator Point.java NonFlattenValue.java
  28  * @compile -XDallowWithFieldOperator ValueArray.java
  29  * @run testng/othervm -XX:+EnableValhalla -XX:ValueArrayElemMaxFlatSize=-1 ValueArray
  30  * @run testng/othervm -XX:+EnableValhalla -XX:ValueArrayElemMaxFlatSize=0  ValueArray
  31  */
  32 
  33 import java.lang.reflect.*;
  34 import java.util.Arrays;
  35 
  36 import org.testng.annotations.BeforeTest;
  37 import org.testng.annotations.DataProvider;
  38 import org.testng.annotations.Test;
  39 import static org.testng.Assert.*;
  40 
  41 public class ValueArray {
  42     @DataProvider(name="arrayTypes")
  43     static Object[][] arrayTypes() {
  44         return new Object[][] {
  45             new Object[] { Object[].class,
  46                            new Object[] { new Object(), new Object()}},
  47             new Object[] { Point[].class,
  48                            new Point[] { Point.makePoint(1, 2),
  49                                          Point.makePoint(10, 20),
  50                                          Point.makePoint(100, 200)}},
  51             new Object[] { Point[][].class,
  52                            new Point[][] { new Point[] { Point.makePoint(1, 2),
  53                                                          Point.makePoint(10, 20)}}},
  54 
  55             new Object[] { NonFlattenValue[].class,
  56                            new NonFlattenValue[] { NonFlattenValue.make(1, 2),
  57                                                    NonFlattenValue.make(10, 20),
  58                                                    NonFlattenValue.make(100, 200)}},
  59         };
  60     }
  61 
  62     @Test(dataProvider="arrayTypes")
  63     public static void test(Class<?> c, Object[] elements) {
  64         ValueArray test = new ValueArray(c, elements.length);
  65         test.run(elements);
  66         if (c.getComponentType().isValue()) {
  67             test.ensureNonNullable();
  68         }
  69      }
  70 
  71     @Test
  72     public static void testPointArray() {
  73         PointArray array = PointArray.makeArray(Point.makePoint(1, 2), Point.makePoint(10, 20));
  74         ValueArray test = new ValueArray(array.points);
  75         test.run(Point.makePoint(3, 4), Point.makePoint(30, 40));
  76     }
  77 
  78     @Test
  79     public static void testIntArray() {
  80         int[] array = new int[] { 1, 2, 3};
  81         for (int i=0; i < array.length; i++) {
  82             Array.set(array, i, Integer.valueOf(i*10));
  83         }
  84 
  85         for (int i=0; i < array.length; i++) {
  86             Integer o = (Integer) Array.get(array, i);
  87             assertTrue(o.intValue() == i*10);
  88         }
  89         Arrays.setAll(array, i -> array[i]);
  90     }
  91 
  92     @Test
  93     public static void testNonArrayObject() {
  94         Object o = new Object();
  95         try {
  96             Array.get(o, 0);
  97             throw new AssertionError("IAE not thrown");
  98         } catch (IllegalArgumentException e) {}
  99 
 100         try {
 101             Array.set(o, 0, o);
 102             throw new AssertionError("IAE not thrown");
 103         } catch (IllegalArgumentException e) {}
 104 
 105     }
 106     private final Object[] array;
 107     ValueArray(Class<?> arrayClass, int len) {
 108         this((Object[])Array.newInstance(arrayClass.getComponentType(), len));
 109         assertTrue(array.getClass() == arrayClass);
 110     }
 111     ValueArray(Object[] array) {
 112         this.array = array;
 113     }
 114 
 115     void run(Object... elements) {
 116         for (int i=0; i < elements.length; i++) {
 117             Array.set(array, i, elements[i]);
 118         }
 119 
 120         for (int i=0; i < elements.length; i++) {
 121             Object o = Array.get(array, i);
 122             assertEquals(o, elements[i]);
 123         }
 124 
 125         Arrays.setAll(array, i -> elements[i]);
 126     }
 127 
 128     void ensureNonNullable() {
 129         assert(array.getClass().getComponentType().isValue());
 130         for (int i=0; i < array.length; i++) {
 131             try {
 132                 Array.set(array, i, null);
 133                 throw new AssertionError("NPE not thrown");
 134             } catch (NullPointerException e) {}
 135         }
 136     }
 137 
 138     static inline class PointArray {
 139         public Point?[] points;
 140         PointArray() {
 141             points = new Point?[0];
 142         }
 143         public static PointArray makeArray(Point... points) {
 144             PointArray a = PointArray.default;
 145             Point?[] boxArray = new Point?[points.length];
 146             for (int i=0; i < points.length; i++) {
 147                 boxArray[i] = points[i];
 148             }
 149             a = __WithField(a.points, boxArray);
 150             return a;
 151         }
 152     }
 153 }