Skip to content

Commit

Permalink
GROOVY-10660: STC: infer closure parameter types from method return type
Browse files Browse the repository at this point in the history
3_0_X backport
  • Loading branch information
eric-milles committed Nov 30, 2023
1 parent 53f48ee commit fdbd736
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2219,11 +2219,15 @@ private void negativeOrPositiveUnary(final Expression expression, final String n
@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
typeCheckingContext.pushEnclosingMethod(node);
final ClassNode returnType = node.getReturnType(); // GROOVY-10660: implicit return case
if (!isConstructor && (isClosureWithType(returnType) || isFunctionalInterface(returnType))) {
new ReturnAdder(returnStmt -> applyTargetType(returnType, returnStmt.getExpression())).visitMethod(node);
}
if (!isSkipMode(node) && !shouldSkipMethodNode(node)) {
super.visitConstructorOrMethod(node, isConstructor);
}
if (!isConstructor) {
returnAdder.visitMethod(node); // return statement added after visitConstructorOrMethod finished... we can not count these auto-generated return statements(GROOVY-7753), see `typeCheckingContext.pushEnclosingReturnStatement`
returnAdder.visitMethod(node); // GROOVY-7753: we cannot count these auto-generated return statements, see `typeCheckingContext.pushEnclosingReturnStatement`
}
typeCheckingContext.popEnclosingMethod();
}
Expand All @@ -2237,6 +2241,12 @@ public void visitExpressionStatement(final ExpressionStatement statement) {

@Override
public void visitReturnStatement(final ReturnStatement statement) {
if (typeCheckingContext.getEnclosingClosure() == null) {
MethodNode method = typeCheckingContext.getEnclosingMethod();
if (method != null && !method.isVoidMethod() && !method.isDynamicReturnType()) {
applyTargetType(method.getReturnType(), statement.getExpression()); // GROOVY-10660
}
}
super.visitReturnStatement(statement);
returnListener.returnStatementAdded(statement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,40 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
'''
}

void testGroovy10660() {
assertScript '''
<T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
// batch processor:
return { text, list ->
for (item in list) proc.accept(text, item)
}
}
m { text, item -> }
'''

assertScript '''
<T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
// batch processor:
return (text, list) -> {
for (item in list) proc.accept(text, item)
}
}
m((text, item) -> { })
'''

assertScript '''
<T> BiConsumer<String, List<T>> m(BiConsumer<String, ? super T> proc) {
/*implicit return*/ (text, list) -> {
for (item in list) proc.accept(text, item)
}
}
m((text, item) -> { })
'''
}

void testGroovy10673() {
assertScript '''
void proc(Consumer<Number> action) {
Expand Down

0 comments on commit fdbd736

Please sign in to comment.