GROOVY-7976: Sort methods that accept a comparator should accept Comparator<? super T> (fix DGM signatures - closes #454)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/ea792ff7 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/ea792ff7 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/ea792ff7 Branch: refs/heads/GROOVY_2_4_X Commit: ea792ff7c49a24986142f3917233f63a2905222e Parents: 9d5de4f Author: paulk <[email protected]> Authored: Mon Oct 31 18:10:30 2016 +1000 Committer: paulk <[email protected]> Committed: Mon Nov 7 10:08:52 2016 +1000 ---------------------------------------------------------------------- .../groovy/runtime/DefaultGroovyMethods.java | 10 +++---- .../stc/DefaultGroovyMethodsSTCTest.groovy | 28 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/ea792ff7/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 11f3d57..39c1cb0 100644 --- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java +++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java @@ -8147,7 +8147,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return the sorted map * @since 1.7.2 */ - public static <K, V> Map<K, V> sort(Map<K, V> self, Comparator<K> comparator) { + public static <K, V> Map<K, V> sort(Map<K, V> self, Comparator<? super K> comparator) { Map<K, V> result = new TreeMap<K, V>(comparator); result.putAll(self); return result; @@ -8231,7 +8231,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return the sorted items as an Iterator * @since 1.5.5 */ - public static <T> Iterator<T> sort(Iterator<T> self, Comparator<T> comparator) { + public static <T> Iterator<T> sort(Iterator<T> self, Comparator<? super T> comparator) { return sort((Iterable<T>) toList(self), true, comparator).listIterator(); } @@ -8275,7 +8275,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return a sorted List * @since 2.2.0 */ - public static <T> List<T> sort(Iterable<T> self, boolean mutate, Comparator<T> comparator) { + public static <T> List<T> sort(Iterable<T> self, boolean mutate, Comparator<? super T> comparator) { List<T> list = mutate ? asList(self) : toList(self); Collections.sort(list, comparator); return list; @@ -8289,7 +8289,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return the sorted array * @since 1.5.5 */ - public static <T> T[] sort(T[] self, Comparator<T> comparator) { + public static <T> T[] sort(T[] self, Comparator<? super T> comparator) { return sort(self, true, comparator); } @@ -8312,7 +8312,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport { * @return a sorted array * @since 1.8.1 */ - public static <T> T[] sort(T[] self, boolean mutate, Comparator<T> comparator) { + public static <T> T[] sort(T[] self, boolean mutate, Comparator<? super T> comparator) { T[] answer = mutate ? self : self.clone(); Arrays.sort(answer, comparator); return answer; http://git-wip-us.apache.org/repos/asf/groovy/blob/ea792ff7/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 4adf2ff..e16a4a4 100644 --- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy +++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy @@ -132,5 +132,33 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase { assert !'abc'.allWhitespace ''' } + + // GROOVY-7976 + void testSortMethodsWithComparatorAcceptingSubclass() { + assertScript ''' + class SecondLetterComparator implements Comparator<? extends CharSequence> { + int compare(CharSequence cs1, CharSequence cs2) { + cs1.charAt(1) <=> cs2.charAt(1) + } + } + + def orig1 = ['ant', 'rat', 'bug', 'dog'] + def sorted1 = orig1.sort(false, new SecondLetterComparator()) + assert orig1 == ['ant', 'rat', 'bug', 'dog'] + assert sorted1 == ['rat', 'ant', 'dog', 'bug'] + + String[] orig2 = ['ant', 'rat', 'bug', 'dog'] + def sorted2 = orig2.sort(false, new SecondLetterComparator()) + assert orig2 == ['ant', 'rat', 'bug', 'dog'] + assert sorted2 == ['rat', 'ant', 'dog', 'bug'] + orig2.sort(new SecondLetterComparator()) + assert orig2 == ['rat', 'ant', 'dog', 'bug'] + + def orig3 = [ant:5, rat:10, bug:15, dog:20] + def sorted3 = orig3.sort(new SecondLetterComparator()) + assert orig3 == [ant:5, rat:10, bug:15, dog:20] + assert sorted3*.value == [10, 5, 20, 15] + ''' + } }
