1 /*
   2  * Copyright (c) 2017, 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 import jdk.experimental.value.ValueType;
  24 import org.testng.annotations.Test;
  25 
  26 import java.lang.invoke.MethodHandle;
  27 import java.lang.invoke.MethodHandles;
  28 
  29 import static java.lang.invoke.MethodType.methodType;
  30 import static org.testng.Assert.*;
  31 
  32 /*
  33  * @test
  34  * @run testng/othervm -Xverify:none -XX:+EnableMVT -Dvalhalla.enablePoolPatches=true MethodHandlesTest
  35  */
  36 
  37 @Test
  38 public class MethodHandlesTest {
  39     @jvm.internal.value.DeriveValueType
  40     final class ValueCapable {}
  41 
  42     static final ValueType<?> VT = ValueType.forClass(Point.class);
  43     static final Class<?> VCC = Point.class;
  44     static final Class<?> DVT = VT.valueClass();
  45 
  46     static final MethodHandle ID_DVT_MH = MethodHandles.identity(DVT);            // (DVT)DVT
  47     static final MethodHandle ID_VCC_MH = ID_DVT_MH.asType(methodType(VCC, VCC)); // (VCC)VCC
  48 
  49     static final Object ARG = new Point(0, (short)1, (short)2);
  50 
  51     @Test
  52     void testInsertArgumentDVT() throws Throwable {
  53         {
  54             MethodHandle mh = MethodHandles.insertArguments(ID_DVT_MH, 0, ARG);
  55             assertEquals(mh.invokeWithArguments(), ARG);
  56         }
  57 
  58         assertThrows(ClassCastException.class,
  59                 () -> MethodHandles.insertArguments(ID_DVT_MH, 0, new ValueCapable()));
  60 
  61         assertThrows(NullPointerException.class,
  62                 () -> MethodHandles.insertArguments(ID_DVT_MH, 0, new Object[] { null }));
  63     }
  64 
  65     @Test
  66     void testInsertArgumentVCC() throws Throwable {
  67         assertEquals(MethodHandles.insertArguments(ID_VCC_MH, 0, ARG).invokeWithArguments(), ARG);
  68 
  69         assertThrows(ClassCastException.class,
  70                 () -> MethodHandles.insertArguments(ID_VCC_MH, 0, new ValueCapable()));
  71 
  72         {
  73             MethodHandle mh = MethodHandles.insertArguments(ID_VCC_MH, 0, new Object[]{null});
  74             assertThrows(NullPointerException.class, () -> mh.invokeWithArguments());
  75         }
  76     }
  77 
  78     @Test
  79     void testConstantDVT() throws Throwable {
  80         assertEquals(MethodHandles.constant(DVT, ARG).type(), methodType(DVT));
  81 
  82         assertEquals(MethodHandles.constant(DVT, ARG).invokeWithArguments(), ARG);
  83 
  84         assertThrows(ClassCastException.class,
  85                 () -> MethodHandles.constant(DVT, new Object()));
  86 
  87         assertThrows(NullPointerException.class,
  88                 () -> MethodHandles.constant(DVT, null));
  89     }
  90 
  91     @Test
  92     void testBindToDVT() {
  93         assertThrows(IllegalArgumentException.class,
  94                 () -> ID_DVT_MH.bindTo(ARG));
  95     }
  96 }