1 /* 2 * Copyright (c) 2015, 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* @test 27 * @bug 8139885 28 * @run testng/othervm -ea -esa test.java.lang.invoke.FoldTest 29 */ 30 31 package test.java.lang.invoke; 32 33 import java.io.StringWriter; 34 import java.lang.invoke.MethodHandle; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.invoke.MethodHandles.Lookup; 37 import java.lang.invoke.MethodType; 38 39 import static java.lang.invoke.MethodType.methodType; 40 41 import static org.testng.AssertJUnit.*; 42 43 import org.testng.annotations.*; 44 45 /** 46 * Tests for the new fold method handle combinator added in JEP 274. 47 */ 48 public class FoldTest { 49 50 static final Lookup LOOKUP = MethodHandles.lookup(); 51 52 @Test testFold0a()53 public static void testFold0a() throws Throwable { 54 // equivalence to foldArguments(MethodHandle,MethodHandle) 55 MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 0, Fold.MH_adder); 56 assertEquals(Fold.MT_folded1, fold.type()); 57 assertEquals(720, (int) fold.invoke(3, 4, 5)); 58 } 59 60 @Test testFold1a()61 public static void testFold1a() throws Throwable { 62 // test foldArguments for folding position 1 63 MethodHandle fold = MethodHandles.foldArguments(Fold.MH_multer, 1, Fold.MH_adder1); 64 assertEquals(Fold.MT_folded1, fold.type()); 65 assertEquals(540, (int) fold.invoke(3, 4, 5)); 66 } 67 68 @Test testFold0b()69 public static void testFold0b() throws Throwable { 70 // test foldArguments equivalence with multiple types 71 MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 0, Fold.MH_comb); 72 assertEquals(Fold.MT_folded2, fold.type()); 73 assertEquals(23, (int) fold.invoke("true", true, 23)); 74 } 75 76 @Test testFold1b()77 public static void testFold1b() throws Throwable { 78 // test folgArguments for folding position 1, with multiple types 79 MethodHandle fold = MethodHandles.foldArguments(Fold.MH_str, 1, Fold.MH_comb2); 80 assertEquals(Fold.MT_folded3, fold.type()); 81 assertEquals(1, (int) fold.invoke(true, true, 1)); 82 assertEquals(-1, (int) fold.invoke(true, false, -1)); 83 } 84 85 @Test testFoldArgumentsExample()86 public static void testFoldArgumentsExample() throws Throwable { 87 // test the JavaDoc foldArguments-with-pos example 88 StringWriter swr = new StringWriter(); 89 MethodHandle trace = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, String.class)).bindTo(swr); 90 MethodHandle cat = LOOKUP.findVirtual(String.class, "concat", methodType(String.class, String.class)); 91 assertEquals("boojum", (String) cat.invokeExact("boo", "jum")); 92 MethodHandle catTrace = MethodHandles.foldArguments(cat, 1, trace); 93 assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); 94 assertEquals("jum", swr.toString()); 95 } 96 97 static class Fold { 98 adder(int a, int b, int c)99 static int adder(int a, int b, int c) { 100 return a + b + c; 101 } 102 adder1(int a, int b)103 static int adder1(int a, int b) { 104 return a + b; 105 } 106 multer(int x, int q, int r, int s)107 static int multer(int x, int q, int r, int s) { 108 return x * q * r * s; 109 } 110 str(boolean b1, String s, boolean b2, int x)111 static int str(boolean b1, String s, boolean b2, int x) { 112 return b1 && s.equals(String.valueOf(b2)) ? x : -x; 113 } 114 comb(String s, boolean b2)115 static boolean comb(String s, boolean b2) { 116 return !s.equals(b2); 117 } 118 comb2(boolean b2, int x)119 static String comb2(boolean b2, int x) { 120 int ib = b2 ? 1 : 0; 121 return ib == x ? "true" : "false"; 122 } 123 124 static final Class<Fold> FOLD = Fold.class; 125 126 static final MethodType MT_adder = methodType(int.class, int.class, int.class, int.class); 127 static final MethodType MT_adder1 = methodType(int.class, int.class, int.class); 128 static final MethodType MT_multer = methodType(int.class, int.class, int.class, int.class, int.class); 129 static final MethodType MT_str = methodType(int.class, boolean.class, String.class, boolean.class, int.class); 130 static final MethodType MT_comb = methodType(boolean.class, String.class, boolean.class); 131 static final MethodType MT_comb2 = methodType(String.class, boolean.class, int.class); 132 133 static final MethodHandle MH_adder; 134 static final MethodHandle MH_adder1; 135 static final MethodHandle MH_multer; 136 static final MethodHandle MH_str; 137 static final MethodHandle MH_comb; 138 static final MethodHandle MH_comb2; 139 140 static final MethodType MT_folded1 = methodType(int.class, int.class, int.class, int.class); 141 static final MethodType MT_folded2 = methodType(int.class, String.class, boolean.class, int.class); 142 static final MethodType MT_folded3 = methodType(int.class, boolean.class, boolean.class, int.class); 143 144 static { 145 try { 146 MH_adder = LOOKUP.findStatic(FOLD, "adder", MT_adder); 147 MH_adder1 = LOOKUP.findStatic(FOLD, "adder1", MT_adder1); 148 MH_multer = LOOKUP.findStatic(FOLD, "multer", MT_multer); 149 MH_str = LOOKUP.findStatic(FOLD, "str", MT_str); 150 MH_comb = LOOKUP.findStatic(FOLD, "comb", MT_comb); 151 MH_comb2 = LOOKUP.findStatic(FOLD, "comb2", MT_comb2); 152 } catch (Exception e) { 153 throw new ExceptionInInitializerError(e); 154 } 155 } 156 } 157 158 } 159