Skip to content

Commit d47b4aa

Browse files
committed
GROOVY-10336
1 parent a08a8f2 commit d47b4aa

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java

+31
Original file line numberDiff line numberDiff line change
@@ -4437,4 +4437,35 @@ public void testTypeChecked10330() {
44374437

44384438
runConformTest(sources, "works");
44394439
}
4440+
4441+
@Test
4442+
public void testTypeChecked10336() {
4443+
assumeTrue(isParrotParser());
4444+
4445+
//@formatter:off
4446+
String[] sources = {
4447+
"Main.groovy",
4448+
"import java.util.function.Supplier\n" +
4449+
"class C {\n" +
4450+
" Integer m() { 1 }\n" +
4451+
"}\n" +
4452+
"@groovy.transform.TypeChecked\n" +
4453+
"void test() {\n" +
4454+
" Supplier<Long> outer = () -> {\n" +
4455+
" Closure<Long> inner = (Object o, Supplier<Integer> s) -> 2L\n" +
4456+
" inner(new Object(), new C()::m)\n" +
4457+
" }\n" +
4458+
"}\n" +
4459+
"test()\n",
4460+
};
4461+
//@formatter:on
4462+
4463+
runNegativeTest(sources,
4464+
"----------\n" +
4465+
"1. ERROR in Main.groovy (at line 9)\n" +
4466+
"\tinner(new Object(), new C()::m)\n" +
4467+
"\t ^^^^^^^^^^\n" +
4468+
"Groovy:The argument is a method reference, but the parameter type is not a functional interface\n" +
4469+
"----------\n");
4470+
}
44404471
}

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -4064,6 +4064,7 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi
40644064
}
40654065

40664066
Parameter[] parameters = selectedMethod.getParameters();
4067+
final int nthParameter = parameters.length - 1;
40674068

40684069
List<Integer> methodReferenceParamIndexList = new LinkedList<>();
40694070
List<Expression> newArgumentExpressionList = new LinkedList<>();
@@ -4073,10 +4074,15 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi
40734074
newArgumentExpressionList.add(argumentExpression);
40744075
continue;
40754076
}
4076-
4077+
/* GRECLIPSE edit -- GROOVY-10336
40774078
Parameter param = parameters[i];
40784079
ClassNode paramType = param.getType();
4079-
4080+
*/
4081+
Parameter param = parameters[Math.min(i, nthParameter)];
4082+
ClassNode paramType = param.getType();
4083+
if (i >= nthParameter && paramType.isArray())
4084+
paramType = paramType.getComponentType();
4085+
// GRECLIPSE end
40804086
if (!isFunctionalInterface(paramType.redirect())) {
40814087
addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression);
40824088
newArgumentExpressionList.add(argumentExpression);

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

+22-20
Original file line numberDiff line numberDiff line change
@@ -3761,34 +3761,36 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi
37613761
}
37623762

37633763
Parameter[] parameters = selectedMethod.getParameters();
3764+
final int nthParameter = parameters.length - 1;
37643765

3765-
List<Integer> methodReferenceParamIndexList = new LinkedList<>();
3766-
List<Expression> newArgumentExpressionList = new LinkedList<>();
3766+
List<Integer> methodReferencePositions = new LinkedList<>();
3767+
List<Expression> newArgumentExpressions = new LinkedList<>();
37673768
for (int i = 0, n = argumentExpressions.size(); i < n; i += 1) {
37683769
Expression argumentExpression = argumentExpressions.get(i);
37693770
if (!(argumentExpression instanceof MethodReferenceExpression)) {
3770-
newArgumentExpressionList.add(argumentExpression);
3771-
continue;
3772-
}
3773-
3774-
Parameter param = parameters[i];
3775-
ClassNode paramType = param.getType();
3776-
3777-
if (!isFunctionalInterface(paramType.redirect())) {
3778-
addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression);
3779-
newArgumentExpressionList.add(argumentExpression);
3771+
newArgumentExpressions.add(argumentExpression);
37803772
} else {
3781-
newArgumentExpressionList.add(constructLambdaExpressionForMethodReference(paramType));
3782-
methodReferenceParamIndexList.add(i);
3773+
Parameter param = parameters[Math.min(i, nthParameter)]; // GROOVY-10336
3774+
ClassNode paramType = param.getType();
3775+
if (i >= nthParameter && paramType.isArray())
3776+
paramType = paramType.getComponentType();
3777+
3778+
if (!isFunctionalInterface(paramType.redirect())) {
3779+
addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression);
3780+
newArgumentExpressions.add(argumentExpression);
3781+
} else {
3782+
methodReferencePositions.add(i);
3783+
newArgumentExpressions.add(constructLambdaExpressionForMethodReference(paramType));
3784+
}
37833785
}
37843786
}
3785-
// GRECLIPSE add -- GROOVY-10269
3786-
if (methodReferenceParamIndexList.isEmpty()) return;
3787-
// GRECLIPSE end
3788-
visitMethodCallArguments(receiver, args(newArgumentExpressionList), true, selectedMethod);
37893787

3790-
for (int index : methodReferenceParamIndexList) {
3791-
Expression lambdaExpression = newArgumentExpressionList.get(index);
3788+
if (methodReferencePositions.isEmpty()) return; // GROOVY-10269
3789+
3790+
visitMethodCallArguments(receiver, args(newArgumentExpressions), true, selectedMethod);
3791+
3792+
for (int index : methodReferencePositions) {
3793+
Expression lambdaExpression = newArgumentExpressions.get(index);
37923794
Expression methodReferenceExpression = argumentExpressions.get(index);
37933795
methodReferenceExpression.putNodeMetaData(CLOSURE_ARGUMENTS, lambdaExpression.getNodeMetaData(CLOSURE_ARGUMENTS));
37943796
}

0 commit comments

Comments
 (0)