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/07/08 14:24:39 UTC
[groovy] branch master updated: GROOVY-9854: STC: propagate `switch` type to `case` closure parameter
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 e21b5d41a3 GROOVY-9854: STC: propagate `switch` type to `case` closure parameter
e21b5d41a3 is described below
commit e21b5d41a3bc2e6583c6aa3615432390d1c229fa
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 8 08:25:55 2022 -0500
GROOVY-9854: STC: propagate `switch` type to `case` closure parameter
---
.../transform/stc/StaticTypeCheckingVisitor.java | 15 +++++++++++++
.../stc/ClosureParamTypeInferenceSTCTest.groovy | 26 ++++++++++++++++++++++
2 files changed, 41 insertions(+)
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 ae0acf3d27..8c45a0b7d9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4085,6 +4085,21 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
@Override
public void visitCaseStatement(final CaseStatement statement) {
+ Expression expression = statement.getExpression();
+ if (expression instanceof ClosureExpression) { // GROOVY-9854: propagate the switch type
+ SwitchStatement switchStatement = typeCheckingContext.getEnclosingSwitchStatement();
+ ClassNode inf = switchStatement.getExpression().getNodeMetaData(TYPE);
+ expression.putNodeMetaData(CLOSURE_ARGUMENTS, new ClassNode[]{inf});
+
+ Parameter[] params = ((ClosureExpression) expression).getParameters();
+ if (params != null && params.length == 1) {
+ boolean lambda = (expression instanceof LambdaExpression);
+ checkParamType(params[0], wrapTypeIfNecessary(inf), false, lambda);
+ } else if (params == null || params.length > 1) {
+ int paramCount = (params != null ? params.length : 0);
+ addError("Incorrect number of parameters. Expected 1 but found " + paramCount, expression);
+ }
+ }
super.visitCaseStatement(statement);
restoreTypeBeforeConditional();
}
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index 975e1c8602..1f6bd95af2 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -1458,6 +1458,32 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ void testGroovy9854() {
+ assertScript '''
+ def result = switch (42) {
+ case { i -> i > 0 } -> 'positive'
+ case { it < 0 } -> 'negative'
+ default -> 'zero'
+ }
+ assert result == 'positive'
+ '''
+
+ shouldFailWithMessages '''
+ switch (42) { case { -> }: break; }
+ ''',
+ 'Incorrect number of parameters. Expected 1 but found 0'
+
+ shouldFailWithMessages '''
+ switch (42) { case { i, j -> }: break; }
+ ''',
+ 'Incorrect number of parameters. Expected 1 but found 2'
+
+ shouldFailWithMessages '''
+ switch (42) { case { String s -> }: break; }
+ ''',
+ 'Expected type java.lang.Integer for closure parameter: s'
+ }
+
void testGroovy9968() {
assertScript '''
import groovy.transform.*