[1/4] groovy git commit: GROOVY-8545: DGM#intersect(Set, Iterable) throws ClassCastException if Iterable is larger than Set (closes #645)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[1/4] groovy git commit: GROOVY-8545: DGM#intersect(Set, Iterable) throws ClassCastException if Iterable is larger than Set (closes #645)

paulk
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_6_X 00cc9e5e5 -> a7e5722be


GROOVY-8545: DGM#intersect(Set, Iterable) throws ClassCastException if Iterable is larger than Set (closes #645)


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

Branch: refs/heads/GROOVY_2_6_X
Commit: 01449f0e6b2ac72f1bab14ff296c7f38b886a3f0
Parents: 00cc9e5
Author: Hugues Lerebours <[hidden email]>
Authored: Tue Dec 19 18:37:56 2017 +0100
Committer: Paul King <[hidden email]>
Committed: Mon Apr 16 15:35:46 2018 +1000

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethods.java         | 10 ++--------
 src/test/groovy/GroovyMethodsTest.groovy             | 15 ++++++++++++---
 .../shell/completion/ImportsSyntaxCompletor.groovy   |  6 +++---
 3 files changed, 17 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/01449f0e/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 07b7c25..a52abf9 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -12224,18 +12224,12 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
         if (left.isEmpty() || right.isEmpty())
             return createSimilarCollection(left, 0);
 
-        if (left.size() < right.size()) {
-            Collection<T> swaptemp = left;
-            left = right;
-            right = swaptemp;
-        }
-
         // TODO optimise if same type?
         // boolean nlgnSort = sameType(new Collection[]{left, right});
 
-        Collection<T> result = createSimilarCollection(left, left.size());
+        Collection<T> result = createSimilarCollection(left, Math.min(left.size(), right.size()));
         //creates the collection to look for values.
-        Collection<T> pickFrom = new TreeSet<T>(new NumberAwareComparator<T>());
+        Collection<T> pickFrom = new TreeSet<>(new NumberAwareComparator<>());
         pickFrom.addAll(left);
 
         for (final T t : right) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/01449f0e/src/test/groovy/GroovyMethodsTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/GroovyMethodsTest.groovy b/src/test/groovy/GroovyMethodsTest.groovy
index 7f550af..903ea02 100644
--- a/src/test/groovy/GroovyMethodsTest.groovy
+++ b/src/test/groovy/GroovyMethodsTest.groovy
@@ -809,10 +809,10 @@ class GroovyMethodsTest extends GroovyTestCase {
     }
 
     void doIt(col) {
-        col.clear();
-        col.addAll(leftCol);
+        col.clear()
+        col.addAll(leftCol)
         // not really concerned about  correctness, rather that the method can be called, however..
-        assert col.intersect(rightCol) == ["2"]
+        assert col.intersect(rightCol) as List == ["2"]
     }
 
     void testFileWithReader() {
@@ -1565,6 +1565,15 @@ class GroovyMethodsTest extends GroovyTestCase {
         assert [4, 5] == iterableA.intersect(iterableB)
     }
 
+    void testIntersectForSets() {
+        assert [].toSet() == [].toSet().intersect([] as Iterable)
+        assert [].toSet() == [].toSet().intersect([1, 2, 3] as Iterable)
+        assert [].toSet() == [1, 2, 3].toSet().intersect([] as Iterable)
+        assert [2, 3].toSet() == [2, 3, 4].toSet().intersect([1, 2, 3] as Iterable)
+        assert [2, 3, 4].toSet() == [2, 3, 4].toSet().intersect([1, 2, 3, 4] as Iterable)
+        assert [2, 3].toSet() == [2, 3, 4, 5].toSet().intersect([1, 2, 3] as Iterable)
+    }
+
     void testIntersectForMaps() {
         // GROOVY-7602
         def list1 = [[language: 'Java'], [language: 'Groovy'], [language: 'Scala']]

http://git-wip-us.apache.org/repos/asf/groovy/blob/01449f0e/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
index cb446a6..67c9b22 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
@@ -105,12 +105,12 @@ class ImportsSyntaxCompletor implements IdentifierCompletor {
                 Class clazz = shell.interp.evaluate([className]) as Class
                 if (clazz != null) {
                     List<String> clazzSymbols = ReflectionCompletor.getPublicFieldsAndMethods(clazz, '')*.value
-                    List<String> importedSymbols;
+                    Collection<String> importedSymbols
                     if (symbolName == '*') {
-                        importedSymbols = clazzSymbols;
+                        importedSymbols = clazzSymbols
                     } else {
                         Set<String> acceptableMatches = [symbolName, symbolName + '(', symbolName + '()']
-                        importedSymbols = acceptableMatches.intersect(clazzSymbols)
+                        importedSymbols = (acceptableMatches as Collection).intersect(clazzSymbols)
                     }
                     matches.addAll(importedSymbols)
                 }

Reply | Threaded
Open this post in threaded view
|

[2/4] groovy git commit: GROOVY-8548: DGM#intersect should provide a variant with a comparator

paulk
GROOVY-8548: DGM#intersect should provide a variant with a comparator


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

Branch: refs/heads/GROOVY_2_6_X
Commit: cd88364c9b1f0eacc17bad23052f7921396da584
Parents: 01449f0
Author: Paul King <[hidden email]>
Authored: Mon Apr 16 13:59:10 2018 +1000
Committer: Paul King <[hidden email]>
Committed: Mon Apr 16 15:35:47 2018 +1000

----------------------------------------------------------------------
 .../groovy/runtime/DefaultGroovyMethods.java    | 112 ++++++++++++++++++-
 1 file changed, 106 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/cd88364c/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index a52abf9..4d4e3f6 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -12212,24 +12212,51 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Create a Collection composed of the intersection of both collections.  Any
      * elements that exist in both collections are added to the resultant collection.
-     * For collection of custom objects; objects should implement java.lang.Comparable
+     * For collections of custom objects; the objects should implement java.lang.Comparable
      * <pre class="groovyTestCase">assert [4,5] == [1,2,3,4,5].intersect([4,5,6,7,8])</pre>
+     * By default, Groovy uses a {@link NumberAwareComparator} when determining if an
+     * element exists in both collections.
      *
      * @param left  a Collection
      * @param right a Collection
      * @return a Collection as an intersection of both collections
+     * @see #intersect(Collection, Collection, Comparator)
      * @since 1.5.6
      */
     public static <T> Collection<T> intersect(Collection<T> left, Collection<T> right) {
+        return intersect(left, right, new NumberAwareComparator<>());
+    }
+
+    /**
+     * Create a Collection composed of the intersection of both collections.  Any
+     * elements that exist in both collections are added to the resultant collection.
+     * For collections of custom objects; the objects should implement java.lang.Comparable
+     * <pre class="groovyTestCase">
+     * assert [3,4] == [1,2,3,4].intersect([3,4,5,6], Comparator.naturalOrder())
+     * </pre>
+     * <pre class="groovyTestCase">
+     * def one = ['a', 'B', 'c', 'd']
+     * def two = ['b', 'C', 'd', 'e']
+     * def compareIgnoreCase = { a, b -> a.toLowerCase() <=> b.toLowerCase() }
+     * assert one.intersect(two) == ['d']
+     * assert two.intersect(one) == ['d']
+     * assert one.intersect(two, compareIgnoreCase) == ['b', 'C', 'd']
+     * assert two.intersect(one, compareIgnoreCase) == ['B', 'c', 'd']
+     * </pre>
+     *
+     * @param left  a Collection
+     * @param right a Collection
+     * @param comparator a Comparator
+     * @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) {
         if (left.isEmpty() || right.isEmpty())
             return createSimilarCollection(left, 0);
 
-        // TODO optimise if same type?
-        // boolean nlgnSort = sameType(new Collection[]{left, right});
-
         Collection<T> result = createSimilarCollection(left, Math.min(left.size(), right.size()));
         //creates the collection to look for values.
-        Collection<T> pickFrom = new TreeSet<>(new NumberAwareComparator<>());
+        Collection<T> pickFrom = new TreeSet<T>(comparator);
         pickFrom.addAll(left);
 
         for (final T t : right) {
@@ -12242,12 +12269,15 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Create a Collection composed of the intersection of both iterables.  Any
      * elements that exist in both iterables are added to the resultant collection.
-     * For collection of custom objects; objects should implement java.lang.Comparable
+     * For iterables of custom objects; the objects should implement java.lang.Comparable
      * <pre class="groovyTestCase">assert [4,5] == [1,2,3,4,5].intersect([4,5,6,7,8])</pre>
+     * By default, Groovy uses a {@link NumberAwareComparator} when determining if an
+     * element exists in both collections.
      *
      * @param left  an Iterable
      * @param right an Iterable
      * @return a Collection as an intersection of both iterables
+     * @see #intersect(Iterable, Iterable, Comparator)
      * @since 2.4.0
      */
     public static <T> Collection<T> intersect(Iterable<T> left, Iterable<T> right) {
@@ -12255,13 +12285,32 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Create a Collection composed of the intersection of both iterables.  Any
+     * elements that exist in both iterables are added to the resultant collection.
+     * For iterables of custom objects; the objects should implement java.lang.Comparable
+     * <pre class="groovyTestCase">assert [3,4] == [1,2,3,4].intersect([3,4,5,6], Comparator.naturalOrder())</pre>
+     *
+     * @param left  an Iterable
+     * @param right an Iterable
+     * @param comparator a Comparator
+     * @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) {
+        return intersect(asCollection(left), asCollection(right), comparator);
+    }
+
+    /**
      * Create a List composed of the intersection of a List and an Iterable.  Any
      * elements that exist in both iterables are added to the resultant collection.
      * <pre class="groovyTestCase">assert [4,5] == [1,2,3,4,5].intersect([4,5,6,7,8])</pre>
+     * By default, Groovy uses a {@link NumberAwareComparator} when determining if an
+     * element exists in both collections.
      *
      * @param left  a List
      * @param right an Iterable
      * @return a List as an intersection of a List and an Iterable
+     * @see #intersect(List, Iterable, Comparator)
      * @since 2.4.0
      */
     public static <T> List<T> intersect(List<T> left, Iterable<T> right) {
@@ -12269,13 +12318,31 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Create a List composed of the intersection of a List and an Iterable.  Any
+     * elements that exist in both iterables are added to the resultant collection.
+     * <pre class="groovyTestCase">assert [3,4] == [1,2,3,4].intersect([3,4,5,6])</pre>
+     *
+     * @param left  a List
+     * @param right an Iterable
+     * @param comparator a Comparator
+     * @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) {
+        return (List<T>) intersect((Collection<T>) left, asCollection(right), comparator);
+    }
+
+    /**
      * Create a Set composed of the intersection of a Set and an Iterable.  Any
      * elements that exist in both iterables are added to the resultant collection.
      * <pre class="groovyTestCase">assert [4,5] as Set == ([1,2,3,4,5] as Set).intersect([4,5,6,7,8])</pre>
+     * By default, Groovy uses a {@link NumberAwareComparator} when determining if an
+     * element exists in both collections.
      *
      * @param left  a Set
      * @param right an Iterable
      * @return a Set as an intersection of a Set and an Iterable
+     * @see #intersect(Set, Iterable, Comparator)
      * @since 2.4.0
      */
     public static <T> Set<T> intersect(Set<T> left, Iterable<T> right) {
@@ -12283,13 +12350,31 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Create a Set composed of the intersection of a Set and an Iterable.  Any
+     * elements that exist in both iterables are added to the resultant collection.
+     * <pre class="groovyTestCase">assert [3,4] as Set == ([1,2,3,4] as Set).intersect([3,4,5,6], Comparator.naturalOrder())</pre>
+     *
+     * @param left  a Set
+     * @param right an Iterable
+     * @param comparator a Comparator
+     * @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) {
+        return (Set<T>) intersect((Collection<T>) left, asCollection(right), comparator);
+    }
+
+    /**
      * Create a SortedSet composed of the intersection of a SortedSet and an Iterable.  Any
      * elements that exist in both iterables are added to the resultant collection.
      * <pre class="groovyTestCase">assert [4,5] as SortedSet == ([1,2,3,4,5] as SortedSet).intersect([4,5,6,7,8])</pre>
+     * By default, Groovy uses a {@link NumberAwareComparator} when determining if an
+     * element exists in both collections.
      *
      * @param left  a SortedSet
      * @param right an Iterable
      * @return a Set as an intersection of a SortedSet and an Iterable
+     * @see #intersect(SortedSet, Iterable, Comparator)
      * @since 2.4.0
      */
     public static <T> SortedSet<T> intersect(SortedSet<T> left, Iterable<T> right) {
@@ -12297,6 +12382,21 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     }
 
     /**
+     * Create a SortedSet composed of the intersection of a SortedSet and an Iterable.  Any
+     * elements that exist in both iterables are added to the resultant collection.
+     * <pre class="groovyTestCase">assert [4,5] as SortedSet == ([1,2,3,4,5] as SortedSet).intersect([4,5,6,7,8])</pre>
+     *
+     * @param left  a SortedSet
+     * @param right an Iterable
+     * @param comparator a Comparator
+     * @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) {
+        return (SortedSet<T>) intersect((Collection<T>) left, asCollection(right), comparator);
+    }
+
+    /**
      * Create a Map composed of the intersection of both maps.
      * Any entries that exist in both maps are added to the resultant map.
      * <pre class="groovyTestCase">assert [4:4,5:5] == [1:1,2:2,3:3,4:4,5:5].intersect([4:4,5:5,6:6,7:7,8:8])</pre>

Reply | Threaded
Open this post in threaded view
|

[3/4] groovy git commit: GROOVY-8545: DGM#intersect(Set, Iterable) exception (minor refactor)

paulk
In reply to this post by paulk
GROOVY-8545: DGM#intersect(Set, Iterable) exception (minor refactor)


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

Branch: refs/heads/GROOVY_2_6_X
Commit: 835c09d9847c847e54b38605ae577a1c4b1e0312
Parents: cd88364
Author: Paul King <[hidden email]>
Authored: Mon Apr 16 15:34:35 2018 +1000
Committer: Paul King <[hidden email]>
Committed: Mon Apr 16 15:35:47 2018 +1000

----------------------------------------------------------------------
 .../groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/835c09d9/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
index 67c9b22..19a55df 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/completion/ImportsSyntaxCompletor.groovy
@@ -104,13 +104,13 @@ class ImportsSyntaxCompletor implements IdentifierCompletor {
                 String className = importSpec.substring(staticPrefix.length(), lastDotIndex)
                 Class clazz = shell.interp.evaluate([className]) as Class
                 if (clazz != null) {
-                    List<String> clazzSymbols = ReflectionCompletor.getPublicFieldsAndMethods(clazz, '')*.value
+                    Set<String> clazzSymbols = ReflectionCompletor.getPublicFieldsAndMethods(clazz, '')*.value
                     Collection<String> importedSymbols
                     if (symbolName == '*') {
                         importedSymbols = clazzSymbols
                     } else {
                         Set<String> acceptableMatches = [symbolName, symbolName + '(', symbolName + '()']
-                        importedSymbols = (acceptableMatches as Collection).intersect(clazzSymbols)
+                        importedSymbols = acceptableMatches.intersect(clazzSymbols)
                     }
                     matches.addAll(importedSymbols)
                 }

Reply | Threaded
Open this post in threaded view
|

[4/4] groovy git commit: GROOVY-8548: DGM#intersect should provide a variant with a comparator (minor refactor for jdk7 compat)

paulk
In reply to this post by paulk
GROOVY-8548: DGM#intersect should provide a variant with a comparator (minor refactor for jdk7 compat)


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

Branch: refs/heads/GROOVY_2_6_X
Commit: a7e5722bed4ce8770c4fd504c42081b08e5ef9b7
Parents: 835c09d
Author: Paul King <[hidden email]>
Authored: Mon Apr 16 15:37:19 2018 +1000
Committer: Paul King <[hidden email]>
Committed: Mon Apr 16 15:37:19 2018 +1000

----------------------------------------------------------------------
 .../java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java  | 5 -----
 1 file changed, 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/a7e5722b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 4d4e3f6..0902b1e 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -12232,9 +12232,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * elements that exist in both collections are added to the resultant collection.
      * For collections of custom objects; the objects should implement java.lang.Comparable
      * <pre class="groovyTestCase">
-     * assert [3,4] == [1,2,3,4].intersect([3,4,5,6], Comparator.naturalOrder())
-     * </pre>
-     * <pre class="groovyTestCase">
      * def one = ['a', 'B', 'c', 'd']
      * def two = ['b', 'C', 'd', 'e']
      * def compareIgnoreCase = { a, b -> a.toLowerCase() <=> b.toLowerCase() }
@@ -12288,7 +12285,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * Create a Collection composed of the intersection of both iterables.  Any
      * elements that exist in both iterables are added to the resultant collection.
      * For iterables of custom objects; the objects should implement java.lang.Comparable
-     * <pre class="groovyTestCase">assert [3,4] == [1,2,3,4].intersect([3,4,5,6], Comparator.naturalOrder())</pre>
      *
      * @param left  an Iterable
      * @param right an Iterable
@@ -12352,7 +12348,6 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     /**
      * Create a Set composed of the intersection of a Set and an Iterable.  Any
      * elements that exist in both iterables are added to the resultant collection.
-     * <pre class="groovyTestCase">assert [3,4] as Set == ([1,2,3,4] as Set).intersect([3,4,5,6], Comparator.naturalOrder())</pre>
      *
      * @param left  a Set
      * @param right an Iterable