You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2023/11/23 16:24:53 UTC

(groovy) branch master updated (50f54915e9 -> 63c4682474)

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


    from 50f54915e9 GROOVY-11194: Add missing options
     new 7e0471f7ff GROOVY-7934: refine `inject` type vars
     new 63c4682474 GROOVY-11213: array `indexOf` and `lastIndexOf`

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../groovy/runtime/ArrayGroovyMethods.java         | 60 ++++++++++++++++-
 .../groovy/runtime/DefaultGroovyMethods.java       | 78 +++++++++++-----------
 .../groovy/transform/stc/GenericsSTCTest.groovy    |  4 +-
 3 files changed, 98 insertions(+), 44 deletions(-)


(groovy) 01/02: GROOVY-7934: refine `inject` type vars

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 7e0471f7ff2e1cfbf77f67997e605990d6ed19f3
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Nov 23 10:06:00 2023 -0600

    GROOVY-7934: refine `inject` type vars
---
 .../codehaus/groovy/runtime/ArrayGroovyMethods.java  |  6 +++---
 .../groovy/runtime/DefaultGroovyMethods.java         | 20 ++++++++++----------
 src/test/groovy/transform/stc/GenericsSTCTest.groovy |  4 ++--
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index 3df60a0e95..753702412a 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -4641,11 +4641,11 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #inject(Object[], Object, Closure)
      * @since 1.8.7
      */
-    public static <E, T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
+    public static <E extends T, T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         if (self.length == 0) {
             throw new NoSuchElementException("Cannot call inject() on an empty array without passing an initial value.");
         }
-        T value = (T) self[0];
+        T value = self[0];
         Object[] params = new Object[2];
         for (int i = 1; i < self.length; i += 1) {
             params[0] = value;
@@ -4681,7 +4681,7 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return base value for empty array or the result of the last closure call
      * @since 1.5.0
      */
-    public static <E, T, U extends T, V extends T> T inject(E[] self, U initialValue, @ClosureParams(value=FromString.class,options="U,E") Closure<V> closure) {
+    public static <E, T, U extends T, V extends T> T inject(E[] self, U initialValue, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         T value = initialValue;
         Object[] params = new Object[2];
         for (int i = 0; i < self.length; i += 1) {
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 99d3c4d618..6c07882d8f 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -7314,7 +7314,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #inject(Object, Object, Closure)
      * @since 1.8.7
      */
-    public static <T, V extends T> T inject(Object self, @ClosureParams(value=FromString.class,options="?,?") Closure<V> closure) {
+    public static <T, V extends T> T inject(Object self, @ClosureParams(value=FromString.class,options="T,?") Closure<V> closure) {
         Iterator<?> iter = InvokerHelper.asIterator(self);
         if (!iter.hasNext()) {
             throw new NoSuchElementException("Cannot call inject() on an empty iterable without passing an initial value.");
@@ -7348,7 +7348,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #inject(Iterable, Object, Closure)
      * @since 5.0.0
      */
-    public static <E, T, V extends T> T inject(Iterable<E> self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
+    public static <E extends T, T, V extends T> T inject(Iterable<E> self, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         Iterator<E> iter = self.iterator();
         if (!iter.hasNext()) {
             throw new NoSuchElementException("Cannot call inject() on an empty iterable without passing an initial value.");
@@ -7374,7 +7374,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #inject(Iterator, Object, Closure)
      * @since 1.5.0
      */
-    public static <T, U extends T, V extends T> T inject(Object self, U initialValue, @ClosureParams(value=FromString.class,options="U,?") Closure<V> closure) {
+    public static <T, U extends T, V extends T> T inject(Object self, U initialValue, @ClosureParams(value=FromString.class,options="T,?") Closure<V> closure) {
         Iterator iter = InvokerHelper.asIterator(self);
         return (T) inject(iter, initialValue, closure);
     }
@@ -7421,7 +7421,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the result of the last closure call
      * @since 5.0.0
      */
-    public static <E, T, U extends T, V extends T> T inject(Iterable<E> self, U initialValue, @ClosureParams(value=FromString.class,options="U,E") Closure<V> closure) {
+    public static <E, T, U extends T, V extends T> T inject(Iterable<E> self, U initialValue, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         return inject(self.iterator(), initialValue, closure);
     }
 
@@ -7440,7 +7440,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the result of the last closure call
      * @since 1.5.0
      */
-    public static <E, T, U extends T, V extends T> T inject(Iterator<E> self, U initialValue, @ClosureParams(value=FromString.class,options="U,E") Closure<V> closure) {
+    public static <E, T, U extends T, V extends T> T inject(Iterator<E> self, U initialValue, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         T value = initialValue;
         Object[] params = new Object[2];
         while (self.hasNext()) {
@@ -7475,7 +7475,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the result of the last closure call
      * @since 1.8.1
      */
-    public static <K, V, T, U extends T, W extends T> T inject(Map<K, V> self, U initialValue, @ClosureParams(value=FromString.class,options={"U,Map.Entry<K,V>","U,K,V"}) Closure<W> closure) {
+    public static <K, V, T, U extends T, W extends T> T inject(Map<K, V> self, U initialValue, @ClosureParams(value=FromString.class,options={"T,Map.Entry<K,V>","T,K,V"}) Closure<W> closure) {
         T value = initialValue;
         for (Map.Entry<K, V> entry : self.entrySet()) {
             if (closure.getMaximumNumberOfParameters() == 3) {
@@ -16682,22 +16682,22 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     @Deprecated(since = "5.0.0")
-    public static <E, T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
+    public static <E extends T, T, V extends T> T inject(E[] self, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         return ArrayGroovyMethods.inject(self, closure);
     }
 
     @Deprecated(since = "5.0.0")
-    public static <E, T, V extends T> T inject(Collection<E> self, @ClosureParams(value=FromString.class,options="E,E") Closure<V> closure) {
+    public static <E extends T, T, V extends T> T inject(Collection<E> self, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         return inject((Iterable<E>) self, closure);
     }
 
     @Deprecated(since = "5.0.0")
-    public static <E, T, U extends T, V extends T> T inject(E[] self, U initialValue, @ClosureParams(value=FromString.class,options="U,E") Closure<V> closure) {
+    public static <E, T, U extends T, V extends T> T inject(E[] self, U initialValue, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         return ArrayGroovyMethods.inject(self, initialValue, closure);
     }
 
     @Deprecated(since = "5.0.0")
-    public static <E, T, U extends T, V extends T> T inject(Collection<E> self, U initialValue, @ClosureParams(value=FromString.class,options="U,E") Closure<V> closure) {
+    public static <E, T, U extends T, V extends T> T inject(Collection<E> self, U initialValue, @ClosureParams(value=FromString.class,options="T,E") Closure<V> closure) {
         return inject((Iterable<E>) self, initialValue, closure);
     }
 
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index e21e84ba3d..e1095a64d1 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -4037,7 +4037,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
     }
 
     // GROOVY-5893
-    void testPlusInClosure() {
+    void testPlusInClosure1() {
         for (type in ['def', 'var', 'Object', 'Number', 'Integer', 'Comparable']) {
             assertScript """
                 List<Integer> list = [1, 2, 3]
@@ -4051,7 +4051,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
                 assert sum == 6
 
                 $type  sumViaInject = list.inject(0, { int x, int y -> x + y })
-                //     ^^^^^^^^^^^^ T ^^^^ E[]    ^ U      ^ U    ^ E  ^^^^^ V
+                //     ^^^^^^^^^^^^ T ^^^^ E[]    ^ U      ^ T    ^ E  ^^^^^ V
                 assert sumViaInject == 6
             """
         }


(groovy) 02/02: GROOVY-11213: array `indexOf` and `lastIndexOf`

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 63c4682474416f04f8637c53f506dca362773ffb
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Nov 23 10:24:41 2023 -0600

    GROOVY-11213: array `indexOf` and `lastIndexOf`
---
 .../groovy/runtime/ArrayGroovyMethods.java         | 54 ++++++++++++++++++++
 .../groovy/runtime/DefaultGroovyMethods.java       | 58 +++++++++++-----------
 2 files changed, 83 insertions(+), 29 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
index 753702412a..54c2acb443 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayGroovyMethods.java
@@ -4318,6 +4318,33 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return self[0];
     }
 
+    //--------------------------------------------------------------------------
+    // indexOf
+
+    /**
+     * Returns the index of the first occurrence of the specified element in the
+     * array. That is, the lowest index {@code i} such that
+     * {@code Objects.equals(array[i], object)} or -1 if there is no such index.
+     *
+     * <pre class="groovyTestCase">
+     * String[] array = ['foo','bar','foo']
+     * assert array.indexOf('foo') ==  0
+     * assert array.indexOf('bar') ==  1
+     * assert array.indexOf('baz') == -1
+     * assert array.indexOf(12345) == -1
+     * </pre>
+     *
+     * @since 5.0.0
+     */
+    public static int indexOf(Object[] self, Object object) {
+        for (int i = 0; i < self.length; i += 1) {
+            if (Objects.equals(self[i], object)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     //--------------------------------------------------------------------------
     // indexed
 
@@ -5104,6 +5131,33 @@ public class ArrayGroovyMethods extends DefaultGroovyMethodsSupport {
         return self[self.length - 1];
     }
 
+    //--------------------------------------------------------------------------
+    // lastIndexOf
+
+    /**
+     * Returns the index of the last occurrence of the specified element in the
+     * array. That is, the highest index {@code i} such that
+     * {@code Objects.equals(array[i], object)} or -1 if there is no such index.
+     *
+     * <pre class="groovyTestCase">
+     * String[] array = ['foo','bar','foo']
+     * assert array.lastIndexOf('foo') ==  2
+     * assert array.lastIndexOf('bar') ==  1
+     * assert array.lastIndexOf('baz') == -1
+     * assert array.lastIndexOf(12345) == -1
+     * </pre>
+     *
+     * @since 5.0.0
+     */
+    public static int lastIndexOf(Object[] self, Object object) {
+        for (int i = self.length - 1; i >= 0; i -= 1) {
+            if (Objects.equals(self[i], object)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     //--------------------------------------------------------------------------
     // max
 
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 6c07882d8f..2bf5658e85 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -4492,6 +4492,35 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return true;
     }
 
+    //--------------------------------------------------------------------------
+    // equalsIgnoreZeroSign
+
+    /**
+     * Compares this object against the specified object returning the same result
+     * as {@link Float#equals(Object)} but returning true if this object
+     * and the specified object are both zero and negative zero respectively or vice versa.
+     *
+     * @since 3.0.8
+     */
+    public static boolean equalsIgnoreZeroSign(Float number, Object other) {
+        if (other instanceof Float && 0.0f == number && 0.0f == (Float) other)
+            return true;
+        return number.equals(other);
+    }
+
+    /**
+     * Compares this object against the specified object returning the same result
+     * as {@link Double#equals(Object)} but returning true if this object
+     * and the specified object are both zero and negative zero respectively or vice versa.
+     *
+     * @since 3.0.8
+     */
+    public static boolean equalsIgnoreZeroSign(Double number, Object other) {
+        if (other instanceof Double && 0.0d == number && 0.0d == (Double) other)
+            return true;
+        return number.equals(other);
+    }
+
     //--------------------------------------------------------------------------
     // every
 
@@ -4601,35 +4630,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return true;
     }
 
-    //--------------------------------------------------------------------------
-    // equalsIgnoreZeroSign
-
-    /**
-     * Compares this object against the specified object returning the same result
-     * as {@link Float#equals(Object)} but returning true if this object
-     * and the specified object are both zero and negative zero respectively or vice versa.
-     *
-     * @since 3.0.8
-     */
-    public static boolean equalsIgnoreZeroSign(Float number, Object other) {
-        if (other instanceof Float && 0.0f == number && 0.0f == (Float) other)
-            return true;
-        return number.equals(other);
-    }
-
-    /**
-     * Compares this object against the specified object returning the same result
-     * as {@link Double#equals(Object)} but returning true if this object
-     * and the specified object are both zero and negative zero respectively or vice versa.
-     *
-     * @since 3.0.8
-     */
-    public static boolean equalsIgnoreZeroSign(Double number, Object other) {
-        if (other instanceof Double && 0.0d == number && 0.0d == (Double) other)
-            return true;
-        return number.equals(other);
-    }
-
     //--------------------------------------------------------------------------
     // find