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/23 16:52:28 UTC

[groovy] branch GROOVY_3_0_X updated: GROOVY-8737: STC: no varargs distance for exact match of variadic method

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new f236b6bbce GROOVY-8737: STC: no varargs distance for exact match of variadic method
f236b6bbce is described below

commit f236b6bbcef9b743b51caf37caf0a147c14c35b3
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Aug 23 10:57:45 2022 -0500

    GROOVY-8737: STC: no varargs distance for exact match of variadic method
---
 .../transform/stc/StaticTypeCheckingSupport.java   |  19 +--
 .../groovy/transform/stc/MethodCallsSTCTest.groovy | 147 +++++++++++++--------
 2 files changed, 102 insertions(+), 64 deletions(-)

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 a42203d9b4..0faa278a93 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1075,13 +1075,14 @@ public abstract class StaticTypeCheckingSupport {
     private static int measureParametersAndArgumentsDistance(final Parameter[] parameters, final ClassNode[] argumentTypes) {
         int dist = -1;
         if (parameters.length == argumentTypes.length) {
-            int allPMatch = allParametersAndArgumentsMatch(parameters, argumentTypes);
-            int firstParamDist = firstParametersAndArgumentsMatch(parameters, argumentTypes);
-            int lastArgMatch = isVargs(parameters) && firstParamDist >= 0 ? lastArgMatchesVarg(parameters, argumentTypes) : -1;
-            if (lastArgMatch >= 0) {
-                lastArgMatch += getVarargsDistance(parameters);
+            dist = allParametersAndArgumentsMatch(parameters, argumentTypes);
+            if (isVargs(parameters) && firstParametersAndArgumentsMatch(parameters, argumentTypes) >= 0) {
+                int endDist = lastArgMatchesVarg(parameters, argumentTypes);
+                if (endDist >= 0) {
+                    endDist += getVarargsDistance(parameters);
+                    dist = (dist < 0 ? endDist : Math.min(dist, endDist)); // GROOVY-8737
+                }
             }
-            dist = allPMatch >= 0 ? Math.max(allPMatch, lastArgMatch) : lastArgMatch;
         } else if (isVargs(parameters)) {
             dist = firstParametersAndArgumentsMatch(parameters, argumentTypes);
             if (dist >= 0) {
@@ -1096,10 +1097,10 @@ public abstract class StaticTypeCheckingSupport {
                 if (parameters.length < argumentTypes.length) {
                     // (3) there is more than one argument for the vargs array
                     int excessArgumentsDistance = excessArgumentsMatchesVargsParameter(parameters, argumentTypes);
-                    if (excessArgumentsDistance < 0) {
-                        dist = -1;
-                    } else {
+                    if (excessArgumentsDistance >= 0) {
                         dist += excessArgumentsDistance;
+                    } else {
+                        dist = -1;
                     }
                 }
             }
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index 37aedf213a..4578ac9d20 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -958,7 +958,7 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testVargsSelection() {
+    void testVargsSelection1() {
         assertScript '''
             int foo(int x, Object... args) { 1 }
             int foo(Object... args) { 2 }
@@ -988,6 +988,96 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-6147
+    void testVargsSelection4() {
+        assertScript '''
+            int select(Object a, String s) { 1 }
+            int select(Object a, String s, Object[] args) { 2 }
+            def o = new Date()
+            def s = 'String'
+            @ASTTest(phase=INSTRUCTION_SELECTION,value={
+                def method = node.rightExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
+                assert method.name == 'select'
+                assert method.parameters.length==2
+            })
+            def result = select(o,s)
+            assert result == 1
+        '''
+    }
+
+    // GROOVY-6195
+    void testVargsSelection5() {
+        assertScript '''
+            def list = ['a', 'b', 'c']
+            Object[] arr = list.toArray()
+            println arr
+        '''
+    }
+
+    // GROOVY-6235
+    void testVargsSelection6() {
+        assertScript '''import org.codehaus.groovy.classgen.asm.sc.support.Groovy6235SupportSub as Support
+            def b = new Support()
+            assert b.overload() == 1
+            assert b.overload('a') == 1
+            assert b.overload('a','b') == 2
+        '''
+    }
+
+    // GROOVY-6646
+    void testVargsSelection7() {
+        assertScript '''
+            def foo(Class... cs) { "Classes" }
+            def foo(String... ss) { "Strings" }
+
+            assert foo(List, Map) == "Classes"
+            assert foo("2","1") == "Strings"
+        '''
+        assertScript '''
+            def foo(Class<?>... cs) { "Classes" }
+            def foo(String... ss) { "Strings" }
+
+            assert foo(List, Map) == "Classes"
+            assert foo("2","1") == "Strings"
+        '''
+    }
+
+    // GROOVY-8737
+    void testVargsSelection8() {
+        String methods = '''
+            String m(String key, Object[] args) {
+                "key=$key, args=$args"
+            }
+            String m(String key, Object[] args, Object[] parts) {
+                "key=$key, args=$args, parts=$parts"
+            }
+            String m(String key, Object[] args, String[] names) {
+                "key=$key, args=$args, names=$names"
+            }
+        '''
+        assertScript methods + '''
+            String result = m( 'hello', new Object[]{'world'} ) // exact match for m(String,Object[])
+            assert result == 'key=hello, args=[world]'
+        '''
+        assertScript methods + '''
+            String result = m( 'hello', new String[]{'world'} )
+            assert result == 'key=hello, args=[world]'
+        '''
+        assertScript methods + '''
+            String result = m( "${'hello'}", 'world' )
+            assert result == 'key=hello, args=[world]'
+        '''
+        assertScript methods + '''
+            String result = m( 'hello', 'world' )
+            assert result == 'key=hello, args=[world]'
+        '''
+
+        assertScript methods + '''
+            String result = m( 'hello', new String[]{'there'}, 'Steve' )
+            assert result == 'key=hello, args=[there], names=[Steve]'
+        '''
+    }
+
     // GROOVY-5702
     void testShouldFindInterfaceMethod() {
         assertScript '''
@@ -1169,41 +1259,6 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    // GROOVY-6147
-    void testVargsCallWithOverloadedMethod() {
-        assertScript '''
-            int select(Object a, String s) { 1 }
-            int select(Object a, String s, Object[] args) { 2 }
-            def o = new Date()
-            def s = 'String'
-            @ASTTest(phase=INSTRUCTION_SELECTION,value={
-                def method = node.rightExpression.getNodeMetaData(DIRECT_METHOD_CALL_TARGET)
-                assert method.name == 'select'
-                assert method.parameters.length==2
-            })
-            def result = select(o,s)
-            assert result == 1
-        '''
-    }
-
-    // GROOVY-6195
-    void testShouldNotThrowAmbiguousVargs() {
-        assertScript '''
-            def list = ['a', 'b', 'c']
-            Object[] arr = list.toArray()
-            println arr
-        '''
-    }
-
-    void testOverloadedMethodWithVargs() {
-        assertScript '''import org.codehaus.groovy.classgen.asm.sc.support.Groovy6235SupportSub as Support
-            def b = new Support()
-            assert b.overload() == 1
-            assert b.overload('a') == 1
-            assert b.overload('a','b') == 2
-        '''
-    }
-
     // GROOVY-10720
     void testOverloadedMethodWithArray() {
         assertScript '''
@@ -1246,25 +1301,7 @@ class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
         ''', 'Cannot find matching method java.lang.String#doSomething()'
     }
 
-    // GROOVY-6646
-    void testNPlusVargsCallInOverloadSituation() {
-        assertScript '''
-            def foo(Class... cs) { "Classes" }
-            def foo(String... ss) { "Strings" }
-
-            assert foo(List, Map) == "Classes"
-            assert foo("2","1") == "Strings"
-        '''
-        assertScript '''
-            def foo(Class<?>... cs) { "Classes" }
-            def foo(String... ss) { "Strings" }
-
-            assert foo(List, Map) == "Classes"
-            assert foo("2","1") == "Strings"
-        '''
-    }
-
-    //GROOVY-6776
+    // GROOVY-6776
     void testPrimtiveParameterAndNullArgument() {
         shouldFailWithMessages '''
             def foo(int i){}