groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject [groovy] 01/02: GROOVY-7954 Fix equality check in special case (closes #895)
Date Wed, 20 Mar 2019 12:43:00 GMT
This is an automated email from the ASF dual-hosted git repository.

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

commit 74ef3a58426ea0b571acbb27b499391261fc003b
Author: Nicolas Guillaumin <nicolas.guillaumin@zetcom.com>
AuthorDate: Mon Mar 11 17:14:56 2019 +0100

    GROOVY-7954 Fix equality check in special case (closes #895)
    
    Fix equality check with two instances A & B when:
    - A and B implement the same interface but are not of the same class
    - The common interface implements `Comparable`
    
    `DefaultTypeTransformation.compareToWithEqualityCheck(...)` checks for
    assignable classes and use `compareTo()` when assignable on the class
    level, but it doesn't check it on the interface level.
    
    As a result `compareTo()` is not called at the interface level and `-1`
    is returned.  The fix ensures that `compareTo()` is called in this case.
---
 .../typehandling/DefaultTypeTransformation.java    |  5 +-
 .../runtime/typehandling/EqualityTest.groovy       | 12 +++++
 .../typehandling/EqualityTestAbstractClass.java    | 57 ++++++++++++++++++++++
 .../runtime/typehandling/EqualityTestClassA.java   |  9 ++++
 .../runtime/typehandling/EqualityTestClassB.java   |  9 ++++
 .../typehandling/EqualityTestInterface.java        |  6 +++
 6 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
b/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
index f487ad0..e6d5219 100644
--- a/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
+++ b/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
@@ -585,8 +585,9 @@ public class DefaultTypeTransformation {
                 return ((GString) left).compareTo(right);
             }
             if (!equalityCheckOnly || left.getClass().isAssignableFrom(right.getClass())
-                    || (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass()))
//GROOVY-4046
-                    ) {
+                    || (right.getClass() != Object.class && right.getClass().isAssignableFrom(left.getClass())
//GROOVY-4046
+                    || right instanceof Comparable) // GROOVY-7954
+            ) {
                 Comparable comparable = (Comparable) left;
                 // GROOVY-7876: when comparing for equality we try to only call compareTo
when an assignable
                 // relationship holds but with a container/holder class and because of erasure,
we might still end
diff --git a/src/test/groovy/runtime/typehandling/EqualityTest.groovy b/src/test/groovy/runtime/typehandling/EqualityTest.groovy
new file mode 100755
index 0000000..b5d42ba
--- /dev/null
+++ b/src/test/groovy/runtime/typehandling/EqualityTest.groovy
@@ -0,0 +1,12 @@
+package groovy.runtime.typehandling
+
+class EqualityTest extends GroovyTestCase {
+
+    void testEquality() {
+        def classA = new EqualityTestClassA(1, "Test")
+        def classB = new EqualityTestClassB(1, "Test")
+
+        assert classA == classB
+        assert classA.equals(classB)
+    }
+}
diff --git a/src/test/groovy/runtime/typehandling/EqualityTestAbstractClass.java b/src/test/groovy/runtime/typehandling/EqualityTestAbstractClass.java
new file mode 100755
index 0000000..6b5d138
--- /dev/null
+++ b/src/test/groovy/runtime/typehandling/EqualityTestAbstractClass.java
@@ -0,0 +1,57 @@
+package groovy.runtime.typehandling;
+
+public class EqualityTestAbstractClass implements EqualityTestInterface {
+
+    private final int id;
+    private final String value;
+
+    public EqualityTestAbstractClass(int id, String value) {
+        this.id = id;
+        this.value = value;
+    }
+
+    @Override
+    public int getId() {
+        return id;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public int compareTo(EqualityTestInterface other) {
+        if (other == null) {
+            return 1;
+        }
+        if (getValue() == null) {
+            if (other.getValue() == null) {
+                return 0;
+            }
+            return -1;
+        }
+        if (other.getValue() == null) {
+            return 1;
+        }
+        return getValue().compareTo(other.getValue());
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof EqualityTestInterface) {
+            EqualityTestInterface castedOther = (EqualityTestInterface) other;
+            return getId() == castedOther.getId();
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return getId();
+    }
+
+}
diff --git a/src/test/groovy/runtime/typehandling/EqualityTestClassA.java b/src/test/groovy/runtime/typehandling/EqualityTestClassA.java
new file mode 100755
index 0000000..8bfa539
--- /dev/null
+++ b/src/test/groovy/runtime/typehandling/EqualityTestClassA.java
@@ -0,0 +1,9 @@
+package groovy.runtime.typehandling;
+
+public class EqualityTestClassA extends EqualityTestAbstractClass {
+
+    public EqualityTestClassA(int id, String value) {
+        super(id, value);
+    }
+
+}
diff --git a/src/test/groovy/runtime/typehandling/EqualityTestClassB.java b/src/test/groovy/runtime/typehandling/EqualityTestClassB.java
new file mode 100755
index 0000000..7381082
--- /dev/null
+++ b/src/test/groovy/runtime/typehandling/EqualityTestClassB.java
@@ -0,0 +1,9 @@
+package groovy.runtime.typehandling;
+
+public class EqualityTestClassB extends EqualityTestAbstractClass {
+
+    public EqualityTestClassB(int id, String value) {
+        super(id, value);
+    }
+
+}
diff --git a/src/test/groovy/runtime/typehandling/EqualityTestInterface.java b/src/test/groovy/runtime/typehandling/EqualityTestInterface.java
new file mode 100755
index 0000000..4c4ef24
--- /dev/null
+++ b/src/test/groovy/runtime/typehandling/EqualityTestInterface.java
@@ -0,0 +1,6 @@
+package groovy.runtime.typehandling;
+
+public interface EqualityTestInterface extends Comparable<EqualityTestInterface> {
+    int getId();
+    String getValue();
+}


Mime
View raw message