You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2022/09/17 08:57:04 UTC

[groovy] branch GROOVY_4_0_X updated: GROOVY-7976, GROOVY-7992: DGM: `Comparator` for parameters

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

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


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new 103c03c7b9 GROOVY-7976, GROOVY-7992: DGM: `Comparator<? super T>` for parameters
103c03c7b9 is described below

commit 103c03c7b9ae54db4ae95402e68bfca8050f7f28
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Sep 2 21:22:00 2022 -0500

    GROOVY-7976, GROOVY-7992: DGM: `Comparator<? super T>` for parameters
    
    (cherry picked from commit 628872aef10cf1454e49973fc5d08c611f620e5a)
---
 .../groovy/runtime/DefaultGroovyMethods.java       | 54 +++++++++++-----------
 .../stc/DefaultGroovyMethodsSTCTest.groovy         | 29 ++++++++++++
 2 files changed, 56 insertions(+), 27 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index c5e9b65a92..6c7e5edb75 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -1549,7 +1549,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the modified Iterator
      * @since 1.5.5
      */
-    public static <T> Iterator<T> unique(Iterator<T> self, Comparator<T> comparator) {
+    public static <T> Iterator<T> unique(Iterator<T> self, Comparator<? super T> comparator) {
         return uniqueItems(new IteratorIterableAdapter<>(self), comparator).listIterator();
     }
 
@@ -1613,7 +1613,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #unique(java.util.Collection, boolean, java.util.Comparator)
      * @since 1.0
      */
-    public static <T> Collection<T> unique(Collection<T> self, Comparator<T> comparator) {
+    public static <T> Collection<T> unique(Collection<T> self, Comparator<? super T> comparator) {
         return unique(self, true, comparator) ;
     }
 
@@ -1664,7 +1664,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #unique(java.util.Collection, boolean, java.util.Comparator)
      * @since 2.4.0
      */
-    public static <T> List<T> unique(List<T> self, Comparator<T> comparator) {
+    public static <T> List<T> unique(List<T> self, Comparator<? super T> comparator) {
         return (List<T>) unique((Collection<T>) self, true, comparator);
     }
 
@@ -1715,7 +1715,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return self      the collection without duplicates
      * @since 1.8.1
      */
-    public static <T> Collection<T> unique(Collection<T> self, boolean mutate, Comparator<T> comparator) {
+    public static <T> Collection<T> unique(Collection<T> self, boolean mutate, Comparator<? super T> comparator) {
         List<T> answer = uniqueItems(self, comparator);
         if (mutate) {
             self.clear();
@@ -1724,7 +1724,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         return mutate ? self : answer;
     }
 
-    private static <T> List<T> uniqueItems(Iterable<T> self, Comparator<T> comparator) {
+    private static <T> List<T> uniqueItems(Iterable<T> self, Comparator<? super T> comparator) {
         List<T> answer = new ArrayList<>();
         for (T t : self) {
             boolean duplicated = false;
@@ -1787,7 +1787,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return self      the List without duplicates
      * @since 2.4.0
      */
-    public static <T> List<T> unique(List<T> self, boolean mutate, Comparator<T> comparator) {
+    public static <T> List<T> unique(List<T> self, boolean mutate, Comparator<? super T> comparator) {
         return (List<T>) unique((Collection<T>) self, mutate, comparator);
     }
 
@@ -1827,9 +1827,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         private boolean exhausted;
         private E next;
 
-        private ToUniqueIterator(Iterator<E> delegate, Comparator<E> comparator) {
+        private ToUniqueIterator(Iterator<E> delegate, Comparator<? super E> comparator) {
+            this.seen = new TreeSet<>(comparator);
             this.delegate = delegate;
-            seen = new TreeSet<>(comparator);
             advance();
         }
 
@@ -1874,7 +1874,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return an Iterator with no duplicate items
      * @since 2.4.0
      */
-    public static <T> Iterator<T> toUnique(Iterator<T> self, Comparator<T> comparator) {
+    public static <T> Iterator<T> toUnique(Iterator<T> self, Comparator<? super T> comparator) {
         return new ToUniqueIterator<>(self, comparator);
     }
 
@@ -1935,7 +1935,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the Collection of non-duplicate items
      * @since 2.4.0
      */
-    public static <T> Collection<T> toUnique(Iterable<T> self, Comparator<T> comparator) {
+    public static <T> Collection<T> toUnique(Iterable<T> self, Comparator<? super T> comparator) {
         Collection<T> result = createSimilarCollection(self);
         addAll(result, toUnique(self.iterator(), comparator));
         return result;
@@ -1986,7 +1986,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the List of non-duplicate items
      * @since 2.4.0
      */
-    public static <T> List<T> toUnique(List<T> self, Comparator<T> comparator) {
+    public static <T> List<T> toUnique(List<T> self, Comparator<? super T> comparator) {
         return (List<T>) toUnique((Iterable<T>) self, comparator);
     }
 
@@ -2129,7 +2129,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      *        If {@code null}, the Comparable natural ordering of the elements will be used.
      * @return the unique items from the array
      */
-    public static <T> T[] toUnique(T[] self, Comparator<T> comparator) {
+    public static <T> T[] toUnique(T[] self, Comparator<? super T> comparator) {
         Collection<T> items = toUnique(new ArrayIterable<>(self), comparator);
         return items.toArray(createSimilarArray(self, items.size()));
     }
@@ -7010,7 +7010,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #min(Iterator, java.util.Comparator)
      * @since 2.2.0
      */
-    public static <T> T min(Iterable<T> self, Comparator<T> comparator) {
+    public static <T> T min(Iterable<T> self, Comparator<? super T> comparator) {
         return min(self.iterator(), comparator);
     }
 
@@ -7022,7 +7022,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the minimum value
      * @since 1.5.5
      */
-    public static <T> T min(Iterator<T> self, Comparator<T> comparator) {
+    public static <T> T min(Iterator<T> self, Comparator<? super T> comparator) {
         T answer = null;
         boolean first = true;
         while (self.hasNext()) {
@@ -7046,7 +7046,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #min(Iterator, java.util.Comparator)
      * @since 1.5.5
      */
-    public static <T> T min(T[] self, Comparator<T> comparator) {
+    public static <T> T min(T[] self, Comparator<? super T> comparator) {
         return min(new ArrayIterator<>(self), comparator);
     }
 
@@ -7451,7 +7451,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #max(Iterator, Comparator)
      * @since 2.2.0
      */
-    public static <T> T max(Iterable<T> self, Comparator<T> comparator) {
+    public static <T> T max(Iterable<T> self, Comparator<? super T> comparator) {
         return max(self.iterator(), comparator);
     }
 
@@ -7463,7 +7463,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the maximum value
      * @since 1.5.5
      */
-    public static <T> T max(Iterator<T> self, Comparator<T> comparator) {
+    public static <T> T max(Iterator<T> self, Comparator<? super T> comparator) {
         T answer = null;
         while (self.hasNext()) {
             T value = self.next();
@@ -7483,7 +7483,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @see #max(Iterator, Comparator)
      * @since 1.5.5
      */
-    public static <T> T max(T[] self, Comparator<T> comparator) {
+    public static <T> T max(T[] self, Comparator<? super T> comparator) {
         return max(new ArrayIterator<>(self), comparator);
     }
 
@@ -9614,7 +9614,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return a sorted List
      * @since 2.4.0
      */
-    public static <T> List<T> toSorted(Iterable<T> self, Comparator<T> comparator) {
+    public static <T> List<T> toSorted(Iterable<T> self, Comparator<? super T> comparator) {
         List<T> list = toList(self);
         list.sort(comparator);
         return list;
@@ -9673,7 +9673,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the sorted items as an Iterator
      * @since 2.4.0
      */
-    public static <T> Iterator<T> toSorted(Iterator<T> self, Comparator<T> comparator) {
+    public static <T> Iterator<T> toSorted(Iterator<T> self, Comparator<? super T> comparator) {
         return toSorted(toList(self), comparator).listIterator();
     }
 
@@ -9727,7 +9727,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the sorted array
      * @since 2.4.0
      */
-    public static <T> T[] toSorted(T[] self, Comparator<T> comparator) {
+    public static <T> T[] toSorted(T[] self, Comparator<? super T> comparator) {
         T[] answer = self.clone();
         Arrays.sort(answer, comparator);
         return answer;
@@ -12932,7 +12932,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return a Collection as an intersection of both collections
      * @since 2.5.0
      */
-    public static <T> Collection<T> intersect(Collection<T> left, Collection<T> right, Comparator<T> comparator) {
+    public static <T> Collection<T> intersect(Collection<T> left, Collection<T> right, Comparator<? super T> comparator) {
         if (left.isEmpty() || right.isEmpty())
             return createSimilarCollection(left, 0);
 
@@ -12982,7 +12982,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return a Collection as an intersection of both iterables
      * @since 2.5.0
      */
-    public static <T> Collection<T> intersect(Iterable<T> left, Iterable<T> right, Comparator<T> comparator) {
+    public static <T> Collection<T> intersect(Iterable<T> left, Iterable<T> right, Comparator<? super T> comparator) {
         return intersect(asCollection(left), asCollection(right), comparator);
     }
 
@@ -13048,7 +13048,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return a List as an intersection of a List and an Iterable
      * @since 2.5.0
      */
-    public static <T> List<T> intersect(List<T> left, Iterable<T> right, Comparator<T> comparator) {
+    public static <T> List<T> intersect(List<T> left, Iterable<T> right, Comparator<? super T> comparator) {
         return (List<T>) intersect((Collection<T>) left, asCollection(right), comparator);
     }
 
@@ -13084,7 +13084,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return a Set as an intersection of a Set and an Iterable
      * @since 2.5.0
      */
-    public static <T> Set<T> intersect(Set<T> left, Iterable<T> right, Comparator<T> comparator) {
+    public static <T> Set<T> intersect(Set<T> left, Iterable<T> right, Comparator<? super T> comparator) {
         return (Set<T>) intersect((Collection<T>) left, asCollection(right), comparator);
     }
 
@@ -13120,7 +13120,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return a Set as an intersection of a SortedSet and an Iterable
      * @since 2.5.0
      */
-    public static <T> SortedSet<T> intersect(SortedSet<T> left, Iterable<T> right, Comparator<T> comparator) {
+    public static <T> SortedSet<T> intersect(SortedSet<T> left, Iterable<T> right, Comparator<? super T> comparator) {
         return (SortedSet<T>) intersect((Collection<T>) left, asCollection(right), comparator);
     }
 
@@ -13718,7 +13718,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 4.0.0
      */
     @SuppressWarnings("unchecked")
-    public static <T> Collection<T> minus(Iterable<T> self, Iterable<?> removeMe, Comparator<T> comparator) {
+    public static <T> Collection<T> minus(Iterable<T> self, Iterable<?> removeMe, Comparator<? super T> comparator) {
         Collection<T> self1 = asCollection(self);
         Collection<?> removeMe1 = asCollection(removeMe);
         Collection<T> ansCollection = createSimilarCollection(self1);
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index dc30227909..9aeb54e547 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -18,6 +18,8 @@
  */
 package groovy.transform.stc
 
+import groovy.test.NotYetImplemented
+
 /**
  * Unit tests for static type checking : default groovy methods.
  */
@@ -218,6 +220,33 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-7976, GROOVY-7992
+    void testSortMethodsWithComparatorAcceptingSuperclass() {
+        assertScript '''
+            List<Number> numbers = [2,1,3]
+            numbers.sort(new Comparator<Object>() {
+                int compare(o1, o2) {
+                    o1.toString() <=> o2.toString()
+                }
+            })
+            assert numbers == [1,2,3]
+        '''
+    }
+
+    @NotYetImplemented // GROOVY-7992
+    void testMaxWithComparatorAcceptingSuperclass() {
+        assertScript '''
+            List<Number> numbers = [1,2,3]
+            // Cannot assign value of type Object to variable of type Number
+            Number highest = numbers.max(new Comparator<Object>() {
+                int compare(o1, o2) {
+                    o1.hashCode() <=> o2.hashCode()
+                }
+            })
+            assert highest == 3
+        '''
+    }
+
     // GROOVY-8205
     void testEachOnEnumValues() {
         assertScript '''