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 2021/08/17 19:57:17 UTC

[groovy] 01/02: GROOVY-8111: lowestUpperBound: primitives and self-referential types fix

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

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

commit 6ca7b9122d90908783ff60e7ca60918dab118f9d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jun 1 14:15:26 2021 -0500

    GROOVY-8111: lowestUpperBound: primitives and self-referential types fix
    
    Conflicts:
    	src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
---
 .../groovy/ast/tools/WideningCategories.java       |  3 +-
 .../groovy/ast/tools/WideningCategoriesTest.groovy | 41 ++++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java b/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
index 85cdd76..2682581 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
@@ -267,7 +267,7 @@ public class WideningCategories {
             ClassNode t1 = agt[i].getType();
             ClassNode t2 = bgt[i].getType();
             ClassNode basicType;
-            if (areEqualWithGenerics(t1, a) && areEqualWithGenerics(t2,b)) {
+            if (areEqualWithGenerics(t1, isPrimitiveType(a)?getWrapper(a):a) && areEqualWithGenerics(t2, isPrimitiveType(b)?getWrapper(b):b)) {
                 // we are facing a self referencing type !
                 basicType = fallback;
             } else {
@@ -702,7 +702,6 @@ public class WideningCategories {
                 GenericsType ga = gta[i];
                 GenericsType gb = gtb[i];
                 boolean result = ga.isPlaceholder()==gb.isPlaceholder() && ga.isWildcard()==gb.isWildcard();
-                result = result && ga.isResolved() && gb.isResolved();
                 result = result && ga.getName().equals(gb.getName());
                 result = result && areEqualWithGenerics(ga.getType(), gb.getType());
                 result = result && areEqualWithGenerics(ga.getLowerBound(), gb.getLowerBound());
diff --git a/src/test/org/codehaus/groovy/ast/tools/WideningCategoriesTest.groovy b/src/test/org/codehaus/groovy/ast/tools/WideningCategoriesTest.groovy
index 63b72d6..4be1162 100644
--- a/src/test/org/codehaus/groovy/ast/tools/WideningCategoriesTest.groovy
+++ b/src/test/org/codehaus/groovy/ast/tools/WideningCategoriesTest.groovy
@@ -20,11 +20,11 @@ package org.codehaus.groovy.ast.tools
 
 import org.codehaus.groovy.ast.ClassNode
 import org.codehaus.groovy.ast.GenericsTestCase
-import static org.codehaus.groovy.ast.tools.WideningCategories.*
+
 import static org.codehaus.groovy.ast.ClassHelper.*
-import org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode
+import static org.codehaus.groovy.ast.tools.WideningCategories.*
 
-class WideningCategoriesTest extends GenericsTestCase {
+final class WideningCategoriesTest extends GenericsTestCase {
 
     void testBuildCommonTypeWithNullClassNode() {
         ClassNode a = null
@@ -113,7 +113,6 @@ class WideningCategoriesTest extends GenericsTestCase {
         }
     }
 
-
     void testBuildCommonTypeWithTwoIdenticalClasses() {
         ClassNode a = make(HashSet)
         ClassNode b = make(HashSet)
@@ -176,6 +175,20 @@ class WideningCategoriesTest extends GenericsTestCase {
         assert type.interfaces as Set == [make(Serializable)] as Set
     }
 
+    // GROOVY-8111
+    void testBuildCommonTypeFromTwoClassesWithTwoCommonInterfacesOneIsSelfReferential() {
+        ClassNode a = boolean_TYPE
+        ClassNode b = extractTypesFromCode("${getClass().getName()}.Pair<String,String> type").type
+        ClassNode lub = lowestUpperBound(a, b)
+
+        assert lub.superClass == OBJECT_TYPE
+        assert lub.interfaces as Set == [make(Comparable), make(Serializable)] as Set
+
+        lub = lowestUpperBound(b, a)
+        assert lub.superClass == OBJECT_TYPE
+        assert lub.interfaces as Set == [make(Comparable), make(Serializable)] as Set
+    }
+
     void testStringWithGString() {
         ClassNode a = make(String)
         ClassNode b = make(GString)
@@ -270,7 +283,6 @@ class WideningCategoriesTest extends GenericsTestCase {
         assert genericType == Long_TYPE
     }
 
-
     void testCommonAssignableType() {
         def typeA = extractTypesFromCode('LinkedList type').type
         def typeB = extractTypesFromCode('List type').type
@@ -339,6 +351,7 @@ class WideningCategoriesTest extends GenericsTestCase {
     }
 
     // ---------- Classes and Interfaces used in this unit test ----------------
+
     private static interface InterfaceA {}
     private static interface InterfaceB {}
     private static interface InterfaceE {}
@@ -361,5 +374,21 @@ class WideningCategoriesTest extends GenericsTestCase {
 
     private static class PTop<E> {}
     private static class PTopInt extends PTop<Integer> implements Serializable {}
-    private static class PTopLong extends PTop<Long>  implements Serializable {}
+    private static class PTopLong extends PTop<Long  > implements Serializable {}
+
+    private static class Pair<L,R> implements Map.Entry<L,R>, Comparable<Pair<L,R>>, Serializable {
+        public final L left
+        public final R right
+        private Pair(final L left, final R right) {
+            this.left = left
+            this.right = right
+        }
+        static <L, R> Pair<L, R> of(final L left, final R right) {
+            return new Pair<>(left, right)
+        }
+        L getKey() { left }
+        R getValue() { right }
+        R setValue(R value) { right }
+        int compareTo(Pair<L,R> that) { 0 }
+    }
 }