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

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


The following commit(s) were added to refs/heads/master by this push:
     new 290cd3f72f GROOVY-8045: support coercion for variadic parameter
290cd3f72f is described below

commit 290cd3f72f381bb2752a14595b1245af81f67c26
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Wed May 25 15:40:57 2022 -0500

    GROOVY-8045: support coercion for variadic parameter
---
 .../codehaus/groovy/reflection/ParameterTypes.java | 123 ++++++++++-----------
 .../groovy/transform/stc/CoercionSTCTest.groovy    |  11 ++
 2 files changed, 69 insertions(+), 65 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java 
b/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java
index 86056e578b..59a745b9a1 100644
--- a/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java
+++ b/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java
@@ -235,19 +235,17 @@ public class ParameterTypes {
         return result;
     }
 
-    public boolean isValidMethod(Class[] arguments) {
-        if (arguments == null) return true;
-
-        final int size = arguments.length;
+    public boolean isValidMethod(Class[] argumentTypes) {
+        if (argumentTypes == null) return true;
         CachedClass[] pt = getParameterTypes();
-        final int paramMinus1 = pt.length - 1;
-
-        if (isVargsMethod && size >= paramMinus1)
-            return isValidVarargsMethod(arguments, size, pt, paramMinus1);
-        else if (pt.length == size)
-            return isValidExactMethod(arguments, pt);
-        else if (pt.length == 1 && size == 0 && !pt[0].isPrimitive)
-            return true;
+        final int nArguments = argumentTypes.length, nParameters = pt.length, 
nthParameter = nParameters - 1;
+
+        if (isVargsMethod && nArguments >= nthParameter)
+            return isValidVargsMethod(argumentTypes, pt, nthParameter);
+        else if (nArguments == nParameters)
+            return isValidExactMethod(argumentTypes, pt);
+        else if (nArguments == 0 && nParameters == 1 && !pt[0].isPrimitive)
+            return true; // implicit null argument
         return false;
     }
 
@@ -292,77 +290,72 @@ public class ParameterTypes {
         return true;
     }
 
-    private static boolean testComponentAssignable(Class toTestAgainst, Class 
toTest) {
-        Class component = toTest.getComponentType();
-        if (component == null) return false;
-        return MetaClassHelper.isAssignableFrom(toTestAgainst, component);
-    }
-
-    private static boolean isValidVarargsMethod(Class[] arguments, int size, 
CachedClass[] pt, int paramMinus1) {
-        // first check normal number of parameters
-        for (int i = 0; i < paramMinus1; i++) {
-            if (pt[i].isAssignableFrom(arguments[i])) continue;
-            return false;
+    private static boolean isValidVargsMethod(Class[] argumentTypes, 
CachedClass[] parameterTypes, int nthParameter) {
+        for (int i = 0; i < nthParameter; i += 1) {
+            if (!parameterTypes[i].isAssignableFrom(argumentTypes[i])) {
+                return false;
+            }
         }
 
+        CachedClass arrayType = parameterTypes[nthParameter];
+        CachedClass componentType = 
ReflectionCache.getCachedClass(arrayType.getTheClass().getComponentType());
+
         // check direct match
-        CachedClass varg = pt[paramMinus1];
-        Class clazz = varg.getTheClass().getComponentType();
-        if (size == pt.length &&
-                (varg.isAssignableFrom(arguments[paramMinus1]) ||
-                        testComponentAssignable(clazz, 
arguments[paramMinus1]))) {
-            return true;
+        if (argumentTypes.length == parameterTypes.length) {
+            Class argumentType = argumentTypes[nthParameter];
+            if (arrayType.isAssignableFrom(argumentType) || 
(argumentType.isArray()
+                    && 
componentType.isAssignableFrom(argumentType.getComponentType()))) {
+                return true;
+            }
         }
 
-        // check varged
-        for (int i = paramMinus1; i < size; i++) {
-            if (MetaClassHelper.isAssignableFrom(clazz, arguments[i])) 
continue;
-            return false;
+        // check vararg match
+        for (int i = nthParameter; i < argumentTypes.length; i += 1) {
+            if (!componentType.isAssignableFrom(argumentTypes[i])) {
+                return false;
+            }
         }
+
         return true;
     }
 
     public boolean isValidMethod(Object[] arguments) {
         if (arguments == null) return true;
-
-        final int size = arguments.length;
-        CachedClass[] paramTypes = getParameterTypes();
-        final int paramMinus1 = paramTypes.length - 1;
-
-        if (size >= paramMinus1 && paramTypes.length > 0 &&
-                paramTypes[(paramMinus1)].isArray) {
-            // first check normal number of parameters
-            for (int i = 0; i < paramMinus1; i++) {
-                if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i]))) 
continue;
-                return false;
+        final CachedClass[] parameterTypes = getParameterTypes();
+        final int nArguments = arguments.length, nParameters = 
parameterTypes.length, nthParameter = nParameters - 1;
+
+        if (nParameters > 0 && parameterTypes[nthParameter].isArray && 
nArguments >= nthParameter) {
+            for (int i = 0; i < nthParameter; i += 1) {
+                if 
(!parameterTypes[i].isAssignableFrom(getArgClass(arguments[i]))) {
+                    return false;
+                }
             }
-
-
+            CachedClass arrayType = parameterTypes[nthParameter];
+            CachedClass componentType = 
ReflectionCache.getCachedClass(arrayType.getTheClass().getComponentType());
             // check direct match
-            CachedClass varg = paramTypes[paramMinus1];
-            Class clazz = varg.getTheClass().getComponentType();
-            if (size == paramTypes.length &&
-                    
(varg.isAssignableFrom(getArgClass(arguments[paramMinus1])) ||
-                            testComponentAssignable(clazz, 
getArgClass(arguments[paramMinus1])))) {
-                return true;
+            if (nArguments == parameterTypes.length) {
+                Class argumentType = getArgClass(arguments[nthParameter]);
+                if (arrayType.isAssignableFrom(argumentType) || 
(argumentType.isArray()
+                        && 
componentType.isAssignableFrom(argumentType.getComponentType()))) {
+                    return true;
+                }
             }
-
-
-            // check varged
-            for (int i = paramMinus1; i < size; i++) {
-                if (MetaClassHelper.isAssignableFrom(clazz, 
getArgClass(arguments[i]))) continue;
-                return false;
+            // check vararg match
+            for (int i = nthParameter; i < nArguments; i += 1) {
+                if 
(!componentType.isAssignableFrom(getArgClass(arguments[i]))) {
+                    return false;
+                }
             }
             return true;
-        } else if (paramTypes.length == size) {
-            // lets check the parameter types match
-            for (int i = 0; i < size; i++) {
-                if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i]))) 
continue;
-                return false;
+        } else if (nArguments == nParameters) {
+            for (int i = 0; i < nArguments; i += 1) {
+                if 
(!parameterTypes[i].isAssignableFrom(getArgClass(arguments[i]))) {
+                    return false;
+                }
             }
             return true;
-        } else if (paramTypes.length == 1 && size == 0 && 
!paramTypes[0].isPrimitive) {
-            return true;
+        } else if (nArguments == 0 && nParameters == 1 && 
!parameterTypes[0].isPrimitive) {
+            return true; // implicit null argument
         }
         return false;
     }
diff --git a/src/test/groovy/transform/stc/CoercionSTCTest.groovy 
b/src/test/groovy/transform/stc/CoercionSTCTest.groovy
index 2c100508b7..35f6a1be2c 100644
--- a/src/test/groovy/transform/stc/CoercionSTCTest.groovy
+++ b/src/test/groovy/transform/stc/CoercionSTCTest.groovy
@@ -158,4 +158,15 @@ class CoercionSTCTest extends StaticTypeCheckingTestCase {
             def s = (() -> ['']) as Supplier<Number>
         ''', 'Cannot return value of type java.util.List<java.lang.String> for 
lambda expecting java.lang.Number'
     }
+
+    // GROOVY-8045
+    void testCoerceToFunctionalInterface2() {
+        assertScript '''import java.util.function.*
+            def f(Supplier<Integer>... suppliers) {
+                suppliers*.get().sum()
+            }
+            Object result = f({->1},{->2})
+            assert result == 3
+        '''
+    }
 }

Reply via email to