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"() {