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:50:01 UTC

[groovy] branch GROOVY_4_0_X 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 GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new c187608cb7 GROOVY-9854: STC: propagate `switch` type to `case` closure parameter
c187608cb7 is described below

commit c187608cb7d5e9d7d1460a8c15789a87cf55ec08
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 a0e919f981..d8f43a852b 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4075,6 +4075,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 8a74e3d12a..a131a594fb 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -1462,6 +1462,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.*