Skip to content

Commit

Permalink
GROOVY-10336
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 1, 2021
1 parent e540810 commit d21f3fa
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4412,4 +4412,35 @@ public void testTypeChecked10330() {

runConformTest(sources, "works");
}

@Test
public void testTypeChecked10336() {
assumeTrue(isParrotParser());

//@formatter:off
String[] sources = {
"Main.groovy",
"import java.util.function.Supplier\n" +
"class C {\n" +
" Integer m() { 1 }\n" +
"}\n" +
"@groovy.transform.TypeChecked\n" +
"void test() {\n" +
" Supplier<Long> outer = () -> {\n" +
" Closure<Long> inner = (Object o, Supplier<Integer> s) -> 2L\n" +
" inner(new Object(), new C()::m)\n" +
" }\n" +
"}\n" +
"test()\n",
};
//@formatter:on

runNegativeTest(sources,
"----------\n" +
"1. ERROR in Main.groovy (at line 9)\n" +
"\tinner(new Object(), new C()::m)\n" +
"\t ^^^^^^^^^^\n" +
"Groovy:The argument is a method reference, but the parameter type is not a functional interface\n" +
"----------\n");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4064,6 +4064,7 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi
}

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

List<Integer> methodReferenceParamIndexList = new LinkedList<>();
List<Expression> newArgumentExpressionList = new LinkedList<>();
Expand All @@ -4073,10 +4074,15 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi
newArgumentExpressionList.add(argumentExpression);
continue;
}

/* GRECLIPSE edit -- GROOVY-10336
Parameter param = parameters[i];
ClassNode paramType = param.getType();

*/
Parameter param = parameters[Math.min(i, nthParameter)];
ClassNode paramType = param.getType();
if (i >= nthParameter && paramType.isArray())
paramType = paramType.getComponentType();
// GRECLIPSE end
if (!isFunctionalInterface(paramType.redirect())) {
addError("The argument is a method reference, but the parameter type is not a functional interface", argumentExpression);
newArgumentExpressionList.add(argumentExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3761,34 +3761,36 @@ private void inferMethodReferenceType(final ClassNode receiver, final ArgumentLi
}

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));
}
}
}
// GRECLIPSE add -- GROOVY-10269
if (methodReferenceParamIndexList.isEmpty()) return;
// GRECLIPSE end
visitMethodCallArguments(receiver, args(newArgumentExpressionList), true, selectedMethod);

for (int index : methodReferenceParamIndexList) {
Expression lambdaExpression = newArgumentExpressionList.get(index);
if (methodReferencePositions.isEmpty()) return; // GROOVY-10269

visitMethodCallArguments(receiver, args(newArgumentExpressions), true, selectedMethod);

for (int index : methodReferencePositions) {
Expression lambdaExpression = newArgumentExpressions.get(index);
Expression methodReferenceExpression = argumentExpressions.get(index);
methodReferenceExpression.putNodeMetaData(CLOSURE_ARGUMENTS, lambdaExpression.getNodeMetaData(CLOSURE_ARGUMENTS));
}
Expand Down

0 comments on commit d21f3fa

Please sign in to comment.