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 2022/08/24 14:48:50 UTC

[groovy] 01/01: GROOVY-6668: STC: reduce distance of `GString` for `String` target

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

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

commit 1e36ab4e77feda5d60cdb81173d4bfe32655fbd4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Aug 18 12:10:41 2022 -0500

    GROOVY-6668: STC: reduce distance of `GString` for `String` target
---
 .../transform/stc/StaticTypeCheckingSupport.java   |  3 ++
 .../transform/stc/StaticTypeCheckingVisitor.java   |  2 +-
 .../stc/DefaultGroovyMethodsSTCTest.groovy         | 42 ++++++++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 847f481294..7ced503cbe 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -923,6 +923,9 @@ public abstract class StaticTypeCheckingSupport {
         if (receiver.isArray() && compare.isArray()) {
             return getDistance(receiver.getComponentType(), compare.getComponentType());
         }
+        if (isGStringOrGStringStringLUB(receiver) && isStringType(compare)) {
+            return 3; // GROOVY-6668: closer than Object and GroovyObjectSupport
+        }
         int dist = 0;
         ClassNode unwrapReceiver = getUnwrapper(receiver);
         ClassNode unwrapCompare = getUnwrapper(compare);
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index d791fddc1c..a4844cb8e8 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4520,7 +4520,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         }
 
         if (isArrayOp(op)) {
-            if (isOrImplements(left, MAP_TYPE) && isStringType(right)) { // GROOVY-5700, GROOVY-8788
+            if (isOrImplements(left, MAP_TYPE) && (isStringType(right) || isGStringOrGStringStringLUB(right))) { // GROOVY-5700, GROOVY-6668, GROOVY-8788
                 PropertyExpression prop = propX(leftExpression, rightExpression); // m['xx'] -> m.xx
                 return existsProperty(prop, !typeCheckingContext.isTargetOfEnclosingAssignment(expr))
                             ? getType(prop) : getTypeForMapPropertyExpression(left, prop);
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index dc30227909..d0df11fddb 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -338,4 +338,46 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
             test()
         '''
     }
+
+    // GROOVY-6668
+    void testMapGetAtVsObjectGetAt2() {
+        assertScript '''
+            Map<String, String> map = [key:'val']
+
+            // no value type inference
+            assert map.getAt('key') == 'val'
+            assert map.getAt("${'key'}") == 'val'
+
+            // yes value type inference
+            assert map['key'].toUpperCase() == 'VAL'
+            assert map["${'key'}"].toUpperCase() == 'VAL'
+
+            assert map.get('key').toUpperCase() == 'VAL'
+            assert map.get("${'key'}")?.toUpperCase() == null // get(Object); no coerce
+        '''
+    }
+
+    // GROOVY-6668
+    void testMapPutAtVsObjectPutAt() {
+        assertScript '''
+            Map<String, String> map = [:]
+
+            map['key'] = 'val'
+            assert map.remove('key') == 'val'
+
+            map["${'key'}"] = 'val'
+            assert map.remove('key') == 'val'
+
+            map.putAt('key','val')
+            assert map.remove('key') == 'val'
+
+            map.putAt("${'key'}",'val')
+            assert map.remove('key') == 'val'
+        '''
+        shouldFailWithMessages '''
+            Map<String, String> map = [:]
+            map.put("${'key'}",'val')
+        ''',
+        'Cannot call java.util.LinkedHashMap#put(java.lang.String, java.lang.String) with arguments [groovy.lang.GString, java.lang.String]'
+    }
 }