You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/07/24 11:47:57 UTC

[groovy] branch master updated: Revert groovy deconstruction for switch-expression

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

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


The following commit(s) were added to refs/heads/master by this push:
     new fb502bd  Revert groovy deconstruction for switch-expression
fb502bd is described below

commit fb502bd53023838b735a0fda3e825fad5bf8dd1e
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jul 24 19:47:41 2021 +0800

    Revert groovy deconstruction for switch-expression
---
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 57 ++---------------
 src/spec/doc/core-semantics.adoc                   |  9 +--
 src/spec/test/SemanticsTest.groovy                 | 40 +-----------
 .../core/SwitchExpression_27x.groovy               | 29 ---------
 .../core/SwitchExpression_28x.groovy               | 74 ----------------------
 .../core/SwitchExpression_29x.groovy               | 29 ---------
 .../groovy/parser/antlr4/GroovyParserTest.groovy   |  3 -
 7 files changed, 8 insertions(+), 233 deletions(-)

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 3e81754..621bc0c 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -350,11 +350,9 @@ import static org.apache.groovy.parser.antlr4.util.PositionConfigureUtils.config
 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.castX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.closureX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.declS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.localVarX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
 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;
@@ -366,7 +364,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);
@@ -1145,13 +1142,9 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         switchExpressionRuleContextStack.push(ctx);
         try {
             validateSwitchExpressionLabels(ctx);
-            final String variableName = SWITCH_EXPRESSION_VARIABLE_NAME_PREFIX + switchExpressionVariableSeq++;
             List<Tuple3<List<Statement>, Boolean, Boolean>> statementInfoList =
                     ctx.switchBlockStatementExpressionGroup().stream()
-                            .map(e -> {
-                                e.putNodeMetaData(SWITCH_EXPRESSION_VARIABLE_NAME, variableName);
-                                return this.visitSwitchBlockStatementExpressionGroup(e);
-                            })
+                            .map(e -> this.visitSwitchBlockStatementExpressionGroup(e))
                             .collect(Collectors.toList());
 
             Boolean isArrow = statementInfoList.get(0).getV2();
@@ -1189,6 +1182,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                 throw createParsingFailedException("default case should appear at last", defaultStatementList.get(0));
             }
 
+            String variableName = "__$$sev" + switchExpressionVariableSeq++;
             Statement declarationStatement = declS(localVarX(variableName), this.visitExpressionInPar(ctx.expressionInPar()));
             SwitchStatement switchStatement = configureAST(
                     new SwitchStatement(
@@ -1211,7 +1205,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         }
     }
     private int switchExpressionVariableSeq;
-    private int switchExpressionCastedVariableSeq;
 
     @Override
     @SuppressWarnings("unchecked")
@@ -1306,8 +1299,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                         }
                     }
 
-                    VariableExpression switchExpressionVar = varX((String) ctx.getNodeMetaData(SWITCH_EXPRESSION_VARIABLE_NAME));
-
                     switch (tuple.getV1().getType()) {
                         case CASE: {
                             if (!asBoolean(statementList)) {
@@ -1316,22 +1307,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
 
                             for (int i = 0, n = tuple.getV2().size(); i < n; i++) {
                                 Expression expr = tuple.getV2().get(i);
-                                MethodCallExpression mce = expr.getNodeMetaData(SWITCH_EXPRESSION_DECONSTRUCTED);
-                                BlockStatement newCodeBlock = codeBlock;
-                                if (null != mce) {
-                                    final String methodName = mce.getMethodAsString();
-                                    final String castedVariableName = SWITCH_EXPRESSION_CASTED_VARIABLE_NAME_PREFIX + switchExpressionCastedVariableSeq++;
-                                    Statement declarationCastStatement = declS(localVarX(castedVariableName), castX(ClassHelper.make(methodName), switchExpressionVar));
-                                    List<Statement> declarationStatementList = ((TupleExpression) mce.getArguments()).getExpressions().stream().map(arg -> {
-                                        String argName = arg.getText();
-                                        return declS(localVarX(argName), propX(varX(castedVariableName), argName));
-                                    }).collect(Collectors.toList());
-                                    newCodeBlock =
-                                            createBlockStatement(
-                                                    Stream.concat(Stream.of(declarationCastStatement),
-                                                            Stream.concat(declarationStatementList.stream(), Stream.of(codeBlock)))
-                                                            .collect(Collectors.toList()));
-                                }
 
                                 statementList.add(
                                         configureAST(
@@ -1339,7 +1314,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                                                         expr,
 
                                                         // check whether processing the last label. if yes, block statement should be attached.
-                                                        (isLast && i == n - 1) ? newCodeBlock
+                                                        (isLast && i == n - 1) ? codeBlock
                                                                 : EmptyStatement.INSTANCE
                                                 ),
                                                 firstLabelHolder.get(0)));
@@ -1380,27 +1355,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     public Tuple3<Token, List<Expression>, Integer> visitSwitchExpressionLabel(SwitchExpressionLabelContext ctx) {
         final Integer acType = ctx.ac.getType();
         if (asBoolean(ctx.CASE())) {
-            List<Expression> expressionList = this.visitExpressionList(ctx.expressionList());
-            expressionList = expressionList.stream().map(expr -> {
-                if (expr instanceof MethodCallExpression) {
-                    MethodCallExpression mce = (MethodCallExpression) expr;
-                    String methodName = mce.getMethodAsString();
-                    if (mce.isImplicitThis() && Character.isUpperCase(methodName.charAt(0))) {
-                        List<Expression> argList = ((TupleExpression) mce.getArguments()).getExpressions();
-                        boolean allVariableArgs = !argList.isEmpty() && argList.stream()
-                                .allMatch(arg -> arg instanceof VariableExpression
-                                        && Character.isLowerCase(((VariableExpression) arg).getName().charAt(0)));
-                        if (allVariableArgs) {
-                            VariableExpression variableExpression = new VariableExpression(methodName);
-                            variableExpression.putNodeMetaData(SWITCH_EXPRESSION_DECONSTRUCTED, expr);
-                            return variableExpression;
-                        }
-                    }
-                }
-
-                return expr;
-            }).collect(Collectors.toList());
-            return tuple(ctx.CASE().getSymbol(), expressionList, acType);
+            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);
         }
@@ -5088,8 +5043,4 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     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";
-    private static final String SWITCH_EXPRESSION_DECONSTRUCTED = "_SWITCH_EXPRESSION_DECONSTRUCTED";
-    private static final String SWITCH_EXPRESSION_VARIABLE_NAME = "_SWITCH_EXPRESSION_VARIABLE_NAME";
-    private static final String SWITCH_EXPRESSION_VARIABLE_NAME_PREFIX = "__$$sev";
-    private static final String SWITCH_EXPRESSION_CASTED_VARIABLE_NAME_PREFIX = "__$$sevc";
 }
diff --git a/src/spec/doc/core-semantics.adoc b/src/spec/doc/core-semantics.adoc
index afbe6ef..697c2b6 100644
--- a/src/spec/doc/core-semantics.adoc
+++ b/src/spec/doc/core-semantics.adoc
@@ -189,16 +189,11 @@ Switch supports the following kinds of comparisons:
 
 NOTE: When using a closure case value, the default `it` parameter is actually the switch value (in our example, variable `x`).
 
-Groovy also supports switch expressions as shown in the following examples:
+Groovy also supports switch expressions as shown in the following example:
 
 [source,groovy]
 ----
-include::../test/SemanticsTest.groovy[tags=switch_expression_01,indent=0]
-----
-
-[source,groovy]
-----
-include::../test/SemanticsTest.groovy[tags=switch_expression_02,indent=0]
+include::../test/SemanticsTest.groovy[tags=switch_expression,indent=0]
 ----
 
 ==== Looping structures
diff --git a/src/spec/test/SemanticsTest.groovy b/src/spec/test/SemanticsTest.groovy
index 863bddd..e991913 100644
--- a/src/spec/test/SemanticsTest.groovy
+++ b/src/spec/test/SemanticsTest.groovy
@@ -162,51 +162,15 @@ class SemanticsTest extends CompilableTestSupport {
 
     void testSwitchExpression() {
         def person = 'Romeo'
-        // tag::switch_expression_01[]
+        // tag::switch_expression[]
         def partner = switch(person) {
             case 'Romeo'  -> 'Juliet'
             case 'Adam'   -> 'Eve'
             case 'Antony' -> 'Cleopatra'
             case 'Bonnie' -> 'Clyde'
         }
-        // end::switch_expression_01[]
+        // end::switch_expression[]
         assert partner == 'Juliet'
-
-
-        assertScript '''\
-import groovy.transform.Immutable
-
-interface Expr { }
-@Immutable class IntExpr implements Expr { int i }
-@Immutable class NegExpr implements Expr { Expr n }
-@Immutable class AddExpr implements Expr { Expr left, right }
-@Immutable class MulExpr implements Expr { Expr left, right }
-
-int eval(Expr e) {
-// tag::switch_expression_02[]
-    switch(e) {
-        case IntExpr(i) -> i
-        case NegExpr(n) -> -eval(n)
-        case AddExpr(left, right) -> eval(left) + eval(right)
-        case MulExpr(left, right) -> eval(left) * eval(right)
-        default -> throw new IllegalStateException()
-    }
-// end::switch_expression_02[]
-}
-
-@Newify(pattern=".*Expr")
-def test() {
-    def exprs = [
-        IntExpr(4),
-        NegExpr(IntExpr(4)),
-        AddExpr(IntExpr(4), MulExpr(IntExpr(3), IntExpr(2))), // 4 + (3*2)
-        MulExpr(IntExpr(4), AddExpr(IntExpr(3), IntExpr(2)))  // 4 * (3+2)
-    ]
-    assert exprs.collect { eval(it) } == [4, -4, 10, 20]
-}
-
-test()
-        '''
     }
 
     void testClassicForLoop() {
diff --git a/src/test-resources/core/SwitchExpression_27x.groovy b/src/test-resources/core/SwitchExpression_27x.groovy
deleted file mode 100644
index a9a148a..0000000
--- a/src/test-resources/core/SwitchExpression_27x.groovy
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  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.
- */
-
-class Coord {
-    int x
-    int y
-}
-
-def s = new Coord(x: 2, y: 5)
-def result = switch (s) {
-    case Coord(x, y) -> x * 3 + y
-}
-assert 11 == result
diff --git a/src/test-resources/core/SwitchExpression_28x.groovy b/src/test-resources/core/SwitchExpression_28x.groovy
deleted file mode 100644
index 0ab6c44..0000000
--- a/src/test-resources/core/SwitchExpression_28x.groovy
+++ /dev/null
@@ -1,74 +0,0 @@
-import groovy.transform.CompileStatic
-
-/*
- *  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.
- */
-
-interface Expr {}
-class IntExpr implements Expr {
-    int i
-}
-class NegExpr implements Expr {
-    Expr n
-}
-class AddExpr implements Expr {
-    Expr left, right
-}
-class MulExpr implements Expr {
-    Expr left, right
-}
-
-@CompileStatic
-int evalStatic(Expr expr) {
-    int result = switch(expr) {
-        case IntExpr(i) -> i
-        case NegExpr(n) -> -evalStatic(n)
-        case AddExpr(left, right) -> evalStatic(left) + evalStatic(right)
-        case MulExpr(left, right) -> evalStatic(left) * evalStatic(right)
-        default -> throw new IllegalStateException()
-    }
-    return result
-}
-
-// -2 * 5 + 4
-assert -6 == evalStatic(new AddExpr(
-        left: new MulExpr(
-                left: new NegExpr(n: new IntExpr(i: 2)),
-                right: new IntExpr(i: 5)
-        ),
-        right: new IntExpr(i: 4)
-))
-
-int evalDynamic(Expr expr) {
-    int result = switch(expr) {
-        case IntExpr(i) -> i
-        case NegExpr(n) -> -evalDynamic(n)
-        case AddExpr(left, right) -> evalDynamic(left) + evalDynamic(right)
-        case MulExpr(left, right) -> evalDynamic(left) * evalDynamic(right)
-        default -> throw new IllegalStateException()
-    }
-    return result
-}
-// -2 * 5 + 4
-assert -6 == evalDynamic(new AddExpr(
-        left: new MulExpr(
-                left: new NegExpr(n: new IntExpr(i: 2)),
-                right: new IntExpr(i: 5)
-        ),
-        right: new IntExpr(i: 4)
-))
diff --git a/src/test-resources/core/SwitchExpression_29x.groovy b/src/test-resources/core/SwitchExpression_29x.groovy
deleted file mode 100644
index b4e4ea7..0000000
--- a/src/test-resources/core/SwitchExpression_29x.groovy
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  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.
- */
-
-class Coord {
-    int x
-    int y
-}
-
-def s = new Coord(x: 2, y: 5)
-def result = switch (s) {
-    case Coord(x, y): yield x * 3 + y
-}
-assert 11 == result
diff --git a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index 8a41f96..10c2af0 100644
--- a/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/src/test/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -450,9 +450,6 @@ final class GroovyParserTest extends GroovyTestCase {
         doRunAndTestAntlr4('core/SwitchExpression_24x.groovy')
         doRunAndTestAntlr4('core/SwitchExpression_25x.groovy')
         doRunAndTestAntlr4('core/SwitchExpression_26x.groovy')
-        doRunAndTestAntlr4('core/SwitchExpression_27x.groovy')
-        doRunAndTestAntlr4('core/SwitchExpression_28x.groovy')
-        doRunAndTestAntlr4('core/SwitchExpression_29x.groovy')
     }
 
     void "test groovy core - BUG"() {