[7/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple1.java
--
diff --git a/src/main/groovy/groovy/lang/Tuple1.java 
b/src/main/groovy/groovy/lang/Tuple1.java
index 9b8d6bd..1e84013 100644
--- a/src/main/groovy/groovy/lang/Tuple1.java
+++ b/src/main/groovy/groovy/lang/Tuple1.java
@@ -18,6 +18,8 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Function1;
+
 /**
  * Represents a list of 1 typed Object.
  *
@@ -25,30 +27,197 @@ package groovy.lang;
  */
 public class Tuple1 extends Tuple {
 private static final long serialVersionUID = -4647790147461409603L;
-private final T1 first;
+private final T1 v1;
 
-public Tuple1(T1 first) {
-super(first);
+public Tuple1(T1 t1) {
+super(t1);
 
-this.first = first;
+this.v1 = t1;
 }
 
-@Override
-public Object get(int index) {
-switch (index) {
-case 0:
-return first;
-default:
-throw new IndexOutOfBoundsException("index: " + index);
-}
+public Tuple1(Tuple1 tuple) {
+this(tuple.v1);
 }
 
-@Override
-public int size() {
-return 1;
+@Deprecated
+public T1 getFirst() {
+return v1;
 }
 
-public T1 getFirst() {
-return first;
+public T1 v1() {
+return v1;
+}
+
+/**
+ * Concatenate a value to this tuple.
+ */
+public final  Tuple2 concat(T2 value) {
+return new Tuple2<>(v1, value);
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple2 concat(Tuple1 tuple) {
+return new Tuple2<>(v1, tuple.v1());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple3 concat(Tuple2 tuple) {
+return new Tuple3<>(v1, tuple.v1(), tuple.v2());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple4 concat(Tuple3 
tuple) {
+return new Tuple4<>(v1, tuple.v1(), tuple.v2(), tuple.v3());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple5 concat(Tuple4 tuple) {
+return new Tuple5<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple6 
concat(Tuple5 tuple) {
+return new Tuple6<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple7 
concat(Tuple6 tuple) {
+return new Tuple7<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple8 concat(Tuple7 tuple) {
+return new Tuple8<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple9 concat(Tuple8 tuple) {
+return new Tuple9<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple10 concat(Tuple9 
tuple) {
+return new Tuple10<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple11 concat(Tuple10 tuple) {
+return new Tuple11<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), 
tuple.v10());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple12 concat(Tuple11 tuple) {
+return new Tuple12<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), 
tuple.v10(), tuple.v11());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  
Tuple13 
concat(Tuple12 tuple) {
+return new Tuple13<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), 
tuple.v10(), tuple.v11(), tuple.v12());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  
Tuple14 
concat(Tuple13 tuple) {
+return new Tuple14<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), 
tuple.v10(), tuple.v11(), tuple.v12(), tuple.v13());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple15 
concat(Tuple14 
tuple) {
+return new Tuple15<>(v1, tuple.v1(), tuple.v2(), tuple.v3(), 
tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), tuple.v9(), 

[5/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple4.java
--
diff --git a/src/main/groovy/groovy/lang/Tuple4.java 
b/src/main/groovy/groovy/lang/Tuple4.java
index 04f414e..30793a2 100644
--- a/src/main/groovy/groovy/lang/Tuple4.java
+++ b/src/main/groovy/groovy/lang/Tuple4.java
@@ -19,6 +19,9 @@
 
 package groovy.lang;
 
+import groovy.util.function.Function1;
+import groovy.util.function.Function4;
+
 /**
  * Represents a list of 4 typed Objects.
  *
@@ -26,54 +29,294 @@ package groovy.lang;
  */
 public class Tuple4 extends Tuple {
 private static final long serialVersionUID = -7788878731471377207L;
-private final T1 first;
-private final T2 second;
-private final T3 third;
-private final T4 fourth;
-
-public Tuple4(T1 first, T2 second, T3 third, T4 fourth) {
-super(first, second, third, fourth);
+private final T1 v1;
+private final T2 v2;
+private final T3 v3;
+private final T4 v4;
 
-this.first = first;
-this.second = second;
-this.third = third;
-this.fourth = fourth;
-}
+public Tuple4(T1 v1, T2 v2, T3 v3, T4 v4) {
+super(v1, v2, v3, v4);
 
-@Override
-public Object get(int index) {
-switch (index) {
-case 0:
-return first;
-case 1:
-return second;
-case 2:
-return third;
-case 3:
-return fourth;
-default:
-throw new IndexOutOfBoundsException("index: " + index);
-}
+this.v1 = v1;
+this.v2 = v2;
+this.v3 = v3;
+this.v4 = v4;
 }
 
-@Override
-public int size() {
-return 4;
+public Tuple4(Tuple4 tuple) {
+this(tuple.v1, tuple.v2, tuple.v3, tuple.v4);
 }
 
+@Deprecated
 public T1 getFirst() {
-return first;
+return v1;
 }
 
+@Deprecated
 public T2 getSecond() {
-return second;
+return v2;
 }
 
+@Deprecated
 public T3 getThird() {
-return third;
+return v3;
 }
 
+@Deprecated
 public T4 getFourth() {
-return fourth;
+return v4;
+}
+
+public T1 v1() {
+return v1;
+}
+
+public T2 v2() {
+return v2;
+}
+
+public T3 v3() {
+return v3;
+}
+
+public T4 v4() {
+return v4;
+}
+
+
+/**
+ * Concatenate a value to this tuple.
+ */
+public final  Tuple5 concat(T5 value) {
+return new Tuple5<>(v1, v2, v3, v4, value);
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple5 concat(Tuple1 tuple) {
+return new Tuple5<>(v1, v2, v3, v4, tuple.v1());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple6 concat(Tuple2 
tuple) {
+return new Tuple6<>(v1, v2, v3, v4, tuple.v1(), tuple.v2());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple7 
concat(Tuple3 tuple) {
+return new Tuple7<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple8 
concat(Tuple4 tuple) {
+return new Tuple8<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple9 concat(Tuple5 tuple) {
+return new Tuple9<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4(), tuple.v5());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple10 concat(Tuple6 tuple) {
+return new Tuple10<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple11 concat(Tuple7 tuple) {
+return new Tuple11<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple12 concat(Tuple8 tuple) {
+return new Tuple12<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple13 concat(Tuple9 tuple) {
+return new Tuple13<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), 
tuple.v9());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple14 concat(Tuple10 tuple) {
+return new Tuple14<>(v1, v2, v3, v4, tuple.v1(), tuple.v2(), 
tuple.v3(), tuple.v4(), tuple.v5(), tuple.v6(), tuple.v7(), tuple.v8(), 
tuple.v9(), 

[1/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
Repository: groovy
Updated Branches:
  refs/heads/master f07dbebe0 -> 3ac1abcd0


http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/test/groovy/lang/TupleTest.java
--
diff --git a/src/test/groovy/lang/TupleTest.java 
b/src/test/groovy/lang/TupleTest.java
index 19f07b7..65243cc 100644
--- a/src/test/groovy/lang/TupleTest.java
+++ b/src/test/groovy/lang/TupleTest.java
@@ -18,9 +18,31 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Consumer0;
+import groovy.util.function.Consumer1;
+import groovy.util.function.Consumer2;
 import junit.framework.TestCase;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import static groovy.lang.Tuple.collectors;
+import static groovy.lang.Tuple.tuple;
+import static java.util.stream.Collectors.averagingInt;
+import static java.util.stream.Collectors.counting;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.mapping;
 
 /**
  * @author James Strachan
@@ -41,15 +63,13 @@ public class TupleTest extends TestCase {
 try {
 t.get(-1);
 fail("Should have thrown IndexOut");
-}
-catch (IndexOutOfBoundsException e) {
+} catch (IndexOutOfBoundsException e) {
 // worked
 }
 try {
 t.get(10);
 fail("Should have thrown IndexOut");
-}
-catch (IndexOutOfBoundsException e) {
+} catch (IndexOutOfBoundsException e) {
 // worked
 }
 
@@ -307,4 +327,280 @@ public class TupleTest extends TestCase {
 
 assertEquals(t, t.subTuple(0, t.size()));
 }
+
+public void testEqualsHashCode() {
+Set> set = new HashSet<>();
+
+set.add(tuple(1, "abc"));
+assertEquals(1, set.size());
+set.add(tuple(1, "abc"));
+assertEquals(1, set.size());
+set.add(tuple(null, null));
+assertEquals(2, set.size());
+set.add(tuple(null, null));
+assertEquals(2, set.size());
+set.add(tuple(1, null));
+assertEquals(3, set.size());
+set.add(tuple(1, null));
+assertEquals(3, set.size());
+}
+
+public void testEqualsNull() {
+assertFalse(tuple(1).equals(null));
+assertFalse(tuple(1, 2).equals(null));
+assertFalse(tuple(1, 2, 3).equals(null));
+}
+
+public void testToMap() {
+Map m = new LinkedHashMap<>();
+m.put(0, 1);
+m.put(1, "a");
+m.put(2, null);
+assertEquals(m, tuple(1, "a", null).toMap(i -> i));
+}
+
+public void testSwap() {
+assertEquals(tuple(1, "a"), tuple("a", 1).swap());
+assertEquals(tuple(1, "a"), tuple(1, "a").swap().swap());
+}
+
+public void testConcat() {
+assertEquals(tuple(1, "a"), tuple(1).concat("a"));
+assertEquals(tuple(1, "a", 2), tuple(1).concat("a").concat(2));
+
+assertEquals(tuple(1, "a"), tuple(1).concat(tuple("a")));
+assertEquals(tuple(1, "a", 2, "b", 3, "c", 4, "d"), 
tuple(1).concat(tuple("a", 2, "b").concat(tuple(3).concat(tuple("c", 4, 
"d");
+}
+
+public void testCompareTo() {
+Set> set = new TreeSet<>();
+
+set.add(tuple(2, "a"));
+set.add(tuple(1, "b"));
+set.add(tuple(1, "a"));
+set.add(tuple(2, "a"));
+
+assertEquals(3, set.size());
+assertEquals(Arrays.asList(tuple(1, "a"), tuple(1, "b"), tuple(2, 
"a")), new ArrayList<>(set));
+}
+
+public void testCompareToWithNulls() {
+Set> set = new TreeSet<>();
+
+set.add(tuple(2, "a"));
+set.add(tuple(1, "b"));
+set.add(tuple(1, null));
+set.add(tuple(null, "a"));
+set.add(tuple(null, "b"));
+set.add(tuple(null, null));
+
+assertEquals(6, set.size());
+assertEquals(Arrays.asList(tuple(1, "b"), tuple(1, null), tuple(2, 
"a"), tuple(null, "a"), tuple(null, "b"), tuple(null, null)), new 
ArrayList<>(set));
+}
+
+public void testIterable() {
+LinkedList list = new LinkedList<>(tuple(1, "b", null));
+for (Object o : tuple(1, "b", null)) {
+assertEquals(list.poll(), o);
+}
+}
+
+public void testFunctions() {
+assertEquals("[1, b, null]", tuple(1, "b", null).map((v1, v2, v3) -> 
tuple(v1, v2, v3).toString()));
+assertEquals("1-b", tuple(1, "b", null).map((v1, v2, v3) -> v1 + "-" + 
v2));
+}
+
+public void testMapN() {
+assertEquals(tuple(1, "a", 2, "b"), tuple(1, null, 2, null).map2(v -> 
"a").map4(v -> "b"));
+}
+
+public void testOverlaps() {
+   

[3/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer3.java
--
diff --git a/src/main/groovy/groovy/util/function/Consumer3.java 
b/src/main/groovy/groovy/util/function/Consumer3.java
new file mode 100644
index 000..f5ac7e2
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer3.java
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+
+
+/**
+ * A consumer with 3 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer3 {
+
+/**
+ * Performs this operation on the given argument.
+ *
+ * @param args The arguments as a tuple.
+ */
+default void accept(Tuple3 args) 
{
+accept(args.v1(), args.v2(), args.v3());
+}
+
+/**
+ * Performs this operation on the given argument.
+ */
+void accept(T1 v1, T2 v2, T3 v3);
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer2 acceptPartially(T1 v1) {
+return (v2, v3) -> accept(v1, v2, v3);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer1 acceptPartially(T1 v1, T2 v2) {
+return (v3) -> accept(v1, v2, v3);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3) {
+return () -> accept(v1, v2, v3);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer2 acceptPartially(Tuple1 args) {
+return (v2, v3) -> accept(args.v1(), v2, v3);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer1 acceptPartially(Tuple2 
args) {
+return (v3) -> accept(args.v1(), args.v2(), v3);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer0 acceptPartially(Tuple3 args) {
+return () -> accept(args.v1(), args.v2(), args.v3());
+}
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer4.java
--
diff --git a/src/main/groovy/groovy/util/function/Consumer4.java 
b/src/main/groovy/groovy/util/function/Consumer4.java
new file mode 100644
index 000..97f7252
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer4.java
@@ -0,0 +1,104 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+
+
+/**
+ * A consumer with 4 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer4 {
+
+/**
+ * Performs this operation on the given argument.
+ *
+ * @param args The arguments as a tuple.
+ */
+default void accept(Tuple4 args) {
+accept(args.v1(), args.v2(), args.v3(), args.v4());
+}
+
+/**
+ * Performs this operation on the given argument.
+ */
+void accept(T1 v1, T2 v2, T3 v3, T4 v4);
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default 

[2/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Function14.java
--
diff --git a/src/main/groovy/groovy/util/function/Function14.java 
b/src/main/groovy/groovy/util/function/Function14.java
new file mode 100644
index 000..72c7d77
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Function14.java
@@ -0,0 +1,255 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple11;
+import groovy.lang.Tuple12;
+import groovy.lang.Tuple13;
+import groovy.lang.Tuple14;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A function with 14 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Function14 {
+
+/**
+ * Apply this function to the arguments.
+ *
+ * @param args The arguments as a tuple.
+ */
+default R apply(Tuple14 
args) {
+return apply(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), 
args.v6(), args.v7(), args.v8(), args.v9(), args.v10(), args.v11(), args.v12(), 
args.v13(), args.v14());
+}
+
+/**
+ * Apply this function to the arguments.
+ */
+R apply(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 
v10, T11 v11, T12 v12, T13 v13, T14 v14);
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function13 applyPartially(T1 v1) {
+return (v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> 
apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function12 
applyPartially(T1 v1, T2 v2) {
+return (v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> 
apply(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function11 
applyPartially(T1 v1, T2 v2, T3 v3) {
+return (v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, 
v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function10 
applyPartially(T1 v1, T2 v2, T3 v3, T4 v4) {
+return (v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, 
v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function9 
applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+return (v6, v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, 
v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function8 
applyPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) {
+return (v7, v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, 
v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function7 applyPartially(T1 
v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) {
+return (v8, v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, 
v6, v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function6 applyPartially(T1 v1, T2 
v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+return (v9, v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, 
v7, v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * Partially apply this function to the arguments.
+ */
+default Function5 applyPartially(T1 v1, T2 v2, 
T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+return (v10, v11, v12, v13, v14) -> apply(v1, v2, v3, v4, v5, v6, v7, 
v8, v9, v10, v11, v12, v13, v14);
+}
+
+/**
+ * 

[4/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/util/function/Consumer10.java
--
diff --git a/src/main/groovy/groovy/util/function/Consumer10.java 
b/src/main/groovy/groovy/util/function/Consumer10.java
new file mode 100644
index 000..8e49f45
--- /dev/null
+++ b/src/main/groovy/groovy/util/function/Consumer10.java
@@ -0,0 +1,194 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.util.function;
+
+import groovy.lang.Tuple1;
+import groovy.lang.Tuple10;
+import groovy.lang.Tuple2;
+import groovy.lang.Tuple3;
+import groovy.lang.Tuple4;
+import groovy.lang.Tuple5;
+import groovy.lang.Tuple6;
+import groovy.lang.Tuple7;
+import groovy.lang.Tuple8;
+import groovy.lang.Tuple9;
+
+
+/**
+ * A consumer with 10 arguments.
+ *
+ * @since 3.0.0
+ */
+@FunctionalInterface
+public interface Consumer10 {
+
+/**
+ * Performs this operation on the given argument.
+ *
+ * @param args The arguments as a tuple.
+ */
+default void accept(Tuple10 args) {
+accept(args.v1(), args.v2(), args.v3(), args.v4(), args.v5(), 
args.v6(), args.v7(), args.v8(), args.v9(), args.v10());
+}
+
+/**
+ * Performs this operation on the given argument.
+ */
+void accept(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, 
T10 v10);
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer9 acceptPartially(T1 
v1) {
+return (v2, v3, v4, v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, 
v5, v6, v7, v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer8 acceptPartially(T1 v1, 
T2 v2) {
+return (v3, v4, v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, 
v6, v7, v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer7 acceptPartially(T1 v1, T2 
v2, T3 v3) {
+return (v4, v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, 
v7, v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer6 acceptPartially(T1 v1, T2 v2, 
T3 v3, T4 v4) {
+return (v5, v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, 
v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer5 acceptPartially(T1 v1, T2 v2, T3 
v3, T4 v4, T5 v5) {
+return (v6, v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, 
v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer4 acceptPartially(T1 v1, T2 v2, T3 v3, T4 
v4, T5 v5, T6 v6) {
+return (v7, v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, 
v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer3 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, 
T5 v5, T6 v6, T7 v7) {
+return (v8, v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, 
v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer2 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 
v5, T6 v6, T7 v7, T8 v8) {
+return (v9, v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer1 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, 
T6 v6, T7 v7, T8 v8, T9 v9) {
+return (v10) -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer0 acceptPartially(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 
v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+return () -> accept(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+/**
+ * Let this consumer partially accept the arguments.
+ */
+default Consumer9 
acceptPartially(Tuple1 args) {
+return (v2, v3, v4, v5, v6, v7, v8, v9, v10) -> accept(args.v1(), v2, 
v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+/**

[6/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple14.java
--
diff --git a/src/main/groovy/groovy/lang/Tuple14.java 
b/src/main/groovy/groovy/lang/Tuple14.java
new file mode 100644
index 000..12dee86
--- /dev/null
+++ b/src/main/groovy/groovy/lang/Tuple14.java
@@ -0,0 +1,618 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package groovy.lang;
+
+import groovy.util.function.Function1;
+import groovy.util.function.Function14;
+
+/**
+ * Represents a list of 14 typed Objects.
+ *
+ * @since 3.0.0
+ */
+public class Tuple14 extends Tuple {
+private static final long serialVersionUID = -8866382365396941648L;
+private final T1 v1;
+private final T2 v2;
+private final T3 v3;
+private final T4 v4;
+private final T5 v5;
+private final T6 v6;
+private final T7 v7;
+private final T8 v8;
+private final T9 v9;
+private final T10 v10;
+private final T11 v11;
+private final T12 v12;
+private final T13 v13;
+private final T14 v14;
+
+public Tuple14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 
v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+super(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
+
+this.v1 = v1;
+this.v2 = v2;
+this.v3 = v3;
+this.v4 = v4;
+this.v5 = v5;
+this.v6 = v6;
+this.v7 = v7;
+this.v8 = v8;
+this.v9 = v9;
+this.v10 = v10;
+this.v11 = v11;
+this.v12 = v12;
+this.v13 = v13;
+this.v14 = v14;
+}
+
+public Tuple14(Tuple14 tuple) {
+this(tuple.v1, tuple.v2, tuple.v3, tuple.v4, tuple.v5, tuple.v6, 
tuple.v7, tuple.v8, tuple.v9, tuple.v10, tuple.v11, tuple.v12, tuple.v13, 
tuple.v14);
+}
+
+@Deprecated
+public T1 getFirst() {
+return v1;
+}
+
+@Deprecated
+public T2 getSecond() {
+return v2;
+}
+
+@Deprecated
+public T3 getThird() {
+return v3;
+}
+
+@Deprecated
+public T4 getFourth() {
+return v4;
+}
+
+@Deprecated
+public T5 getFifth() {
+return v5;
+}
+
+@Deprecated
+public T6 getSixth() {
+return v6;
+}
+
+@Deprecated
+public T7 getSeventh() {
+return v7;
+}
+
+@Deprecated
+public T8 getEighth() {
+return v8;
+}
+
+@Deprecated
+public T9 getNinth() {
+return v9;
+}
+
+public T1 v1() {
+return v1;
+}
+
+public T2 v2() {
+return v2;
+}
+
+public T3 v3() {
+return v3;
+}
+
+public T4 v4() {
+return v4;
+}
+
+public T5 v5() {
+return v5;
+}
+
+public T6 v6() {
+return v6;
+}
+
+public T7 v7() {
+return v7;
+}
+
+public T8 v8() {
+return v8;
+}
+
+public T9 v9() {
+return v9;
+}
+
+public T10 v10() {
+return v10;
+}
+
+public T11 v11() {
+return v11;
+}
+
+public T12 v12() {
+return v12;
+}
+
+public T13 v13() {
+return v13;
+}
+
+public T14 v14() {
+return v14;
+}
+
+/**
+ * Concatenate a value to this tuple.
+ */
+public final  Tuple15 concat(T15 value) {
+return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, 
v12, v13, v14, value);
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple15 concat(Tuple1 tuple) {
+return new Tuple15<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, 
v12, v13, v14, tuple.v1());
+}
+
+/**
+ * Concatenate a tuple to this tuple.
+ */
+public final  Tuple16 concat(Tuple2 tuple) {
+return new Tuple16<>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, 
v12, v13, v14, tuple.v1(), tuple.v2());
+}
+
+/**
+ * Split this tuple into two tuples of degree 0 and 14.
+ */
+public final Tuple2> split0() {
+return new Tuple2<>(limit0(), skip0());
+}
+
+/**
+ * Split this tuple into two tuples of degree 1 and 13.
+ */
+  

[8/8] groovy git commit: GROOVY-8874: Refine tuples to support functional programming better(closes #821)

2018-11-12 Thread sunlan
GROOVY-8874: Refine tuples to support functional programming better(closes #821)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/3ac1abcd
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/3ac1abcd
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/3ac1abcd

Branch: refs/heads/master
Commit: 3ac1abcd0b586f531272bb06b93c8307df357d64
Parents: f07dbeb
Author: Daniel Sun 
Authored: Tue Nov 13 00:43:03 2018 +0800
Committer: Daniel Sun 
Committed: Tue Nov 13 00:43:03 2018 +0800

--
 src/main/groovy/groovy/lang/Tuple.java  | 1412 +-
 src/main/groovy/groovy/lang/Tuple0.java |  188 +++
 src/main/groovy/groovy/lang/Tuple1.java |  203 ++-
 src/main/groovy/groovy/lang/Tuple10.java|  510 +++
 src/main/groovy/groovy/lang/Tuple11.java|  537 +++
 src/main/groovy/groovy/lang/Tuple12.java|  565 +++
 src/main/groovy/groovy/lang/Tuple13.java|  592 
 src/main/groovy/groovy/lang/Tuple14.java|  618 
 src/main/groovy/groovy/lang/Tuple15.java|  644 
 src/main/groovy/groovy/lang/Tuple16.java|  665 +
 src/main/groovy/groovy/lang/Tuple2.java |  271 +++-
 src/main/groovy/groovy/lang/Tuple3.java |  275 +++-
 src/main/groovy/groovy/lang/Tuple4.java |  309 +++-
 src/main/groovy/groovy/lang/Tuple5.java |  343 -
 src/main/groovy/groovy/lang/Tuple6.java |  377 -
 src/main/groovy/groovy/lang/Tuple7.java |  413 -
 src/main/groovy/groovy/lang/Tuple8.java |  447 +-
 src/main/groovy/groovy/lang/Tuple9.java |  481 +-
 .../groovy/groovy/util/function/Consumer0.java  |   64 +
 .../groovy/groovy/util/function/Consumer1.java  |   75 +
 .../groovy/groovy/util/function/Consumer10.java |  194 +++
 .../groovy/groovy/util/function/Consumer11.java |  209 +++
 .../groovy/groovy/util/function/Consumer12.java |  224 +++
 .../groovy/groovy/util/function/Consumer13.java |  239 +++
 .../groovy/groovy/util/function/Consumer14.java |  254 
 .../groovy/groovy/util/function/Consumer15.java |  269 
 .../groovy/groovy/util/function/Consumer16.java |  284 
 .../groovy/groovy/util/function/Consumer2.java  |   90 ++
 .../groovy/groovy/util/function/Consumer3.java  |   89 ++
 .../groovy/groovy/util/function/Consumer4.java  |  104 ++
 .../groovy/groovy/util/function/Consumer5.java  |  119 ++
 .../groovy/groovy/util/function/Consumer6.java  |  134 ++
 .../groovy/groovy/util/function/Consumer7.java  |  149 ++
 .../groovy/groovy/util/function/Consumer8.java  |  164 ++
 .../groovy/groovy/util/function/Consumer9.java  |  179 +++
 .../groovy/groovy/util/function/Function0.java  |   69 +
 .../groovy/groovy/util/function/Function1.java  |   75 +
 .../groovy/groovy/util/function/Function10.java |  195 +++
 .../groovy/groovy/util/function/Function11.java |  210 +++
 .../groovy/groovy/util/function/Function12.java |  225 +++
 .../groovy/groovy/util/function/Function13.java |  240 +++
 .../groovy/groovy/util/function/Function14.java |  255 
 .../groovy/groovy/util/function/Function15.java |  270 
 .../groovy/groovy/util/function/Function16.java |  285 
 .../groovy/groovy/util/function/Function2.java  |   91 ++
 .../groovy/groovy/util/function/Function3.java  |   90 ++
 .../groovy/groovy/util/function/Function4.java  |  105 ++
 .../groovy/groovy/util/function/Function5.java  |  120 ++
 .../groovy/groovy/util/function/Function6.java  |  135 ++
 .../groovy/groovy/util/function/Function7.java  |  150 ++
 .../groovy/groovy/util/function/Function8.java  |  165 ++
 .../groovy/groovy/util/function/Function9.java  |  180 +++
 src/test/groovy/lang/TupleTest.java |  304 +++-
 53 files changed, 14504 insertions(+), 350 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/groovy/blob/3ac1abcd/src/main/groovy/groovy/lang/Tuple.java
--
diff --git a/src/main/groovy/groovy/lang/Tuple.java 
b/src/main/groovy/groovy/lang/Tuple.java
index 8a1a6e7..1ccd5bd 100644
--- a/src/main/groovy/groovy/lang/Tuple.java
+++ b/src/main/groovy/groovy/lang/Tuple.java
@@ -18,19 +18,56 @@
  */
 package groovy.lang;
 
+import groovy.util.function.Consumer0;
+import groovy.util.function.Consumer1;
+import groovy.util.function.Consumer10;
+import groovy.util.function.Consumer11;
+import groovy.util.function.Consumer12;
+import groovy.util.function.Consumer13;
+import groovy.util.function.Consumer14;
+import groovy.util.function.Consumer15;
+import groovy.util.function.Consumer16;
+import groovy.util.function.Consumer2;
+import groovy.util.function.Consumer3;
+import groovy.util.function.Consumer4;
+import groovy.util.function.Consumer5;
+import groovy.util.function.Consumer6;

groovy git commit: GROOVY-8868: Static factory method does not compile anymore with 2.5.3 (was ok with 2.4.x)

2018-11-12 Thread paulk
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X 781f15cc1 -> 43908fa49


GROOVY-8868: Static factory method does not compile anymore with 2.5.3 (was ok 
with 2.4.x)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/43908fa4
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/43908fa4
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/43908fa4

Branch: refs/heads/GROOVY_2_5_X
Commit: 43908fa4903056301ea531ac08004b217dbb416e
Parents: 781f15c
Author: Paul King 
Authored: Tue Nov 6 23:29:49 2018 +1000
Committer: Paul King 
Committed: Mon Nov 12 22:56:36 2018 +1000

--
 .../TupleConstructorASTTransformation.java  |  6 
 src/test/groovy/bugs/Groovy8868Bug.groovy   | 35 
 2 files changed, 41 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/groovy/blob/43908fa4/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
--
diff --git 
a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
 
b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
index d421a47..1748eb6 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
@@ -39,6 +39,7 @@ import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.ast.stmt.EmptyStatement;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
 import org.codehaus.groovy.classgen.VariableScopeVisitor;
 import org.codehaus.groovy.control.CompilationUnit;
@@ -265,6 +266,11 @@ public class TupleConstructorASTTransformation extends 
AbstractASTTransformation
 scopeVisitor.visitClass(cNode);
 }
 
+// GROOVY-8868 don't want an empty body to cause the constructor to be 
deleted later
+if (body.isEmpty()) {
+body.addStatement(new 
ExpressionStatement(ConstantExpression.EMPTY_EXPRESSION));
+}
+
 // If the first param is def or a Map, named args might not work as 
expected so we add a hard-coded map constructor in this case
 // we don't do it for LinkedHashMap for now (would lead to duplicate 
signature)
 // or if there is only one Map property (for backwards compatibility)

http://git-wip-us.apache.org/repos/asf/groovy/blob/43908fa4/src/test/groovy/bugs/Groovy8868Bug.groovy
--
diff --git a/src/test/groovy/bugs/Groovy8868Bug.groovy 
b/src/test/groovy/bugs/Groovy8868Bug.groovy
new file mode 100644
index 000..d30d8a2
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8868Bug.groovy
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+class Groovy8868Bug extends GroovyTestCase {
+void testNoargConstructorIncludedForImmutableWithNoProperties() {
+assertScript '''
+@groovy.transform.CompileStatic
+@groovy.transform.Immutable
+class Foo {
+static Foo create(){
+return new Foo()
+}
+}
+
+assert Foo.create().toString() == 'Foo()'
+'''
+}
+}