You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2021/07/14 13:10:20 UTC

[groovy] branch master updated (d865108 -> b1108b0)

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git.


    from d865108  GROOVY-7867: collection conversion: attach exception of constructor as suppressed exception
     new b4298c7  GROOVY-9272: Support switch expression
     new 5c14853  GROOVY-10171: Bump slf4j to 1.7.31
     new 6a9f77a  GROOVY-10172: Bump Spotbugs version to 4.3.0
     new 88aa33b  GROOVY-10173: Bump checkstyle to 8.44
     new 04024b0  GROOVY-10170: Bump JUnit Jupiter/JUnit Platform to 5.7.2/1.7.2
     new 738231c  GROOVY-10167: Bump jackson version to 2.12.4
     new 6930c23  GROOVY-10168: Bump json-unit version to 2.27.0
     new 96616ac  GROOVY-10169: Bump Ant version to 1.10.11 (incorporates CVE-2021-36373 and CVE-2021-36374)
     new b1108b0  update dependency metadata

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 gradle/verification-metadata.xml                   |  24 +-
 src/antlr/GroovyLexer.g4                           |   1 +
 src/antlr/GroovyParser.g4                          |  34 ++-
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 309 ++++++++++++++++++++-
 .../groovy/parser/antlr4/SemanticPredicates.java   |   3 +-
 .../SwitchExpression_01x.groovy}                   |   7 +-
 .../SwitchExpression_02x.groovy}                   |  15 +-
 .../core/SwitchExpression_03x.groovy}              |   8 +-
 .../core/SwitchExpression_04x.groovy}              |   9 +-
 .../SwitchExpression_05x.groovy}                   |   6 +-
 ...ation_03.groovy => SwitchExpression_06x.groovy} |  15 +-
 .../core/SwitchExpression_07x.groovy}              |  25 +-
 .../{For_02.groovy => SwitchExpression_08x.groovy} |  44 ++-
 .../core/SwitchExpression_09x.groovy               |  14 +-
 ...ation_02.groovy => SwitchExpression_10x.groovy} |  57 ++--
 .../core/SwitchExpression_11x.groovy               | 111 ++++++++
 .../SwitchExpression_12x.groovy}                   |  20 +-
 .../SwitchExpression_13x.groovy}                   |  12 +-
 .../core/SwitchExpression_14x.groovy               |  79 ++++++
 .../core/SwitchExpression_15x.groovy}              |  13 +-
 .../core/SwitchExpression_16x.groovy}              |  21 +-
 ...ssion_16.groovy => SwitchExpression_17x.groovy} |  28 +-
 .../SwitchExpression_18x.groovy}                   |  13 +-
 .../SwitchExpression_19x.groovy}                   |  13 +-
 .../core/SwitchExpression_20x.groovy               |  20 +-
 .../core/SwitchExpression_21x.groovy               |  20 +-
 .../SwitchExpression_22x.groovy}                   |  14 +-
 .../core/SwitchExpression_23x.groovy}              |  31 ++-
 .../core/SwitchExpression_24x.groovy               |  34 ++-
 .../SwitchExpression_01x.groovy}                   |   6 +-
 .../SwitchExpression_02x.groovy}                   |   6 +-
 .../SwitchExpression_03x.groovy}                   |   7 +-
 .../SwitchExpression_04x.groovy}                   |   7 +-
 .../SwitchExpression_05x.groovy}                   |   6 +-
 .../SwitchExpression_06x.groovy}                   |   6 +-
 .../fail/SwitchExpression_07x.groovy}              |  10 +-
 .../fail/SwitchExpression_08x.groovy}              |  10 +-
 src/test/groovy/MethodInBadPositionTest.groovy     |   2 +-
 src/test/groovy/bugs/Groovy6932Bug.groovy          |   2 +-
 src/test/groovy/bugs/Groovy8060Bug.groovy          |   2 +-
 .../groovy/parser/antlr4/GroovyParserTest.groovy   |  47 +++-
 .../groovy/parser/antlr4/SyntaxErrorTest.groovy    |  13 +-
 .../apache/groovy/parser/antlr4/TestUtils.groovy   |   5 +-
 .../asm/sc/StaticCompileFlowTypingTest.groovy      |   2 +-
 .../console/ui/text/SmartDocumentFilter.java       |   3 +-
 .../groovy-ginq/src/spec/doc/ginq-userguide.adoc   |   7 +
 .../test/org/apache/groovy/ginq/GinqTest.groovy    |  16 ++
 subprojects/groovy-json/build.gradle               |   2 +-
 versions.properties                                |  16 +-
 49 files changed, 921 insertions(+), 254 deletions(-)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => core/SwitchExpression_01x.groovy} (89%)
 copy src/test-resources/{bugs/BUG-GROOVY-4757.groovy => core/SwitchExpression_02x.groovy} (85%)
 copy src/{main/java/org/codehaus/groovy/util/Finalizable.java => test-resources/core/SwitchExpression_03x.groovy} (89%)
 copy src/{main/java/org/codehaus/groovy/util/Finalizable.java => test-resources/core/SwitchExpression_04x.groovy} (87%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => core/SwitchExpression_05x.groovy} (91%)
 copy src/test-resources/core/{InterfaceDeclaration_03.groovy => SwitchExpression_06x.groovy} (84%)
 copy src/{spec/test-resources/ambiguousmethods.groovy => test-resources/core/SwitchExpression_07x.groovy} (74%)
 copy src/test-resources/core/{For_02.groovy => SwitchExpression_08x.groovy} (72%)
 copy subprojects/groovy-json/src/main/java/org/apache/groovy/json/internal/CacheType.java => src/test-resources/core/SwitchExpression_09x.groovy (87%)
 copy src/test-resources/core/{TraitDeclaration_02.groovy => SwitchExpression_10x.groovy} (61%)
 create mode 100644 src/test-resources/core/SwitchExpression_11x.groovy
 copy src/test-resources/{bugs/BUG-GROOVY-8641.groovy => core/SwitchExpression_12x.groovy} (81%)
 copy src/test-resources/{bugs/BUG-GROOVY-4757.groovy => core/SwitchExpression_13x.groovy} (86%)
 create mode 100644 src/test-resources/core/SwitchExpression_14x.groovy
 copy src/{main/java/org/codehaus/groovy/runtime/wrappers/ByteWrapper.java => test-resources/core/SwitchExpression_15x.groovy} (82%)
 copy src/{test/org/codehaus/groovy/runtime/methoddispatching/vm8/FooOne.java => test-resources/core/SwitchExpression_16x.groovy} (74%)
 copy src/test-resources/core/{Expression_16.groovy => SwitchExpression_17x.groovy} (83%)
 copy src/test-resources/{fail/Switch_01.groovy => core/SwitchExpression_18x.groovy} (90%)
 copy src/test-resources/{fail/Switch_01.groovy => core/SwitchExpression_19x.groovy} (90%)
 copy buildSrc/src/main/groovy/org/apache/groovy/gradle/DocAggregationExtension.groovy => src/test-resources/core/SwitchExpression_20x.groovy (76%)
 copy buildSrc/src/main/groovy/org/apache/groovy/gradle/DocAggregationExtension.groovy => src/test-resources/core/SwitchExpression_21x.groovy (74%)
 copy src/test-resources/{fail/Number_04x.groovy => core/SwitchExpression_22x.groovy} (68%)
 copy src/{test/groovy/bugs/Groovy8797Bug.groovy => test-resources/core/SwitchExpression_23x.groovy} (66%)
 copy subprojects/groovy-macro/build.gradle => src/test-resources/core/SwitchExpression_24x.groovy (63%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => fail/SwitchExpression_01x.groovy} (93%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => fail/SwitchExpression_02x.groovy} (93%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => fail/SwitchExpression_03x.groovy} (92%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => fail/SwitchExpression_04x.groovy} (90%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => fail/SwitchExpression_05x.groovy} (92%)
 copy src/test-resources/{bugs/BUG-GROOVY-9692.groovy => fail/SwitchExpression_06x.groovy} (91%)
 copy src/{test/org/codehaus/groovy/classgen/Main.groovy => test-resources/fail/SwitchExpression_07x.groovy} (88%)
 copy src/{test/org/codehaus/groovy/classgen/Main.groovy => test-resources/fail/SwitchExpression_08x.groovy} (88%)

[groovy] 06/09: GROOVY-10167: Bump jackson version to 2.12.4

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 738231c67c39c4044b8b87e6ca08960b09f08f10
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:55:18 2021 +1000

    GROOVY-10167: Bump jackson version to 2.12.4
---
 versions.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/versions.properties b/versions.properties
index a36e880..343e40c 100644
--- a/versions.properties
+++ b/versions.properties
@@ -28,7 +28,7 @@ commonsMath3 = 3.6.1
 gpars = 1.2.1
 ivy = 2.5.0
 jansi = 2.3.3
-jackson = 2.12.3
+jackson = 2.12.4
 jarjar = 1.7.2
 javaParser = 3.22.1
 jline = 2.14.6

[groovy] 01/09: GROOVY-9272: Support switch expression

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit b4298c727089e790782a6a995208fdf8cb223071
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sun Jun 27 22:21:32 2021 +0800

    GROOVY-9272: Support switch expression
---
 src/antlr/GroovyLexer.g4                           |   1 +
 src/antlr/GroovyParser.g4                          |  34 ++-
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 309 ++++++++++++++++++++-
 .../groovy/parser/antlr4/SemanticPredicates.java   |   3 +-
 .../core/SwitchExpression_01x.groovy}              |  32 +--
 .../core/SwitchExpression_02x.groovy}              |  35 +--
 .../core/SwitchExpression_03x.groovy}              |  32 +--
 .../core/SwitchExpression_04x.groovy}              |  33 +--
 .../core/SwitchExpression_05x.groovy}              |  31 +--
 .../core/SwitchExpression_06x.groovy}              |  35 +--
 .../core/SwitchExpression_07x.groovy}              |  42 ++-
 .../core/SwitchExpression_08x.groovy}              |  45 ++-
 .../core/SwitchExpression_09x.groovy}              |  32 +--
 .../core/SwitchExpression_10x.groovy}              |  58 ++--
 .../core/SwitchExpression_11x.groovy               | 111 ++++++++
 .../core/SwitchExpression_12x.groovy}              |  37 +--
 .../core/SwitchExpression_13x.groovy}              |  30 +-
 .../core/SwitchExpression_14x.groovy               |  79 ++++++
 .../core/SwitchExpression_15x.groovy}              |  35 +--
 .../core/SwitchExpression_16x.groovy}              |  39 ++-
 .../core/SwitchExpression_17x.groovy}              |  37 +--
 .../core/SwitchExpression_18x.groovy}              |  33 +--
 .../core/SwitchExpression_19x.groovy}              |  33 +--
 .../core/SwitchExpression_20x.groovy}              |  39 ++-
 .../core/SwitchExpression_21x.groovy}              |  39 ++-
 .../core/SwitchExpression_22x.groovy}              |  36 +--
 .../core/SwitchExpression_23x.groovy}              |  40 ++-
 .../core/SwitchExpression_24x.groovy}              |  49 ++--
 .../fail/SwitchExpression_01x.groovy}              |  31 +--
 .../fail/SwitchExpression_02x.groovy}              |  31 +--
 .../fail/SwitchExpression_03x.groovy}              |  32 +--
 .../fail/SwitchExpression_04x.groovy}              |  32 +--
 .../fail/SwitchExpression_05x.groovy}              |  31 +--
 .../fail/SwitchExpression_06x.groovy}              |  31 +--
 .../fail/SwitchExpression_07x.groovy}              |  31 +--
 .../fail/SwitchExpression_08x.groovy}              |  31 +--
 src/test/groovy/MethodInBadPositionTest.groovy     |   2 +-
 .../groovy/parser/antlr4/GroovyParserTest.groovy   |  47 +++-
 .../groovy/parser/antlr4/SyntaxErrorTest.groovy    |  13 +-
 .../apache/groovy/parser/antlr4/TestUtils.groovy   |   5 +-
 .../console/ui/text/SmartDocumentFilter.java       |   3 +-
 .../groovy-ginq/src/spec/doc/ginq-userguide.adoc   |   7 +
 .../test/org/apache/groovy/ginq/GinqTest.groovy    |  16 ++
 43 files changed, 925 insertions(+), 777 deletions(-)

diff --git a/src/antlr/GroovyLexer.g4 b/src/antlr/GroovyLexer.g4
index 53532b1..2c58768 100644
--- a/src/antlr/GroovyLexer.g4
+++ b/src/antlr/GroovyLexer.g4
@@ -417,6 +417,7 @@ fragment
 BOOLEAN       : 'boolean';
 
 BREAK         : 'break';
+YIELD         : 'yield';
 
 fragment
 BYTE          : 'byte';
diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index 07f1fae..3faf7ad 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -45,6 +45,7 @@ options {
 }
 
 @members {
+    private int inSwitchExpressionLevel = 0;
 
     public static class GroovyParserRuleContext extends ParserRuleContext implements NodeMetaDataHandler {
         private Map metaDataMap = null;
@@ -614,6 +615,11 @@ breakStatement
         identifier?
     ;
 
+yieldStatement
+    :   YIELD
+        expression
+    ;
+
 tryCatchStatement
     :   TRY resources? nls block
         (nls catchClause)*
@@ -634,6 +640,8 @@ statement
     |   THROW expression                                                                                    #throwStmtAlt
     |   breakStatement                                                                                      #breakStmtAlt
     |   continueStatement                                                                                   #continueStmtAlt
+    |   { inSwitchExpressionLevel > 0 }?
+        yieldStatement                                                                                      #yieldStmtAlt
     |   identifier COLON nls statement                                                                      #labeledStmtAlt
     |   assertStatement                                                                                     #assertStmtAlt
     |   localVariableDeclaration                                                                            #localVariableDeclarationStmtAlt
@@ -717,7 +725,7 @@ expressionInPar
     ;
 
 expressionList[boolean canSpread]
-    :   expressionListElement[$canSpread] (COMMA expressionListElement[$canSpread])*
+    :   expressionListElement[$canSpread] (COMMA nls expressionListElement[$canSpread])*
     ;
 
 expressionListElement[boolean canSpread]
@@ -737,6 +745,26 @@ postfixExpression
     :   pathExpression op=(INC | DEC)?
     ;
 
+switchExpression
+@init {
+    inSwitchExpressionLevel++;
+}
+@after {
+    inSwitchExpressionLevel--;
+}
+    :   SWITCH expressionInPar nls LBRACE nls switchBlockStatementExpressionGroup* nls RBRACE
+    ;
+
+switchBlockStatementExpressionGroup
+    :   (switchExpressionLabel nls)+ blockStatements
+    ;
+
+switchExpressionLabel
+    :   (   CASE expressionList[true]
+        |   DEFAULT
+        ) ac=(ARROW | COLON)
+    ;
+
 expression
     // must come before postfixExpression to resovle the ambiguities between casting and call on parentheses expression, e.g. (int)(1 / 2)
     :   castParExpression castOperandExpression                                             #castExprAlt
@@ -744,6 +772,8 @@ expression
     // qualified names, array expressions, method invocation, post inc/dec
     |   postfixExpression                                                                   #postfixExprAlt
 
+    |   switchExpression                                                                    #switchExprAlt
+
     // ~(BNOT)/!(LNOT) (level 1)
     |   (BITNOT | NOT) nls expression                                                       #unaryNotExprAlt
 
@@ -1177,6 +1207,7 @@ identifier
 //  |   DEF
     |   TRAIT
     |   AS
+    |   YIELD
     ;
 
 builtInType
@@ -1229,6 +1260,7 @@ keywords
     |   VAR
     |   VOLATILE
     |   WHILE
+    |   YIELD
 
     |   NullLiteral
     |   BooleanLiteral
diff --git a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 3505867..eea1e49 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -214,6 +214,7 @@ import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.CodeVisitorSupport;
 import org.codehaus.groovy.ast.ConstructorNode;
 import org.codehaus.groovy.ast.EnumConstantClassNode;
 import org.codehaus.groovy.ast.FieldNode;
@@ -314,6 +315,13 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static groovy.lang.Tuple.tuple;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.ARROW;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchBlockStatementExpressionGroupContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchExpressionContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.SwitchExpressionLabelContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.YieldStatementContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.YieldStmtAltContext;
 import static org.apache.groovy.parser.antlr4.GroovyParser.ADD;
 import static org.apache.groovy.parser.antlr4.GroovyParser.AS;
 import static org.apache.groovy.parser.antlr4.GroovyParser.CASE;
@@ -339,11 +347,14 @@ import static org.apache.groovy.parser.antlr4.GroovyParser.STATIC;
 import static org.apache.groovy.parser.antlr4.GroovyParser.SUB;
 import static org.apache.groovy.parser.antlr4.GroovyParser.VAR;
 import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.configureAST;
+import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveVoid;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.closureX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 import static org.codehaus.groovy.classgen.asm.util.TypeUtil.isPrimitiveType;
-import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveVoid;
 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;
 
@@ -351,7 +362,6 @@ import static org.codehaus.groovy.runtime.DefaultGroovyMethods.last;
  * Builds the AST from the parse tree generated by Antlr4.
  */
 public class AstBuilder extends GroovyParserBaseVisitor<Object> {
-
     public AstBuilder(final SourceUnit sourceUnit, final boolean groovydocEnabled, final boolean runtimeGroovydocEnabled) {
         this.sourceUnit = sourceUnit;
         this.moduleNode = new ModuleNode(sourceUnit);
@@ -1009,6 +1019,11 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
 
     @Override
     public ReturnStatement visitReturnStmtAlt(final ReturnStmtAltContext ctx) {
+        GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
+        if (gprc instanceof SwitchExpressionContext) {
+            throw createParsingFailedException("switch expression does not support `return`", ctx);
+        }
+
         return configureAST(new ReturnStatement(asBoolean(ctx.expression())
                         ? (Expression) this.visit(ctx.expression())
                         : ConstantExpression.EMPTY_EXPRESSION),
@@ -1037,6 +1052,11 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
             throw createParsingFailedException("break statement is only allowed inside loops or switches", ctx);
         }
 
+        GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
+        if (gprc instanceof SwitchExpressionContext) {
+            throw createParsingFailedException("switch expression does not support `break`", ctx);
+        }
+
         String label = asBoolean(ctx.identifier())
                 ? this.visitIdentifier(ctx.identifier())
                 : null;
@@ -1045,11 +1065,28 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     }
 
     @Override
+    public ReturnStatement visitYieldStatement(YieldStatementContext ctx) {
+        ReturnStatement returnStatement = (ReturnStatement) returnS((Expression) this.visit(ctx.expression()));
+        returnStatement.putNodeMetaData(IS_YIELD_STATEMENT, true);
+        return configureAST(returnStatement, ctx);
+    }
+
+    @Override
+    public ReturnStatement visitYieldStmtAlt(YieldStmtAltContext ctx) {
+        return configureAST(this.visitYieldStatement(ctx.yieldStatement()), ctx);
+    }
+
+    @Override
     public ContinueStatement visitContinueStatement(final ContinueStatementContext ctx) {
         if (visitingLoopStatementCount == 0) {
             throw createParsingFailedException("continue statement is only allowed inside loops", ctx);
         }
 
+        GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
+        if (gprc instanceof SwitchExpressionContext) {
+            throw createParsingFailedException("switch expression does not support `continue`", ctx);
+        }
+
         String label = asBoolean(ctx.identifier())
                 ? this.visitIdentifier(ctx.identifier())
                 : null;
@@ -1058,6 +1095,238 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
 
     }
 
+    @Override
+    public Expression visitSwitchExprAlt(SwitchExprAltContext ctx) {
+        return configureAST(this.visitSwitchExpression(ctx.switchExpression()), ctx);
+    }
+
+    /**
+     * <pre>
+     * switch(a) {
+     *     case 0, 1  ->   'a';
+     *     case 2     ->   'b';
+     *     default    ->   'z';
+     * }
+     * </pre>
+     * the above code will be transformed to:
+     * <pre>
+     * {->
+     *     switch(a) {
+     *         case 0:
+     *         case 1:  return 'a';
+     *         case 2:  return 'b';
+     *         default: return 'z';
+     *     }
+     * }()
+     * </pre>
+     *
+     * @param ctx the parse tree
+     * @return {@link MethodCallExpression} instance
+     */
+    @Override
+    public MethodCallExpression visitSwitchExpression(SwitchExpressionContext ctx) {
+        switchExpressionRuleContextStack.push(ctx);
+        try {
+            validateSwitchExpressionLabels(ctx);
+            List<Statement> statementList =
+                    ctx.switchBlockStatementExpressionGroup().stream()
+                            .map(e -> this.visitSwitchBlockStatementExpressionGroup(e))
+                            .reduce(new LinkedList<>(), (r, e) -> {
+                                r.addAll(e);
+                                return r;
+                            });
+
+            List<CaseStatement> caseStatementList = new LinkedList<>();
+            List<Statement> defaultStatementList = new LinkedList<>();
+
+            statementList.forEach(e -> {
+                if (e instanceof CaseStatement) {
+                    caseStatementList.add((CaseStatement) e);
+                } else if (isTrue(e, IS_SWITCH_DEFAULT)) {
+                    defaultStatementList.add(e);
+                }
+            });
+
+            int defaultStatementListSize = defaultStatementList.size();
+            if (defaultStatementListSize > 1) {
+                throw createParsingFailedException("switch expression should have only one default case, which should appear at last", defaultStatementList.get(0));
+            }
+
+            if (defaultStatementListSize > 0 && last(statementList) instanceof CaseStatement) {
+                throw createParsingFailedException("default case should appear at last", defaultStatementList.get(0));
+            }
+
+            SwitchStatement switchStatement = configureAST(
+                    new SwitchStatement(
+                            this.visitExpressionInPar(ctx.expressionInPar()),
+                            caseStatementList,
+                            defaultStatementListSize == 0 ? EmptyStatement.INSTANCE : defaultStatementList.get(0)
+                    ),
+                    ctx);
+
+            MethodCallExpression callClosure = callX(
+                    configureAST(
+                            closureX(null, createBlockStatement(switchStatement)),
+                            ctx
+                    ), "call");
+            callClosure.setImplicitThis(false);
+
+            return configureAST(callClosure, ctx);
+        } finally {
+            switchExpressionRuleContextStack.pop();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<Statement> visitSwitchBlockStatementExpressionGroup(SwitchBlockStatementExpressionGroupContext ctx) {
+        int labelCnt = ctx.switchExpressionLabel().size();
+        List<Token> firstLabelHolder = new ArrayList<>(1);
+        final int[] arrowCntHolder = new int[1];
+
+        return (List<Statement>) ctx.switchExpressionLabel().stream()
+                .map(e -> (Object) this.visitSwitchExpressionLabel(e))
+                .reduce(new ArrayList<Statement>(4), (r, e) -> {
+                    List<Statement> statementList = (List<Statement>) r;
+                    Tuple3<Token, List<Expression>, Integer> tuple = (Tuple3<Token, List<Expression>, Integer>) e;
+
+                    boolean isArrow = ARROW == tuple.getV3();
+                    if (isArrow) {
+                        if (++arrowCntHolder[0] > 1 && !firstLabelHolder.isEmpty()) {
+                            throw createParsingFailedException("`case ... ->` does not support falling through cases", firstLabelHolder.get(0));
+                        }
+                    }
+
+                    boolean isLast = labelCnt - 1 == statementList.size();
+
+                    BlockStatement codeBlock = this.visitBlockStatements(ctx.blockStatements());
+                    List<Statement> statements = codeBlock.getStatements();
+                    int statementsCnt = statements.size();
+                    if (0 == statementsCnt) {
+                        throw createParsingFailedException("`yield` is expected", ctx.blockStatements());
+                    }
+
+                    if (statementsCnt > 1) {
+                        throw new GroovyBugError("statements count should be 1, but the count is actually: " + statementsCnt);
+                    }
+
+                    if (!isArrow) {
+                        boolean[] hasYieldHolder = new boolean[1];
+                        boolean[] hasThrowHolder = new boolean[1];
+                        codeBlock.visit(new CodeVisitorSupport() {
+                            @Override
+                            public void visitReturnStatement(ReturnStatement statement) {
+                                if (isTrue(statement, IS_YIELD_STATEMENT)) {
+                                    hasYieldHolder[0] = true;
+                                    return;
+                                }
+
+                                super.visitReturnStatement(statement);
+                            }
+
+                            @Override
+                            public void visitThrowStatement(ThrowStatement statement) {
+                                hasThrowHolder[0] = true;
+                            }
+                        });
+                        if (!(hasYieldHolder[0] || hasThrowHolder[0])) {
+                            throw createParsingFailedException("`yield` or `throw` is expected", ctx.blockStatements());
+                        }
+                    }
+
+                    Statement exprOrBlockStatement = statements.get(0);
+                    if (exprOrBlockStatement instanceof BlockStatement) {
+                        BlockStatement blockStatement = (BlockStatement) exprOrBlockStatement;
+                        List<Statement> branchStatementList = blockStatement.getStatements();
+                        if (1 == branchStatementList.size()) {
+                            exprOrBlockStatement = branchStatementList.get(0);
+                        }
+                    }
+
+                    if (!(exprOrBlockStatement instanceof ReturnStatement || exprOrBlockStatement instanceof ThrowStatement)) {
+                        MethodCallExpression callClosure = callX(
+                                configureAST(
+                                        closureX(null, exprOrBlockStatement),
+                                        exprOrBlockStatement
+                                ), "call");
+                        callClosure.setImplicitThis(false);
+
+                        codeBlock = configureAST(
+                                createBlockStatement(configureAST(
+                                        returnS(
+                                                exprOrBlockStatement instanceof ExpressionStatement
+                                                        ? ((ExpressionStatement) exprOrBlockStatement).getExpression()
+                                                        : callClosure
+                                        ),
+                                        exprOrBlockStatement
+                                )),
+                                exprOrBlockStatement
+                        );
+                    }
+
+                    switch (tuple.getV1().getType()) {
+                        case CASE: {
+                            if (!asBoolean(statementList)) {
+                                firstLabelHolder.add(tuple.getV1());
+                            }
+
+                            for (int i = 0, n = tuple.getV2().size(); i < n; i++) {
+                                Expression expr = tuple.getV2().get(i);
+
+                                statementList.add(
+                                        configureAST(
+                                                new CaseStatement(
+                                                        expr,
+
+                                                        // check whether processing the last label. if yes, block statement should be attached.
+                                                        (isLast && i == n - 1) ? codeBlock
+                                                                : EmptyStatement.INSTANCE
+                                                ),
+                                                firstLabelHolder.get(0)));
+                            }
+
+                            break;
+                        }
+                        case DEFAULT: {
+                            codeBlock.putNodeMetaData(IS_SWITCH_DEFAULT, true);
+
+                            statementList.add(
+                                    // this.configureAST(codeBlock, tuple.getKey())
+                                    codeBlock
+                            );
+
+                            break;
+                        }
+                    }
+
+                    return statementList;
+                });
+    }
+
+    private void validateSwitchExpressionLabels(SwitchExpressionContext ctx) {
+        Map<String, List<SwitchExpressionLabelContext>> acMap =
+                ctx.switchBlockStatementExpressionGroup().stream()
+                        .flatMap(e -> e.switchExpressionLabel().stream())
+                        .collect(Collectors.groupingBy(e -> e.ac.getText()));
+        if (acMap.size() > 1) {
+            List<SwitchExpressionLabelContext> lastSelcList = acMap.values().stream().reduce((prev, next) -> next).orElse(null);
+            throw createParsingFailedException(acMap.keySet().stream().collect(Collectors.joining("` and `", "`", "`")) + " cannot be used together", lastSelcList.get(0).ac);
+        }
+    }
+
+    @Override
+    public Tuple3<Token, List<Expression>, Integer> visitSwitchExpressionLabel(SwitchExpressionLabelContext ctx) {
+        final Integer acType = ctx.ac.getType();
+        if (asBoolean(ctx.CASE())) {
+            return tuple(ctx.CASE().getSymbol(), this.visitExpressionList(ctx.expressionList()), acType);
+        } else if (asBoolean(ctx.DEFAULT())) {
+            return tuple(ctx.DEFAULT().getSymbol(), Collections.singletonList(EmptyExpression.INSTANCE), acType);
+        }
+
+        throw createParsingFailedException("Unsupported switch expression label: " + ctx.getText(), ctx);
+    }
+
+
     // } statement -------------------------------------------------------------
 
     @Override
@@ -3619,7 +3888,12 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
 
     @Override
     public LambdaExpression visitStandardLambdaExpression(final StandardLambdaExpressionContext ctx) {
-        return configureAST(this.createLambda(ctx.standardLambdaParameters(), ctx.lambdaBody()), ctx);
+        switchExpressionRuleContextStack.push(ctx);
+        try {
+            return configureAST(this.createLambda(ctx.standardLambdaParameters(), ctx.lambdaBody()), ctx);
+        } finally {
+            switchExpressionRuleContextStack.pop();
+        }
     }
 
     private LambdaExpression createLambda(final StandardLambdaParametersContext standardLambdaParametersContext, final LambdaBodyContext lambdaBodyContext) {
@@ -3656,22 +3930,27 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
 
     @Override
     public ClosureExpression visitClosure(final ClosureContext ctx) {
-        visitingClosureCount += 1;
+        switchExpressionRuleContextStack.push(ctx);
+        try {
+            visitingClosureCount += 1;
 
-        Parameter[] parameters = asBoolean(ctx.formalParameterList())
-                ? this.visitFormalParameterList(ctx.formalParameterList())
-                : null;
+            Parameter[] parameters = asBoolean(ctx.formalParameterList())
+                    ? this.visitFormalParameterList(ctx.formalParameterList())
+                    : null;
 
-        if (!asBoolean(ctx.ARROW())) {
-            parameters = Parameter.EMPTY_ARRAY;
-        }
+            if (!asBoolean(ctx.ARROW())) {
+                parameters = Parameter.EMPTY_ARRAY;
+            }
 
-        Statement code = this.visitBlockStatementsOpt(ctx.blockStatementsOpt());
-        ClosureExpression result = configureAST(new ClosureExpression(parameters, code), ctx);
+            Statement code = this.visitBlockStatementsOpt(ctx.blockStatementsOpt());
+            ClosureExpression result = configureAST(new ClosureExpression(parameters, code), ctx);
 
-        visitingClosureCount -= 1;
+            visitingClosureCount -= 1;
 
-        return result;
+            return result;
+        } finally {
+            switchExpressionRuleContextStack.pop();
+        }
     }
 
     @Override
@@ -4664,6 +4943,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     private final List<ClassNode> classNodeList = new LinkedList<>();
     private final Deque<ClassNode> classNodeStack = new ArrayDeque<>();
     private final Deque<List<InnerClassNode>> anonymousInnerClassesDefinedInMethodStack = new ArrayDeque<>();
+    private final Deque<GroovyParserRuleContext> switchExpressionRuleContextStack = new ArrayDeque<>();
 
     private Tuple2<GroovyParserRuleContext, Exception> numberFormatError;
 
@@ -4725,4 +5005,5 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     private static final String INTEGER_LITERAL_TEXT = "_INTEGER_LITERAL_TEXT";
     private static final String FLOATING_POINT_LITERAL_TEXT = "_FLOATING_POINT_LITERAL_TEXT";
     private static final String ENCLOSING_INSTANCE_EXPRESSION = "_ENCLOSING_INSTANCE_EXPRESSION";
+    private static final String IS_YIELD_STATEMENT = "_IS_YIELD_STATEMENT";
 }
diff --git a/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java b/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
index 78e5877..addfd47 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/SemanticPredicates.java
@@ -42,6 +42,7 @@ import static org.apache.groovy.parser.antlr4.GroovyParser.PathExpressionContext
 import static org.apache.groovy.parser.antlr4.GroovyParser.PostfixExprAltContext;
 import static org.apache.groovy.parser.antlr4.GroovyParser.PostfixExpressionContext;
 import static org.apache.groovy.parser.antlr4.GroovyParser.StringLiteral;
+import static org.apache.groovy.parser.antlr4.GroovyParser.YIELD;
 import static org.apache.groovy.parser.antlr4.util.StringUtils.matches;
 
 /**
@@ -141,7 +142,7 @@ public class SemanticPredicates {
     public static boolean isInvalidMethodDeclaration(TokenStream ts) {
         int tokenType = ts.LT(1).getType();
 
-        return (Identifier == tokenType || CapitalizedIdentifier == tokenType || StringLiteral == tokenType)
+        return (Identifier == tokenType || CapitalizedIdentifier == tokenType || StringLiteral == tokenType || YIELD == tokenType)
                 && LPAREN == (ts.LT(2).getType());
     }
 
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_01x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_01x.groovy
index 3b288ca..448719e 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_01x.groovy
@@ -16,30 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+def result = switch(a) {
+    case 8 -> 'b'
+    default -> 'z'
+}
+assert 'z' == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_02x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_02x.groovy
index 3b288ca..5574d94 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_02x.groovy
@@ -16,30 +16,15 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 6
+def result = switch(a) {
+    case 6 -> 'a'
+}
+assert 'a' == result
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+a = 9
+result = switch(a) {
+    case 6 -> 'a'
+}
+assert null == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_03x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_03x.groovy
index 3b288ca..ef46adb 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_03x.groovy
@@ -16,30 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+def result = switch(a) {
+    case 6, 8 -> 'b'
+    default -> 'z'
+}
+assert 'b' == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_04x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_04x.groovy
index 3b288ca..8b773cb 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_04x.groovy
@@ -16,30 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 9
+def result = switch(a) {
+    case 6, 8 -> 'b'
+    case 9 -> 'c'
+    default -> 'z'
+}
+assert 'c' == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_05x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_05x.groovy
index 3b288ca..5a52c93 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_05x.groovy
@@ -16,30 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+def result = switch(a) {
+    case 6, 8 -> 1 + 2
+}
+assert 3 == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_06x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_06x.groovy
index 3b288ca..f864a24 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_06x.groovy
@@ -16,30 +16,15 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 6
+def result = switch(a) {
+    case 6, 8 -> 1.plus 2
+}
+assert 3 == result
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+a = 8
+result = switch(a) {
+    case 6, 8 -> 1.plus 2
+}
+assert 3 == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_07x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_07x.groovy
index 3b288ca..07e375b 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_07x.groovy
@@ -16,30 +16,24 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 9
+def result = switch(a) {
+    case 6, 8 -> 1.plus 2
+    default -> 1.plus 5
+}
+assert 6 == result
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
+a = 6
+result = switch(a) {
+    case 6, 8 -> 1.plus 2
+    default -> 1.plus 5
+}
+assert 3 == result
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+a = 8
+result = switch(a) {
+    case 6, 8 -> 1.plus 2
+    default -> 1.plus 5
+}
+assert 3 == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_08x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_08x.groovy
index 3b288ca..0b171f2 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_08x.groovy
@@ -16,30 +16,27 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 6
+def result = switch(a) {
+    case 6 -> { 'a' }
+}
+assert 'a' == result
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
+a = 6
+result = switch(a) {
+    case 6 -> { yield 'a' }
+}
+assert 'a' == result
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+a = 8
+result = switch(a) {
+    case 6, 8 -> { yield 'a' }
+}
+assert 'a' == result
+
+a = 9
+result = switch(a) {
+    case 6, 8 -> { yield 'a' }
+}
+assert null == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_09x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_09x.groovy
index 3b288ca..14e0dd0 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_09x.groovy
@@ -16,30 +16,14 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 9
+def result = switch(a) {
+    case 6 -> { yield 'a' }
+    default -> { yield 'z' }
+}
+assert 'z' == result
+
+
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_10x.groovy
similarity index 52%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_10x.groovy
index 3b288ca..450fb24 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_10x.groovy
@@ -16,30 +16,44 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 6
+def result = switch(a) {
+    case 6 -> {
+        def n = 1
+        yield 'a' + n
+    }
+    default -> { yield 'z' }
+}
+assert 'a1' == result
+
+a = 8
+result = switch(a) {
+    case 6, 8 -> {
+        def n = 1
+        yield 'a' + n
+    }
+    default -> { yield 'z' }
+}
+assert 'a1' == result
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
+a = 9
+result = switch(a) {
+    case 6, 8 -> {
+        def n = 1
+        yield 'a' + n
     }
+    default -> { yield 'z' }
+}
+assert 'z' == result
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+a = 9
+result = switch(a) {
+    case 6, 8 -> {
+        def n = 1
+        yield 'a' + n
     }
-}
\ No newline at end of file
+    default -> yield 'z'
+}
+assert 'z' == result
+
diff --git a/src/test-resources/core/SwitchExpression_11x.groovy b/src/test-resources/core/SwitchExpression_11x.groovy
new file mode 100644
index 0000000..b8d55f1
--- /dev/null
+++ b/src/test-resources/core/SwitchExpression_11x.groovy
@@ -0,0 +1,111 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+try {
+    def a = 6
+    def result = switch(a) {
+        case 6 : throw new RuntimeException('a')
+    }
+} catch (e) {
+    assert 'a' == e.message
+}
+
+a = 6
+result = switch(a) {
+    case 6 : yield 'a'
+}
+assert 'a' == result
+
+a = 8
+result = switch(a) {
+    case 6 : yield 'a'
+    default: yield 'b'
+}
+assert 'b' == result
+
+a = 9
+result = switch(a) {
+    case 6, 9 : yield 'a'
+    default: yield 'b'
+}
+assert 'a' == result
+
+a = 7
+result = switch(a) {
+    case 7:
+    case 6, 9 : yield 'a'
+    default: yield 'b'
+}
+assert 'a' == result
+
+
+a = 10
+result = switch(a) {
+    case 7:
+    case 6, 9 : yield 'a'
+    case 10:
+    case 11: yield 'c'
+    default: yield 'b'
+}
+assert 'c' == result
+
+a = 10
+result = switch(a) {
+    case 7:
+    case 6, 9 : yield 'a'
+    case 10:
+    case 11: {
+            def x = 1
+            yield 'c' + x
+        }
+    default: yield 'b'
+}
+assert 'c1' == result
+
+
+a = 6
+result = switch(a) {
+    case 6 : yield 'a'
+}
+assert 'a' == result
+
+a = 6
+result = switch(a) {
+    default : yield 'b'
+}
+assert 'b' == result
+
+a = 6
+result = switch(a) {
+    case 6 : { yield 'a' }
+}
+assert 'a' == result
+
+a = 6
+result = switch(a) {
+    default : { yield 'b' }
+}
+assert 'b' == result
+
+a = 6
+result = switch(a) {
+    case 6  : yield 'a'
+    default : yield 'b'
+}
+assert 'a' == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_12x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_12x.groovy
index 3b288ca..bbe8342 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_12x.groovy
@@ -16,30 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = 6
+def result = switch(a) {
+    case 6 -> 'a'
+    default-> yield 'b'
+}
+assert 'a' == result
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+a = 6
+result = switch(a) {
+    case 6 -> 'a'
+    default -> yield 'b'
+}
+assert 'a' == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_13x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_13x.groovy
index 3b288ca..4a2a7c8 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_13x.groovy
@@ -16,30 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def yield (String msg) { return msg }
+def yield () { return 'b' }
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def result = yield 'a'
+assert 'a' == result
+assert 'b'== yield()
diff --git a/src/test-resources/core/SwitchExpression_14x.groovy b/src/test-resources/core/SwitchExpression_14x.groovy
new file mode 100644
index 0000000..0a8a661
--- /dev/null
+++ b/src/test-resources/core/SwitchExpression_14x.groovy
@@ -0,0 +1,79 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+def test() {
+    def a = 2
+    def b = 1
+    def c = 0
+    def d = 99
+    def r = switch (a) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    } + switch (b) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    } + switch (c) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    } + switch (d) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    }
+    assert 'cbaz' == r
+}
+test()
+
+@groovy.transform.CompileStatic
+def testCS() {
+    def a = 2
+    def b = 1
+    def c = 0
+    def d = 99
+    def r = switch (a) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    } + switch (b) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    } + switch (c) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    } + switch (d) {
+        case 0 -> 'a'
+        case 1 -> 'b'
+        case 2 -> 'c'
+        default -> 'z'
+    }
+    assert 'cbaz' == r
+}
+testCS()
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_15x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_15x.groovy
index 3b288ca..58b3a12 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_15x.groovy
@@ -16,30 +16,15 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+def a = 9
+def b = 8
+def result = switch(a) {
+    case 8 -> 'a'
+    case 9 -> switch(b) {
+        case 8 -> 'b'
+        default -> 'c'
     }
-}
\ No newline at end of file
+    default -> 'd'
+}
+assert 'b' == result
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_16x.groovy
similarity index 52%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_16x.groovy
index 3b288ca..028d624 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_16x.groovy
@@ -16,30 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
+def a = 6
+try {
+    switch(a) {
+        case 8 -> 'b'
+        default -> throw new RuntimeException('z')
     }
+} catch (e) {
+    assert 'z' == e.message
+}
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+def r = switch(a) {
+    case 6 -> {
+        def x = 'a'
+        yield x
     }
-}
\ No newline at end of file
+    default -> throw new RuntimeException('z')
+}
+assert 'a' == r
+
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_17x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_17x.groovy
index 3b288ca..aff965b 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_17x.groovy
@@ -16,30 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+def a = '123'
+def r = switch (a) {
+    case String -> 1
+    default -> 2
+}
+assert 1 == r
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+a = 123
+r = switch (a) {
+    case String -> 1
+    default -> 2
+}
+assert 2 == r
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_18x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_18x.groovy
index 3b288ca..ba57d6b 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_18x.groovy
@@ -16,30 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+cnt = 0
+void prt() { cnt++ }
+def a = '123'
+switch (a) {
+    case String -> { prt() }
+}
+assert 1 == cnt
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_19x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_19x.groovy
index 3b288ca..f65840e 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_19x.groovy
@@ -16,30 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+cnt = 0
+void prt() { cnt++ }
+def a = '123'
+switch (a) {
+    case String -> prt()
+}
+assert 1 == cnt
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_20x.groovy
similarity index 52%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_20x.groovy
index 3b288ca..f0eec8d 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_20x.groovy
@@ -16,30 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+import groovy.transform.CompileStatic
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
+@CompileStatic
+String same(String s) { s }
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
+@CompileStatic
+def meth() {
+    def a = 1
+    def r = switch (a) {
+        case 1 -> {
+            if (true) {
+                same 'a'
+            } else {
+                same 'b'
             }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+        }
     }
-}
\ No newline at end of file
+    r + 'z'
+}
+
+assert 'az' == meth()
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_21x.groovy
similarity index 52%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_21x.groovy
index 3b288ca..55bac5a 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_21x.groovy
@@ -16,30 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+import groovy.transform.CompileStatic
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
+@CompileStatic
+String same(String s) { s }
 
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
+@CompileStatic
+def meth() {
+    def a = 1
+    def r = switch (a) {
+        case 1 -> {
+            if (2 == 2) {
+                yield 'hello'
             }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+            yield 'hi'
+        }
+        case 2 -> 'Hello'
     }
-}
\ No newline at end of file
+    r + ', Daniel'
+}
+
+assert 'hello, Daniel' == meth()
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_22x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_22x.groovy
index 3b288ca..ae410da 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_22x.groovy
@@ -16,30 +16,16 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+import java.time.Month
+import static java.time.Month.*
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+Month month = JUNE
+String quarter = switch (month) {
+    case JANUARY, FEBRUARY, MARCH -> "First Quarter"
+    case APRIL, MAY, JUNE -> "Second Quarter"
+    case JULY, AUGUST, SEPTEMBER -> "Third Quarter"
+    case OCTOBER, NOVEMBER, DECEMBER -> "Forth Quarter"
+    default -> "Unknown Quarter"
+}
+assert 'Second Quarter' == quarter
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_23x.groovy
similarity index 52%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_23x.groovy
index 3b288ca..31b5a14 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_23x.groovy
@@ -16,30 +16,24 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+import java.time.Month
+import static java.time.Month.*
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
+Month month = JUNE
+String quarter = switch (month) {
+    case JANUARY,
+        FEBRUARY,
+        MARCH -> {
+            yield "First Quarter"
+        }
+    case APRIL, MAY, JUNE -> {
+        yield "Second Quarter"
     }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+    case JULY, AUGUST, SEPTEMBER -> "Third Quarter"
+    case OCTOBER, NOVEMBER, DECEMBER -> {
+        yield "Forth Quarter"
     }
-}
\ No newline at end of file
+    default -> "Unknown Quarter"
+}
+assert 'Second Quarter' == quarter
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/core/SwitchExpression_24x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/core/SwitchExpression_24x.groovy
index 3b288ca..785008e 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/core/SwitchExpression_24x.groovy
@@ -16,30 +16,29 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
+import java.time.Month
+import static java.time.Month.*
 
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+Month month = JUNE
+String quarter = switch (month) {
+    case JANUARY:
+    case FEBRUARY:
+    case MARCH:
+        yield "First Quarter"
+    case APRIL:
+    case MAY:
+    case JUNE:
+        yield "Second Quarter"
+    case JULY:
+    case AUGUST:
+    case SEPTEMBER:
+        yield "Third Quarter"
+    case OCTOBER:
+    case NOVEMBER:
+    case DECEMBER:
+        yield "Forth Quarter"
+    default:
+        yield "Unknown Quarter"
+}
+assert 'Second Quarter' == quarter
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_01x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_01x.groovy
index 3b288ca..df57b27 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_01x.groovy
@@ -16,30 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+switch(a) {
+    case 8 ->
+    case 9 -> 'a'
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_02x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_02x.groovy
index 3b288ca..8112793 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_02x.groovy
@@ -16,30 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+switch(a) {
+    case 8 ->
+    default -> 'b'
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_03x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_03x.groovy
index 3b288ca..64ddad8 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_03x.groovy
@@ -16,30 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+switch(a) {
+    case 6 ->
+    case 8 ->
+    default -> 'b'
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_04x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_04x.groovy
index 3b288ca..82d52da 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_04x.groovy
@@ -16,30 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+switch(a) {
+    case 6 -> 'a'
+    case 8 : yield 'b'
+    default -> 'c'
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_05x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_05x.groovy
index 3b288ca..13fbb69 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_05x.groovy
@@ -16,30 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+def r = switch(a) {
+    case 6 : 'a'
+    default : 'c'
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_06x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_06x.groovy
index 3b288ca..a799824 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_06x.groovy
@@ -16,30 +16,9 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
-    }
-}
\ No newline at end of file
+def a = 6
+def r = switch(a) {
+    case 6 : return 'a'
+    default : return 'c'
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_07x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_07x.groovy
index 3b288ca..592051c 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_07x.groovy
@@ -16,30 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+def a = 7
+while (a-- > 0) {
+    def r = switch(a) {
+        case 6 : break
+        default : return 'c'
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test-resources/fail/SwitchExpression_08x.groovy
similarity index 51%
copy from src/test/groovy/MethodInBadPositionTest.groovy
copy to src/test-resources/fail/SwitchExpression_08x.groovy
index 3b288ca..3c61cfd 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test-resources/fail/SwitchExpression_08x.groovy
@@ -16,30 +16,11 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy
 
-import gls.CompilableTestSupport
-
-class MethodInBadPositionTest extends CompilableTestSupport {
-    /** GROOVY-4215 */
-    void testMethodDefinitionInClosure() {
-        def msg = shouldNotCompile('''
-            { ->
-                def say(String msg) {
-                  println(msg)
-                }
-            }()
-        ''')
-        assert msg.contains('Method definition not expected here') || msg.contains("Unexpected input: '('")
-    }
-
-    /** GROOVY-4215 */
-    void testXMethodDefinitionInSwitch() {
-        def msg = shouldNotCompile('''
-            switch(1) {
-                case 1: def say(){}
-            }
-        ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+def a = 7
+while (a-- > 0) {
+    def r = switch(a) {
+        case 6 : continue
+        default : return 'c'
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/groovy/MethodInBadPositionTest.groovy b/src/test/groovy/MethodInBadPositionTest.groovy
index 3b288ca..453d75c 100644
--- a/src/test/groovy/MethodInBadPositionTest.groovy
+++ b/src/test/groovy/MethodInBadPositionTest.groovy
@@ -40,6 +40,6 @@ class MethodInBadPositionTest extends CompilableTestSupport {
                 case 1: def say(){}
             }
         ''')
-        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('")
+        assert msg.contains('Method definition not expected here')  || msg.contains("Unexpected input: '('") || msg.contains("Unexpected input: 'switch(1)")
     }
 }
\ No newline at end of file
diff --git a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index f7f0e59..506d6c0 100644
--- a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -412,15 +412,42 @@ final class GroovyParserTest extends GroovyTestCase {
     }
 
     void "test groovy core - var"() {
-        doRunAndTestAntlr4('core/Var_01x.groovy');
+        doRunAndTestAntlr4('core/Var_01x.groovy')
     }
 
     void "test groovy core - String"() {
-        doRunAndTestAntlr4('core/String_01x.groovy');
+        doRunAndTestAntlr4('core/String_01x.groovy')
     }
 
     void "test groovy core - NonStaticClass"() {
-        doRunAndTestAntlr4('core/NonStaticClass_01x.groovy');
+        doRunAndTestAntlr4('core/NonStaticClass_01x.groovy')
+    }
+
+    void "test groovy core - SwitchExpression"() {
+        doRunAndTestAntlr4('core/SwitchExpression_01x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_02x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_03x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_04x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_05x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_06x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_07x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_08x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_09x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_10x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_11x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_12x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_13x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_14x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_15x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_16x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_17x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_18x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_19x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_20x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_21x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_22x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_23x.groovy')
+        doRunAndTestAntlr4('core/SwitchExpression_24x.groovy')
     }
 
     void "test groovy core - BUG"() {
@@ -445,30 +472,30 @@ final class GroovyParserTest extends GroovyTestCase {
     }
 
     void "test groovy core - GROOVY-9427"() {
-        doTest('bugs/BUG-GROOVY-9427.groovy');
+        doTest('bugs/BUG-GROOVY-9427.groovy')
     }
 
     void "test groovy core - GROOVY-9433"() {
-        doTest('bugs/BUG-GROOVY-9433.groovy');
+        doTest('bugs/BUG-GROOVY-9433.groovy')
     }
 
     void "test groovy core - GROOVY-9449"() {
-        doTest('bugs/BUG-GROOVY-9449.groovy');
+        doTest('bugs/BUG-GROOVY-9449.groovy')
     }
 
     void "test groovy core - GROOVY-9511"() {
-        doTest('bugs/BUG-GROOVY-9511.groovy', [MethodNode]);
+        doTest('bugs/BUG-GROOVY-9511.groovy', [MethodNode])
     }
 
     void "test groovy core - GROOVY-9507"() {
-        doTest('bugs/BUG-GROOVY-9507.groovy');
+        doTest('bugs/BUG-GROOVY-9507.groovy')
     }
 
     void "test groovy core - GROOVY-9522"() {
-        doTest('bugs/BUG-GROOVY-9522.groovy');
+        doTest('bugs/BUG-GROOVY-9522.groovy')
     }
 
     void "test groovy core - GROOVY-9692"() {
-        doTest('bugs/BUG-GROOVY-9692.groovy');
+        doTest('bugs/BUG-GROOVY-9692.groovy')
     }
 }
diff --git a/src/test/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy b/src/test/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
index 3b993f7..e5ecbae 100644
--- a/src/test/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
+++ b/src/test/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
@@ -241,7 +241,7 @@ final class SyntaxErrorTest extends GroovyTestCase {
     }
 
     void 'test groovy core - AnnotationDeclaration 1'() {
-        TestUtils.doRunAndShouldFail('fail/AnnotationDeclaration_01x.groovy');
+        TestUtils.doRunAndShouldFail('fail/AnnotationDeclaration_01x.groovy')
     }
 
     void 'test groovy core - AnnotationDeclaration 2'() {
@@ -420,6 +420,17 @@ final class SyntaxErrorTest extends GroovyTestCase {
         TestUtils.doRunAndShouldFail('fail/Array_02x.groovy')
     }
 
+    void "test groovy core - SwitchExpression"() {
+        TestUtils.doRunAndShouldFail('fail/SwitchExpression_01x.groovy')
+        TestUtils.doRunAndShouldFail('fail/SwitchExpression_02x.groovy')
+        TestUtils.doRunAndShouldFail('fail/SwitchExpression_03x.groovy')
+        TestUtils.doRunAndShouldFail('fail/SwitchExpression_04x.groovy')
+        TestUtils.doRunAndShouldFail('fail/SwitchExpression_05x.groovy')
+        TestUtils.doRunAndShouldFail('fail/SwitchExpression_06x.groovy')
+		TestUtils.doRunAndShouldFail('fail/SwitchExpression_07x.groovy')
+		TestUtils.doRunAndShouldFail('fail/SwitchExpression_08x.groovy')
+    }
+
     @NotYetImplemented
     void 'test error alternative - Missing ")" 1'() {
         def err = expectParseError '''\
diff --git a/src/test/org/apache/groovy/parser/antlr4/TestUtils.groovy b/src/test/org/apache/groovy/parser/antlr4/TestUtils.groovy
index 3310447..c8aae4b 100644
--- a/src/test/org/apache/groovy/parser/antlr4/TestUtils.groovy
+++ b/src/test/org/apache/groovy/parser/antlr4/TestUtils.groovy
@@ -198,7 +198,7 @@ final class TestUtils {
     }
 
     static void doRunAndTestAntlr4(String path, CompilerConfiguration compilerConfiguration = CompilerConfiguration.DEFAULT) {
-        assert executeScript(createAntlr4Shell(compilerConfiguration), "$RESOURCES_PATH/$path")
+        assert executeScript(createAntlr4Shell(compilerConfiguration), path)
     }
 
     static void doRunAndTestAntlr2(String path, CompilerConfiguration compilerConfiguration = CompilerConfiguration.DEFAULT) {
@@ -255,7 +255,8 @@ final class TestUtils {
     }
 
     private static boolean executeScript(GroovyShell shell, String path) {
-        def file = new File(path)
+        File file = new File("$RESOURCES_PATH/$path")
+        assert file.exists() : "Test resource not found: $file.absolutePath"
         try {
             shell.evaluate(file.text)
             return true
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/text/SmartDocumentFilter.java b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/text/SmartDocumentFilter.java
index 4496873..cdf55b2 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/text/SmartDocumentFilter.java
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/text/SmartDocumentFilter.java
@@ -108,6 +108,7 @@ import static org.apache.groovy.parser.antlr4.GroovyLexer.VAR;
 import static org.apache.groovy.parser.antlr4.GroovyLexer.VOID;
 import static org.apache.groovy.parser.antlr4.GroovyLexer.VOLATILE;
 import static org.apache.groovy.parser.antlr4.GroovyLexer.WHILE;
+import static org.apache.groovy.parser.antlr4.GroovyLexer.YIELD;
 
 
 /**
@@ -378,7 +379,7 @@ public class SmartDocumentFilter extends DocumentFilter {
                 VAR, BuiltInPrimitiveType, ABSTRACT, ASSERT, BREAK, CASE, CATCH, CLASS, CONST, CONTINUE, DEFAULT, DO,
                 ELSE, ENUM, EXTENDS, FINAL, FINALLY, FOR, IF, GOTO, IMPLEMENTS, IMPORT, INSTANCEOF, INTERFACE,
                 NATIVE, NEW, PACKAGE, PRIVATE, PROTECTED, PUBLIC, RETURN, STATIC, STRICTFP, SUPER, SWITCH, SYNCHRONIZED,
-                THIS, THROW, THROWS, TRANSIENT, TRY, VOID, VOLATILE, WHILE, NullLiteral, BooleanLiteral)) {
+                THIS, THROW, THROWS, TRANSIENT, TRY, VOID, VOLATILE, WHILE, YIELD, NullLiteral, BooleanLiteral)) {
             Style style = createDefaultStyleByTokenType(t);
             StyleConstants.setBold(style, true);
             StyleConstants.setForeground(style, Color.BLUE.darker().darker());
diff --git a/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc b/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc
index 51dedae..fae4474 100644
--- a/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc
+++ b/subprojects/groovy-ginq/src/spec/doc/ginq-userguide.adoc
@@ -912,6 +912,13 @@ GINQ does not support `with` clause for now. We could define a temporary variabl
 include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_tips_12,indent=0]
 ----
 
+==== Alternative for `case-when`
+`case-when` of SQL could be replaced with switch expression:
+[source, groovy]
+----
+include::../test/org/apache/groovy/ginq/GinqTest.groovy[tags=ginq_tips_13,indent=0]
+----
+
 ==== Query JSON
 [source, groovy]
 ----
diff --git a/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy b/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
index 92bf5bc..18182f1 100644
--- a/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
+++ b/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
@@ -5886,6 +5886,22 @@ class GinqTest {
     }
 
     @Test
+    void "testGinq - switch - 1"() {
+        assertGinqScript '''
+// tag::ginq_tips_13[]
+            assert ['a', 'b', 'c', 'c'] == GQ {
+                from n in [1, 2, 3, 4]
+                select switch (n) {
+                    case 1 -> 'a'
+                    case 2 -> 'b'
+                    default -> 'c'
+                }
+            }.toList()
+// end::ginq_tips_13[]
+        '''
+    }
+
+    @Test
     void "testGinq - shutdown - 0"() {
         assertScript '''
             import org.apache.groovy.ginq.provider.collection.runtime.QueryableHelper

[groovy] 04/09: GROOVY-10173: Bump checkstyle to 8.44

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 88aa33b4aa4c14d986feb3377dca917d9a11b1df
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:53:52 2021 +1000

    GROOVY-10173: Bump checkstyle to 8.44
---
 versions.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/versions.properties b/versions.properties
index ed3feac..c03729f 100644
--- a/versions.properties
+++ b/versions.properties
@@ -49,7 +49,7 @@ xstream = 1.4.17
 spock = 2.0-groovy-3.0
 spotbugs = 4.3.0
 spotbugsAnnotations = 4.3.0
-checkstyle = 8.41.1
+checkstyle = 8.44
 junit5 = 5.7.1
 junit5Platform = 1.7.1
 jcipAnnotations = 1.0

[groovy] 03/09: GROOVY-10172: Bump Spotbugs version to 4.3.0

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 6a9f77aa3241d4a93ccf4e6636c9f206102146a1
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:51:13 2021 +1000

    GROOVY-10172: Bump Spotbugs version to 4.3.0
---
 versions.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/versions.properties b/versions.properties
index 73ce1ff..ed3feac 100644
--- a/versions.properties
+++ b/versions.properties
@@ -47,8 +47,8 @@ xmlunit = 1.6
 xstream = 1.4.17
 # running with Groovy 4 can be allowed with -Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true
 spock = 2.0-groovy-3.0
-spotbugs = 4.2.3
-spotbugsAnnotations = 4.2.3
+spotbugs = 4.3.0
+spotbugsAnnotations = 4.3.0
 checkstyle = 8.41.1
 junit5 = 5.7.1
 junit5Platform = 1.7.1

[groovy] 02/09: GROOVY-10171: Bump slf4j to 1.7.31

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 5c1485372a9d00ed7bfdeca95ea8a8f8563b576a
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:49:37 2021 +1000

    GROOVY-10171: Bump slf4j to 1.7.31
---
 src/test/groovy/bugs/Groovy6932Bug.groovy                               | 2 +-
 src/test/groovy/bugs/Groovy8060Bug.groovy                               | 2 +-
 .../codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy  | 2 +-
 versions.properties                                                     | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/test/groovy/bugs/Groovy6932Bug.groovy b/src/test/groovy/bugs/Groovy6932Bug.groovy
index 8dabe24..3dabebe 100644
--- a/src/test/groovy/bugs/Groovy6932Bug.groovy
+++ b/src/test/groovy/bugs/Groovy6932Bug.groovy
@@ -23,7 +23,7 @@ import groovy.test.GroovyTestCase
 class Groovy6932Bug extends GroovyTestCase {
     void testLoggingWithinClosuresShouldHaveGuards() {
         assertScript '''
-            @Grab('org.slf4j:slf4j-simple:1.7.30')
+            @Grab('org.slf4j:slf4j-simple:1.7.31')
             import groovy.util.logging.Slf4j
 
             new TestCode().doSomethingThatLogs()
diff --git a/src/test/groovy/bugs/Groovy8060Bug.groovy b/src/test/groovy/bugs/Groovy8060Bug.groovy
index a41f4c3..937a587 100644
--- a/src/test/groovy/bugs/Groovy8060Bug.groovy
+++ b/src/test/groovy/bugs/Groovy8060Bug.groovy
@@ -23,7 +23,7 @@ import groovy.test.GroovyTestCase
 class Groovy8060Bug extends GroovyTestCase {
     void testLoggingWithinClosuresThatAreMethodArgsShouldHaveGuards() {
         assertScript '''
-            @Grab('org.slf4j:slf4j-simple:1.7.30')
+            @Grab('org.slf4j:slf4j-simple:1.7.31')
             import groovy.util.logging.Slf4j
 
             @Slf4j
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
index 76ad1b4..671ef8c 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
@@ -88,7 +88,7 @@ final class StaticCompileFlowTypingTest {
                 @Grab('javax.servlet:javax.servlet-api:3.0.1'),
                 @Grab('org.grails.plugins:converters:3.3.+'),
                 @Grab('org.grails:grails-web:3.3.+'),
-                @Grab('org.slf4j:slf4j-nop:1.7.30')
+                @Grab('org.slf4j:slf4j-nop:1.7.31')
             ])
             @GrabExclude('org.codehaus.groovy:*')
             import static grails.converters.JSON.parse
diff --git a/versions.properties b/versions.properties
index 55778b3..73ce1ff 100644
--- a/versions.properties
+++ b/versions.properties
@@ -42,7 +42,7 @@ log4j2 = 2.14.1
 openbeans = 1.0.2
 picocli = 4.6.1
 qdox = 1.12.1
-slf4j = 1.7.30
+slf4j = 1.7.31
 xmlunit = 1.6
 xstream = 1.4.17
 # running with Groovy 4 can be allowed with -Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true

[groovy] 07/09: GROOVY-10168: Bump json-unit version to 2.27.0

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 6930c23210704ccb6fa441ac3fe1c9f6f0d11bb1
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:56:05 2021 +1000

    GROOVY-10168: Bump json-unit version to 2.27.0
---
 subprojects/groovy-json/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/subprojects/groovy-json/build.gradle b/subprojects/groovy-json/build.gradle
index 0e3fc2c..a0b0c5f 100644
--- a/subprojects/groovy-json/build.gradle
+++ b/subprojects/groovy-json/build.gradle
@@ -24,7 +24,7 @@ dependencies {
     api rootProject  // JsonBuilder extends GroovyObjectSupport...
     testImplementation project(':groovy-test')
     testImplementation project(':groovy-dateutil')
-    testImplementation 'net.javacrumbs.json-unit:json-unit:2.25.0'
+    testImplementation 'net.javacrumbs.json-unit:json-unit:2.27.0'
     testRuntimeOnly "org.slf4j:slf4j-api:${versions.slf4j}"
     testRuntimeOnly project(':groovy-ant') // for JavadocAssertionTests
     testRuntimeOnly 'com.google.code.gson:gson:2.8.6' // json-unit requires gson, jackson1, or jackson2

[groovy] 09/09: update dependency metadata

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit b1108b0fdca7bc53642473d19424683d5bf76d9f
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:59:16 2021 +1000

    update dependency metadata
---
 gradle/verification-metadata.xml | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 305d76d..bd5650d 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -364,6 +364,11 @@
             <pgp value="afcc4c7594d09e2182c60e0f7a01b0f236e5430f"/>
          </artifact>
       </component>
+      <component group="com.google.code.gson" name="gson" version="2.8.7">
+         <artifact name="gson-2.8.7.jar">
+            <pgp value="c7be5bcc9fec15518cfda882b0f3710fa64900e7"/>
+         </artifact>
+      </component>
       <component group="com.google.errorprone" name="error_prone_annotations" version="2.2.0">
          <artifact name="error_prone_annotations-2.2.0.jar">
             <pgp value="e77417ac194160a3fabd04969a259c7ee636c5ed"/>
@@ -374,6 +379,11 @@
             <pgp value="7615ad56144df2376f49d98b1669c4bb543e0445"/>
          </artifact>
       </component>
+      <component group="com.google.errorprone" name="error_prone_annotations" version="2.5.1">
+         <artifact name="error_prone_annotations-2.5.1.jar">
+            <pgp value="e77417ac194160a3fabd04969a259c7ee636c5ed"/>
+         </artifact>
+      </component>
       <component group="com.google.guava" name="failureaccess" version="1.0.1">
          <artifact name="failureaccess-1.0.1.jar">
             <pgp value="694621a7227d8d5289699830abe9f3126bb741c1"/>
@@ -425,8 +435,8 @@
             <sha512 value="3f205ad4e7b8dd11c48d3c9203128e37e432b92b90e6052545d34ce6b602374d81840b64e3cca41fe3bcb5c7ab1053e587b1b940d11d486f5aa72380ebf7d6e5" origin="Generated by Gradle because artifact wasn't signed"/>
          </artifact>
       </component>
-      <component group="com.puppycrawl.tools" name="checkstyle" version="8.41.1">
-         <artifact name="checkstyle-8.41.1.jar">
+      <component group="com.puppycrawl.tools" name="checkstyle" version="8.44">
+         <artifact name="checkstyle-8.44.jar">
             <pgp value="06d34ed6ff73de368a772a781063fe98bcecb758"/>
          </artifact>
       </component>
@@ -667,6 +677,11 @@
             <sha512 value="5af320643a40ecd3a998c6624e279d5f91999e401d77047cef3f19371dcdfd518af03382d749bcab9985c5fc07faf199c3d8e8244f773df761e4e86017d7a455" origin="Generated by Gradle because artifact wasn't signed"/>
          </artifact>
       </component>
+      <component group="net.sf.saxon" name="Saxon-HE" version="10.5">
+         <artifact name="Saxon-HE-10.5.jar">
+            <pgp value="d9aa7402ba75f78720d975211d185615d0a84648"/>
+         </artifact>
+      </component>
       <component group="net.sourceforge.cobertura" name="cobertura" version="1.9.4.1">
          <artifact name="cobertura-1.9.4.1.jar">
             <sha512 value="827e21e51ceec0ddf37814ee40c7ac0521652262e5b87ae6e7e0f054b041491fb6d97fcd14bf89286c9ae16f590d73b0afdae4fc5b4f4231ccc44a340948882b" origin="Generated by Gradle because artifact wasn't signed"/>
@@ -808,6 +823,11 @@
             <pgp value="19beab2d799c020f17c69126b16698a4adf4d638"/>
          </artifact>
       </component>
+      <component group="org.checkerframework" name="checker-qual" version="3.8.0">
+         <artifact name="checker-qual-3.8.0.jar">
+            <pgp value="19beab2d799c020f17c69126b16698a4adf4d638"/>
+         </artifact>
+      </component>
       <component group="org.codehaus.gpars" name="gpars" version="1.2.1">
          <artifact name="gpars-1.2.1.jar">
             <sha512 value="b9583f7923425ffa2df6b986374325b926385f1f6dd0468333253ed71461b7d150c5f3ad905266558c63dcf113defb42ce8c83ad728e1efa87f622a5a6d235f9" origin="Generated by Gradle because a key couldn't be downloaded"/>

[groovy] 08/09: GROOVY-10169: Bump Ant version to 1.10.11 (incorporates CVE-2021-36373 and CVE-2021-36374)

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 96616ac54b514d9f2299ed68d936ec16cd0e62ac
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:56:31 2021 +1000

    GROOVY-10169: Bump Ant version to 1.10.11 (incorporates CVE-2021-36373 and CVE-2021-36374)
---
 versions.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/versions.properties b/versions.properties
index 343e40c..d980a50 100644
--- a/versions.properties
+++ b/versions.properties
@@ -13,7 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-ant = 1.10.10
+ant = 1.10.11
 asciidoctorj = 2.4.3
 asciidoctorDiagram = 2.1.0
 asciidoctorPdf = 1.5.4

[groovy] 05/09: GROOVY-10170: Bump JUnit Jupiter/JUnit Platform to 5.7.2/1.7.2

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 04024b014e23fc3f5fe049dd58926e0e36a73835
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Jul 14 22:54:40 2021 +1000

    GROOVY-10170: Bump JUnit Jupiter/JUnit Platform to 5.7.2/1.7.2
---
 versions.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/versions.properties b/versions.properties
index c03729f..a36e880 100644
--- a/versions.properties
+++ b/versions.properties
@@ -50,8 +50,8 @@ spock = 2.0-groovy-3.0
 spotbugs = 4.3.0
 spotbugsAnnotations = 4.3.0
 checkstyle = 8.44
-junit5 = 5.7.1
-junit5Platform = 1.7.1
+junit5 = 5.7.2
+junit5Platform = 1.7.2
 jcipAnnotations = 1.0
 treelayout = 1.0.3
 javaxServletApi = 4.0.1