You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2016/08/11 12:26:28 UTC
[1/2] groovy git commit: Adding @ClosureParams and Closure return
types in as many places as possible in the GDK
Repository: groovy
Updated Branches:
refs/heads/master b4a6095f5 -> 8071d118e
Adding @ClosureParams and Closure return types in as many places as possible in the GDK
Issue: GROOVY-7283
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/8c218dec
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8c218dec
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8c218dec
Branch: refs/heads/master
Commit: 8c218dec34730e92eb020cbb1b0888dcc89bd35b
Parents: b4a6095
Author: Craig Andrews <ca...@integralblue.com>
Authored: Wed Feb 18 18:27:23 2015 -0500
Committer: paulk <pa...@asert.com.au>
Committed: Thu Aug 11 22:25:57 2016 +1000
----------------------------------------------------------------------
.../groovy/runtime/DefaultGroovyMethods.java | 109 ++++++++++---------
.../groovy/runtime/IOGroovyMethods.java | 11 +-
2 files changed, 65 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/8c218dec/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 8b4212c..4da6708 100644
--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -94,35 +94,6 @@ import java.util.regex.Pattern;
* at the Java method call level. I.e. future versions of Groovy may
* remove or move a method call in this file but would normally
* aim to keep the method available from within Groovy.
- *
- * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
- * @author Jeremy Rayner
- * @author Sam Pullara
- * @author Rod Cope
- * @author Guillaume Laforge
- * @author John Wilson
- * @author Hein Meling
- * @author Dierk Koenig
- * @author Pilho Kim
- * @author Marc Guillemot
- * @author Russel Winder
- * @author bing ran
- * @author Jochen Theodorou
- * @author Paul King
- * @author Michael Baehr
- * @author Joachim Baumann
- * @author Alex Tkachman
- * @author Ted Naleid
- * @author Brad Long
- * @author Jim Jagielski
- * @author Rodolfo Velasco
- * @author jeremi Joslin
- * @author Hamlet D'Arcy
- * @author Cedric Champeau
- * @author Tim Yates
- * @author Dinko Srkoc
- * @author Andre Steingress
- * @author Yu Kobayashi
*/
public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
@@ -1907,6 +1878,21 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
}
/**
+ * Iterates through an array passing each array entry to the given closure.
+ *
+ * @param self the array over which we iterate
+ * @param closure the closure applied on each array entry
+ * @return the self array
+ * @since 2.5.0
+ */
+ public static <T> T[] each(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
+ for(T item : self){
+ closure.call(item);
+ }
+ return self;
+ }
+
+ /**
* Iterates through an aggregate type or data structure,
* passing each item to the given closure. Custom types may utilize this
* method by simply providing an "iterator()" method. The items returned
@@ -1923,6 +1909,27 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
}
/**
+ * Iterates through an array,
+ * passing each array element and the element's index (a counter starting at
+ * zero) to the given closure.
+ *
+ * @param self an array
+ * @param closure a Closure to operate on each array entry
+ * @return the self array
+ * @since 2.5.0
+ */
+ public static <T> T[] eachWithIndex(T[] self, @ClosureParams(value=FromString.class, options="T,Integer") Closure closure) {
+ final Object[] args = new Object[2];
+ int counter = 0;
+ for(T item : self) {
+ args[0] = item;
+ args[1] = counter++;
+ closure.call(args);
+ }
+ return self;
+ }
+
+ /**
* Iterates through an aggregate type or data structure,
* passing each item and the item's index (a counter starting at
* zero) to the given closure.
@@ -1932,7 +1939,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return the self Object
* @since 1.0
*/
- public static <T> T eachWithIndex(T self, Closure closure) {
+ public static <T> T eachWithIndex(T self, /*@ClosureParams(value=FromString.class, options="?,Integer")*/ Closure closure) {
final Object[] args = new Object[2];
int counter = 0;
for (Iterator iter = InvokerHelper.asIterator(self); iter.hasNext();) {
@@ -5300,8 +5307,8 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
*/
public static <K,U,V> Map<K, Integer> countBy(Map<U,V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<K> closure) {
Map<K, Integer> answer = new LinkedHashMap<K, Integer>();
- for (Object entry : self.entrySet()) {
- countAnswer(answer, callClosureForMapEntry(closure, (Map.Entry) entry));
+ for (Map.Entry<U,V> entry : self.entrySet()) {
+ countAnswer(answer, callClosureForMapEntry(closure, entry));
}
return answer;
}
@@ -5333,7 +5340,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
}
// internal helper method
- protected static <T> T callClosureForMapEntry(Closure<T> closure, Map.Entry entry) {
+ protected static <T, K, V> T callClosureForMapEntry(@ClosureParams(value=FromString.class, options={"K,V","Map.Entry<K,V>"}) Closure<T> closure, Map.Entry<K,V> entry) {
if (closure.getMaximumNumberOfParameters() == 2) {
return closure.call(new Object[]{entry.getKey(), entry.getValue()});
}
@@ -5341,7 +5348,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
}
// internal helper method
- protected static <T> T callClosureForLine(Closure<T> closure, String line, int counter) {
+ protected static <T> T callClosureForLine(@ClosureParams(value=FromString.class, options={"String","String,Integer"}) Closure<T> closure, String line, int counter) {
if (closure.getMaximumNumberOfParameters() == 2) {
return closure.call(new Object[]{line, counter});
}
@@ -5349,7 +5356,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
}
// internal helper method
- protected static <T> T callClosureForMapEntryAndCounter(Closure<T> closure, Map.Entry entry, int counter) {
+ protected static <T, K, V> T callClosureForMapEntryAndCounter(@ClosureParams(value=FromString.class, options={"K,V,Integer", "K,V","Map.Entry<K,V>"}) Closure<T> closure, Map.Entry<K,V> entry, int counter) {
if (closure.getMaximumNumberOfParameters() == 3) {
return closure.call(new Object[]{entry.getKey(), entry.getValue(), counter});
}
@@ -6478,7 +6485,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return an item from the Iterable having the minimum value returned by calling the supplied closure with that item as parameter or null for an empty Iterable
* @since 1.0
*/
- public static <T> T min(Iterable<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure closure) {
+ public static <T> T min(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
int params = closure.getMaximumNumberOfParameters();
if (params != 1) {
return min(self, new ClosureComparator<T>(closure));
@@ -6597,7 +6604,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @see #min(java.util.Collection, groovy.lang.Closure)
* @since 1.5.5
*/
- public static <T> T min(Iterator<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure closure) {
+ public static <T> T min(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
return min((Iterable<T>)toList(self), closure);
}
@@ -6620,7 +6627,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @see #min(java.util.Collection, groovy.lang.Closure)
* @since 1.5.5
*/
- public static <T> T min(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
+ public static <T> T min(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
return min((Iterable<T>)toList(self), closure);
}
@@ -6711,7 +6718,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return an item from the Iterable having the maximum value returned by calling the supplied closure with that item as parameter or null for an empty Iterable
* @since 2.2.0
*/
- public static <T> T max(Iterable<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure closure) {
+ public static <T> T max(Iterable<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
int params = closure.getMaximumNumberOfParameters();
if (params != 1) {
return max(self, new ClosureComparator<T>(closure));
@@ -6753,7 +6760,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @see #max(java.util.Collection, groovy.lang.Closure)
* @since 1.5.5
*/
- public static <T> T max(Iterator<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure closure) {
+ public static <T> T max(Iterator<T> self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
return max((Iterable<T>)toList(self), closure);
}
@@ -6776,7 +6783,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @see #max(java.util.Collection, groovy.lang.Closure)
* @since 1.5.5
*/
- public static <T> T max(T[] self, @ClosureParams(FirstParam.Component.class) Closure closure) {
+ public static <T> T max(T[] self, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
return max((Iterable<T>)toList(self), closure);
}
@@ -7877,7 +7884,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return the wrapped Map
* @since 1.7.1
*/
- public static <K, V> Map<K, V> withDefault(Map<K, V> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure init) {
+ public static <K, V> Map<K, V> withDefault(Map<K, V> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure<V> init) {
return MapWithDefault.newInstance(self, init);
}
@@ -7892,7 +7899,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @see #withEagerDefault(java.util.List, groovy.lang.Closure)
* @since 1.8.7
*/
- public static <T> List<T> withDefault(List<T> self, Closure init) {
+ public static <T> List<T> withDefault(List<T> self, @ClosureParams(value=SimpleType.class, options="int") Closure<T> init) {
return withLazyDefault(self, init);
}
@@ -7938,7 +7945,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return the decorated List
* @since 1.8.7
*/
- public static <T> List<T> withLazyDefault(List<T> self, Closure init) {
+ public static <T> List<T> withLazyDefault(List<T> self, @ClosureParams(value=SimpleType.class, options="int") Closure<T> init) {
return ListWithDefault.newInstance(self, true, init);
}
@@ -7978,7 +7985,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return the wrapped List
* @since 1.8.7
*/
- public static <T> List<T> withEagerDefault(List<T> self, Closure init) {
+ public static <T> List<T> withEagerDefault(List<T> self, @ClosureParams(value=SimpleType.class, options="int") Closure<T> init) {
return ListWithDefault.newInstance(self, false, init);
}
@@ -8597,7 +8604,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* @return a newly created sorted List
* @since 2.2.0
*/
- public static <T> List<T> sort(Iterable<T> self, boolean mutate, Closure closure) {
+ public static <T> List<T> sort(Iterable<T> self, boolean mutate, @ClosureParams(value=FromString.class, options={"T","T,T"}) Closure closure) {
List<T> list = mutate ? asList(self) : toList(self);
// use a comparator of one item or two
int params = closure.getMaximumNumberOfParameters();
@@ -10176,7 +10183,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* the given closure evaluates to true
* @since 1.8.7
*/
- public static <K, V> Map<K, V> takeWhile(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<?> condition) {
+ public static <K, V> Map<K, V> takeWhile(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure condition) {
if (self.isEmpty()) {
return createSimilarMap(self);
}
@@ -10303,7 +10310,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* evaluates to true for each element dropped from the front of the SortedSet
* @since 2.4.0
*/
- public static <T> SortedSet<T> dropWhile(SortedSet<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure<?> condition) {
+ public static <T> SortedSet<T> dropWhile(SortedSet<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure condition) {
return (SortedSet<T>) dropWhile((Iterable<T>) self, condition);
}
@@ -10326,7 +10333,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* evaluates to true for each element dropped from the front of the List
* @since 1.8.7
*/
- public static <T> List<T> dropWhile(List<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure<?> condition) {
+ public static <T> List<T> dropWhile(List<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure condition) {
int num = 0;
BooleanClosureWrapper bcw = new BooleanClosureWrapper(condition);
for (T value : self) {
@@ -10357,7 +10364,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* evaluates to true for each element dropped from the front of the Iterable
* @since 1.8.7
*/
- public static <T> Collection<T> dropWhile(Iterable<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure<?> condition) {
+ public static <T> Collection<T> dropWhile(Iterable<T> self, @ClosureParams(FirstParam.FirstGenericType.class) Closure condition) {
Collection<T> selfCol = self instanceof Collection ? (Collection<T>) self : toList(self);
Collection<T> result = createSimilarCollection(selfCol);
addAll(result, dropWhile(self.iterator(), condition));
@@ -10384,7 +10391,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
* evaluates to true for each element dropped from the front of the Map
* @since 1.8.7
*/
- public static <K, V> Map<K, V> dropWhile(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure<?> condition) {
+ public static <K, V> Map<K, V> dropWhile(Map<K, V> self, @ClosureParams(MapEntryOrKeyValue.class) Closure condition) {
if (self.isEmpty()) {
return createSimilarMap(self);
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/8c218dec/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
index 54f1f9e..f8023a3 100644
--- a/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
+++ b/src/main/org/codehaus/groovy/runtime/IOGroovyMethods.java
@@ -1126,7 +1126,7 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
* @throws IOException if an IOException occurs.
* @since 1.5.2
*/
- public static <T> T withWriter(Writer writer, @ClosureParams(value=SimpleType.class, options="java.io.Writer") Closure<T> closure) throws IOException {
+ public static <T> T withWriter(Writer writer, @ClosureParams(FirstParam.class) Closure<T> closure) throws IOException {
try {
T result = closure.call(writer);
@@ -1154,7 +1154,7 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
* @throws IOException if an IOException occurs.
* @since 1.5.2
*/
- public static <T> T withReader(Reader reader, @ClosureParams(value=SimpleType.class, options="java.io.Reader") Closure<T> closure) throws IOException {
+ public static <T> T withReader(Reader reader, @ClosureParams(FirstParam.class) Closure<T> closure) throws IOException {
try {
T result = closure.call(reader);
@@ -1362,7 +1362,7 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
/**
* Transforms each character from this reader by passing it to the given
* closure. The Closure should return each transformed character, which
- * will be passed to the Writer. The reader and writer will be both be
+ * will be passed to the Writer. The reader and writer will both be
* closed before this method returns.
*
* @param self a Reader object
@@ -1377,7 +1377,10 @@ public class IOGroovyMethods extends DefaultGroovyMethodsSupport {
char[] chars = new char[1];
while ((c = self.read()) != -1) {
chars[0] = (char) c;
- writer.write((String) closure.call(new String(chars)));
+ Object o = closure.call(new String(chars));
+ if (o != null) {
+ writer.write(o.toString());
+ }
}
writer.flush();
[2/2] groovy git commit: GROOVY-7283: DefaultGroovyMethods methods
should include type information
Posted by pa...@apache.org.
GROOVY-7283: DefaultGroovyMethods methods should include type information
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/8071d118
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8071d118
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8071d118
Branch: refs/heads/master
Commit: 8071d118e77c13e78ec5c64295f8b98a478a575a
Parents: 8c218de
Author: paulk <pa...@asert.com.au>
Authored: Thu Aug 11 22:26:17 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Thu Aug 11 22:26:17 2016 +1000
----------------------------------------------------------------------
.../stc/DefaultGroovyMethodsSTCTest.groovy | 25 +++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/8071d118/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index 27b006c..d6aeb35 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -18,11 +18,8 @@
*/
package groovy.transform.stc
-
/**
* Unit tests for static type checking : default groovy methods.
- *
- * @author Cedric Champeau
*/
class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
@@ -125,5 +122,27 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
assert ListCompilerAndReverser.revlist([["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]) == [9, 8, 7, 6, 5, 4, 3, 2, 1]
'''
}
+
+ // GROOVY-7283
+ void testArrayMinMaxSupportsOneAndTwoArgClosures() {
+ assertScript '''
+ Date now = new Date()
+ Date then = now + 7
+ def dates = [now, then] as Date[]
+ assert dates.min() == now
+ assert dates.max() == then
+ assert dates.min{ d -> d.time } == now
+ assert dates.max{ d1, d2 -> d2.time <=> d1.time } == now
+ '''
+ }
+
+ // GROOVY-7283
+ void testListWithDefaultInfersInt() {
+ assertScript '''
+ def list = [].withDefault{ it.longValue() }
+ list[0] = list.get(3) // TODO why doesn't getAt work?
+ assert list[0] == 3 && list[0].class == Long
+ '''
+ }
}