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/11/01 15:38:03 UTC
[groovy] branch master updated: GROOVY-10336: STC: handle method
reference(s) supplied to variadic param
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 43715e5 GROOVY-10336: STC: handle method reference(s) supplied to variadic param
43715e5 is described below
commit 43715e58bff3cb579371e68e1423c153c6742f9a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Nov 1 10:37:29 2021 -0500
GROOVY-10336: STC: handle method reference(s) supplied to variadic param
---
.../transform/stc/StaticTypeCheckingVisitor.java | 38 ++++++++++++----------
.../transform/stc/MethodReferenceTest.groovy | 18 ++++++++++
2 files changed, 38 insertions(+), 18 deletions(-)
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 e132713..ee72e98 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -3611,34 +3611,36 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
Parameter[] parameters = selectedMethod.getParameters();
+ final int nthParameter = parameters.length - 1;
- List<Integer> methodReferenceParamIndexList = new LinkedList<>();
- List<Expression> newArgumentExpressionList = new LinkedList<>();
+ List<Integer> methodReferencePositions = new LinkedList<>();
+ List<Expression> newArgumentExpressions = new LinkedList<>();
for (int i = 0, n = argumentExpressions.size(); i < n; i += 1) {
Expression argumentExpression = argumentExpressions.get(i);
if (!(argumentExpression instanceof MethodReferenceExpression)) {
- newArgumentExpressionList.add(argumentExpression);
- continue;
- }
-
- Parameter param = parameters[i];
- ClassNode paramType = param.getType();
-
- if (!isFunctionalInterface(paramType.redirect())) {
- addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression);
- newArgumentExpressionList.add(argumentExpression);
+ newArgumentExpressions.add(argumentExpression);
} else {
- newArgumentExpressionList.add(constructLambdaExpressionForMethodReference(paramType));
- methodReferenceParamIndexList.add(i);
+ Parameter param = parameters[Math.min(i, nthParameter)]; // GROOVY-10336
+ ClassNode paramType = param.getType();
+ if (i >= nthParameter && paramType.isArray())
+ paramType = paramType.getComponentType();
+
+ if (!isFunctionalInterface(paramType.redirect())) {
+ addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression);
+ newArgumentExpressions.add(argumentExpression);
+ } else {
+ methodReferencePositions.add(i);
+ newArgumentExpressions.add(constructLambdaExpressionForMethodReference(paramType));
+ }
}
}
- if (methodReferenceParamIndexList.isEmpty()) return; // GROOVY-10269
+ if (methodReferencePositions.isEmpty()) return; // GROOVY-10269
- visitMethodCallArguments(receiver, args(newArgumentExpressionList), true, selectedMethod);
+ visitMethodCallArguments(receiver, args(newArgumentExpressions), true, selectedMethod);
- for (int index : methodReferenceParamIndexList) {
- Expression lambdaExpression = newArgumentExpressionList.get(index);
+ for (int index : methodReferencePositions) {
+ Expression lambdaExpression = newArgumentExpressions.get(index);
Expression methodReferenceExpression = argumentExpressions.get(index);
methodReferenceExpression.putNodeMetaData(CLOSURE_ARGUMENTS, lambdaExpression.getNodeMetaData(CLOSURE_ARGUMENTS));
}
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index a5ad7aa..da8a61f 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -644,4 +644,22 @@ final class MethodReferenceTest {
assert err =~ /The argument is a method reference, but the parameter type is not a functional interface/
}
+
+ @Test // GROOVY-10336
+ void testNotFunctionalInterface2() {
+ def err = shouldFail shell, '''
+ class C {
+ Integer m() { 1 }
+ }
+ @CompileStatic
+ void test() {
+ Supplier<Long> outer = () -> {
+ Closure<Long> inner = (Object o, Supplier<Integer> s) -> 2L
+ inner(new Object(), new C()::m) // TODO: resolve call(Object,Supplier<Integer>)
+ }
+ }
+ '''
+
+ assert err =~ /The argument is a method reference, but the parameter type is not a functional interface/
+ }
}