changeset 13256:4d010a9bd0d9

8143343: add JEP 274 Javadoc tests to JavaDocExamplesTest Reviewed-by: sundar
author mhaupt
date Thu, 03 Dec 2015 15:36:20 +0100
parents d41609429f2e
children 9f7e8e4f8cc9
files src/java.base/share/classes/java/lang/invoke/MethodHandles.java test/java/lang/invoke/JavaDocExamplesTest.java
diffstat 2 files changed, 172 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Dec 03 15:34:39 2015 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Dec 03 15:36:20 2015 +0100
@@ -3463,7 +3463,7 @@
      *   return zip;
      * }
      * // assume MH_initZip, MH_zipPred, and MH_zipStep are handles to the above methods
-     * MethodHandle loop = MethodHandles.doWhileLoop(MH_initZip, MH_zipPred, MH_zipStep);
+     * MethodHandle loop = MethodHandles.doWhileLoop(MH_initZip, MH_zipStep, MH_zipPred);
      * List<String> a = Arrays.asList("a", "b", "c", "d");
      * List<String> b = Arrays.asList("e", "f", "g", "h");
      * List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
@@ -3602,7 +3602,8 @@
      * String start(String arg) { return arg; }
      * String step(int counter, String v, String arg) { return "na " + v; }
      * // assume MH_start and MH_step are handles to the two methods above
-     * MethodHandle loop = MethodHandles.countedLoop(13, MH_start, MH_step);
+     * MethodHandle fit13 = MethodHandles.constant(int.class, 13);
+     * MethodHandle loop = MethodHandles.countedLoop(fit13, MH_start, MH_step);
      * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
      * }</pre></blockquote>
      *
@@ -3742,11 +3743,11 @@
      * @apiNote Example:
      * <blockquote><pre>{@code
      * // reverse a list
-     * List<String> reverseStep(String e, List<String> r) {
+     * List<String> reverseStep(String e, List<String> r, List<String> l) {
      *   r.add(0, e);
      *   return r;
      * }
-     * List<String> newArrayList() { return new ArrayList<>(); }
+     * List<String> newArrayList(List<String> l) { return new ArrayList<>(); }
      * // assume MH_reverseStep, MH_newArrayList are handles to the above methods
      * MethodHandle loop = MethodHandles.iteratedLoop(null, MH_newArrayList, MH_reverseStep);
      * List<String> list = Arrays.asList("a", "b", "c", "d", "e");
--- a/test/java/lang/invoke/JavaDocExamplesTest.java	Thu Dec 03 15:34:39 2015 +0100
+++ b/test/java/lang/invoke/JavaDocExamplesTest.java	Thu Dec 03 15:36:20 2015 +0100
@@ -29,6 +29,7 @@
 
 package test.java.lang.invoke;
 
+import java.io.StringWriter;
 import java.lang.invoke.*;
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
@@ -36,7 +37,6 @@
 import java.util.*;
 
 import org.testng.*;
-import static org.testng.AssertJUnit.*;
 import org.testng.annotations.*;
 
 /**
@@ -322,6 +322,13 @@
         Assert.assertEquals(exp, act);
     }
 
+    static void assertTrue(boolean b) {
+        if (verbosity > 0) {
+            System.out.println("result: " + b);
+        }
+        Assert.assertTrue(b);
+    }
+
     @Test public void testMethodHandlesSummary() throws Throwable {
         {{
 {} /// JAVADOC
@@ -639,6 +646,165 @@
             }}
     }
 
+    static int one(int k) { return 1; }
+    static int inc(int i, int acc, int k) { return i + 1; }
+    static int mult(int i, int acc, int k) { return i * acc; }
+    static boolean pred(int i, int acc, int k) { return i < k; }
+    static int fin(int i, int acc, int k) { return acc; }
+
+    @Test public void testLoop() throws Throwable {
+        MethodHandle MH_inc, MH_one, MH_mult, MH_pred, MH_fin;
+        Class<?> I = int.class;
+        MH_inc = LOOKUP.findStatic(THIS_CLASS, "inc", methodType(I, I, I, I));
+        MH_one = LOOKUP.findStatic(THIS_CLASS, "one", methodType(I, I));
+        MH_mult = LOOKUP.findStatic(THIS_CLASS, "mult", methodType(I, I, I, I));
+        MH_pred = LOOKUP.findStatic(THIS_CLASS, "pred", methodType(boolean.class, I, I, I));
+        MH_fin = LOOKUP.findStatic(THIS_CLASS, "fin", methodType(I, I, I, I));
+        {{
+{} /// JAVADOC
+// iterative implementation of the factorial function as a loop handle
+// null initializer for counter, should initialize to 0
+MethodHandle[] counterClause = new MethodHandle[]{null, MH_inc};
+MethodHandle[] accumulatorClause = new MethodHandle[]{MH_one, MH_mult, MH_pred, MH_fin};
+MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
+assertEquals(120, loop.invoke(5));
+{}
+        }}
+    }
+
+    static List<String> initZip(Iterator<String> a, Iterator<String> b) { return new ArrayList<>(); }
+    static boolean zipPred(List<String> zip, Iterator<String> a, Iterator<String> b) { return a.hasNext() && b.hasNext(); }
+    static List<String> zipStep(List<String> zip, Iterator<String> a, Iterator<String> b) {
+        zip.add(a.next());
+        zip.add(b.next());
+        return zip;
+    }
+
+    @Test public void testWhileLoop() throws Throwable {
+        MethodHandle MH_initZip, MH_zipPred, MH_zipStep;
+        Class<?> IT = Iterator.class;
+        Class<?> L = List.class;
+        MH_initZip = LOOKUP.findStatic(THIS_CLASS, "initZip", methodType(L, IT, IT));
+        MH_zipPred = LOOKUP.findStatic(THIS_CLASS, "zipPred", methodType(boolean.class, L, IT, IT));
+        MH_zipStep = LOOKUP.findStatic(THIS_CLASS, "zipStep", methodType(L, L, IT, IT));
+        {{
+{} /// JAVADOC
+// implement the zip function for lists as a loop handle
+MethodHandle loop = MethodHandles.doWhileLoop(MH_initZip, MH_zipStep, MH_zipPred);
+List<String> a = Arrays.asList("a", "b", "c", "d");
+List<String> b = Arrays.asList("e", "f", "g", "h");
+List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
+assertEquals(zipped, (List<String>) loop.invoke(a.iterator(), b.iterator()));
+{}
+        }}
+    }
+
+    static int zero(int limit) { return 0; }
+    static int step(int i, int limit) { return i + 1; }
+    static boolean pred(int i, int limit) { return i < limit; }
+
+    @Test public void testDoWhileLoop() throws Throwable {
+        MethodHandle MH_zero, MH_step, MH_pred;
+        Class<?> I = int.class;
+        MH_zero = LOOKUP.findStatic(THIS_CLASS, "zero", methodType(I, I));
+        MH_step = LOOKUP.findStatic(THIS_CLASS, "step", methodType(I, I, I));
+        MH_pred = LOOKUP.findStatic(THIS_CLASS, "pred", methodType(boolean.class, I, I));
+        {{
+{} /// JAVADOC
+// int i = 0; while (i < limit) { ++i; } return i; => limit
+MethodHandle loop = MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred);
+assertEquals(23, loop.invoke(23));
+{}
+        }}
+    }
+
+    static String start(String arg) { return arg; }
+    static String step(int counter, String v, String arg) { return "na " + v; }
+
+    @Test public void testCountedLoop() throws Throwable {
+        MethodHandle MH_start, MH_step;
+        Class<?> S = String.class;
+        MH_start = LOOKUP.findStatic(THIS_CLASS, "start", methodType(S, S));
+        MH_step = LOOKUP.findStatic(THIS_CLASS, "step", methodType(S, int.class, S, S));
+        {{
+{} /// JAVADOC
+// String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
+// => a variation on a well known theme
+MethodHandle fit13 = MethodHandles.constant(int.class, 13);
+MethodHandle loop = MethodHandles.countedLoop(fit13, MH_start, MH_step);
+assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
+{}
+        }}
+    }
+
+    static List<String> reverseStep(String e, List<String> r, List<String> l) {
+        r.add(0, e);
+        return r;
+    }
+    static List<String> newArrayList(List<String> l) { return new ArrayList<>(); }
+
+    @Test public void testIteratedLoop() throws Throwable {
+        MethodHandle MH_newArrayList, MH_reverseStep;
+        Class<?> L = List.class;
+        MH_newArrayList = LOOKUP.findStatic(THIS_CLASS, "newArrayList", methodType(L, L));
+        MH_reverseStep = LOOKUP.findStatic(THIS_CLASS, "reverseStep", methodType(L, String.class, L, L));
+        {{
+{} /// JAVADOC
+// reverse a list
+MethodHandle loop = MethodHandles.iteratedLoop(null, MH_newArrayList, MH_reverseStep);
+List<String> list = Arrays.asList("a", "b", "c", "d", "e");
+List<String> reversedList = Arrays.asList("e", "d", "c", "b", "a");
+assertEquals(reversedList, (List<String>) loop.invoke(list));
+{}
+        }}
+    }
+
+    @Test public void testFoldArguments3() throws Throwable {
+        {{
+{} /// JAVADOC
+MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
+        "println", methodType(void.class, String.class))
+        .bindTo(System.out);
+MethodHandle cat = lookup().findVirtual(String.class,
+        "concat", methodType(String.class, String.class));
+assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
+MethodHandle catTrace = foldArguments(cat, 1, trace);
+// also prints "jum":
+assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
+{}
+        }}
+    }
+
+    @Test public void testAsCollector2() throws Throwable {
+        {{
+{} /// JAVADOC
+StringWriter swr = new StringWriter();
+MethodHandle swWrite = LOOKUP.findVirtual(StringWriter.class, "write", methodType(void.class, char[].class, int.class, int.class)).bindTo(swr);
+MethodHandle swWrite4 = swWrite.asCollector(0, char[].class, 4);
+swWrite4.invoke('A', 'B', 'C', 'D', 1, 2);
+assertEquals("BC", swr.toString());
+swWrite4.invoke('P', 'Q', 'R', 'S', 0, 4);
+assertEquals("BCPQRS", swr.toString());
+swWrite4.invoke('W', 'X', 'Y', 'Z', 3, 1);
+assertEquals("BCPQRSZ", swr.toString());
+{}
+        }}
+    }
+
+    @Test public void testAsSpreader2() throws Throwable {
+        {{
+{} /// JAVADOC
+MethodHandle compare = LOOKUP.findStatic(Objects.class, "compare", methodType(int.class, Object.class, Object.class, Comparator.class));
+MethodHandle compare2FromArray = compare.asSpreader(0, Object[].class, 2);
+Object[] ints = new Object[]{3, 9, 7, 7};
+Comparator<Integer> cmp = (a, b) -> a - b;
+assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 0, 2), cmp) < 0);
+assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 1, 3), cmp) > 0);
+assertTrue((int) compare2FromArray.invoke(Arrays.copyOfRange(ints, 2, 4), cmp) == 0);
+{}
+        }}
+    }
+
     /* ---- TEMPLATE ----
     @Test public void testFoo() throws Throwable {
         {{