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/09/03 21:05:39 UTC
[groovy] branch GROOVY_3_0_X updated: GROOVY-10734: STC: `Type::instanceMethod` specifies first param type
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 c493f05eba GROOVY-10734: STC: `Type::instanceMethod` specifies first param type
c493f05eba is described below
commit c493f05eba6e0156986d99f2c08e99b288d7cc47
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Sep 3 11:17:37 2022 -0500
GROOVY-10734: STC: `Type::instanceMethod` specifies first param type
---
.../transform/stc/StaticTypeCheckingVisitor.java | 27 ++++++++++++++++------
.../transform/stc/MethodReferenceTest.groovy | 18 +++++++++++++++
2 files changed, 38 insertions(+), 7 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 7154253555..1ab4edd184 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -934,7 +934,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (rhsExpression instanceof ClosureExpression) {
inferParameterAndReturnTypesOfClosureOnRHS(lhsType, (ClosureExpression) rhsExpression);
} else if (rhsExpression instanceof MethodReferenceExpression) {
- LambdaExpression lambdaExpression = constructLambdaExpressionForMethodReference(lhsType);
+ LambdaExpression lambdaExpression = constructLambdaExpressionForMethodReference(lhsType, (MethodReferenceExpression) rhsExpression);
inferParameterAndReturnTypesOfClosureOnRHS(lhsType, lambdaExpression);
rhsExpression.putNodeMetaData(CONSTRUCTED_LAMBDA_EXPRESSION, lambdaExpression);
@@ -3665,7 +3665,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
newArgumentExpressions.add(argumentExpression);
} else {
methodReferencePositions.add(i);
- newArgumentExpressions.add(constructLambdaExpressionForMethodReference(paramType));
+ newArgumentExpressions.add(constructLambdaExpressionForMethodReference(paramType, (MethodReferenceExpression) argumentExpression));
}
}
}
@@ -3681,11 +3681,24 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
}
- private LambdaExpression constructLambdaExpressionForMethodReference(final ClassNode functionalInterfaceType) {
- int nParameters = findSAM(functionalInterfaceType).getParameters().length;
- Parameter[] parameters = new Parameter[nParameters];
- for (int i = 0; i < nParameters; i += 1) {
- parameters[i] = new Parameter(DYNAMIC_TYPE, "p" + i);
+ private LambdaExpression constructLambdaExpressionForMethodReference(final ClassNode functionalInterfaceType, final MethodReferenceExpression methodReference) {
+ Parameter[] parameters = findSAM(functionalInterfaceType).getParameters();
+ int nParameters = parameters.length;
+ if (nParameters > 0) {
+ ClassNode firstParamType = DYNAMIC_TYPE;
+ // GROOVY-10734: Type::instanceMethod has implied first param
+ List<MethodNode> candidates = methodReference.getNodeMetaData(MethodNode.class);
+ if (candidates != null && !candidates.isEmpty()) {
+ ClassNode objExpType = getType(methodReference.getExpression());
+ if (isClassClassNodeWrappingConcreteType(objExpType)
+ && candidates.stream().allMatch(mn -> !mn.isStatic())) {
+ firstParamType = objExpType.getGenericsTypes()[0].getType();
+ }
+ }
+ parameters = new Parameter[nParameters];
+ for (int i = 0; i < nParameters; i += 1) {
+ parameters[i] = new Parameter(i == 0 ? firstParamType : DYNAMIC_TYPE, "p" + i);
+ }
}
return new LambdaExpression(parameters, GENERATED_EMPTY_STATEMENT);
}
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index d7f14b24db..f2ea2d9e62 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -195,6 +195,24 @@ final class MethodReferenceTest extends GroovyTestCase {
'''
}
+ // class::instanceMethod -- GROOVY-10734
+ void testFunctionCI7() {
+ assertScript '''
+ class C {
+ String p
+ }
+ @groovy.transform.CompileStatic
+ Map test(Collection<C> items) {
+ items.stream().collect(
+ java.util.stream.Collectors.groupingBy(C::getP) // Failed to find the expected method[getP(Object)] in the type[C]
+ )
+ }
+ def map = test([new C(p:'foo'), new C(p:'bar'), new C(p:'foo')])
+ assert map.foo.size() == 2
+ assert map.bar.size() == 1
+ '''
+ }
+
// class::instanceMethod -- GROOVY-9974
void testPredicateCI() {
assertScript '''