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/06/26 15:14:26 UTC

[groovy] 01/01: GROOVY-10150: Eliminate ambiguities while parsing non-static class creator

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

sunlan pushed a commit to branch danielsun/tweak-GROOVY-8947
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 8c8c12f07b85f4618ccae0bd61dd5497e3ea2fba
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 26 23:14:10 2021 +0800

    GROOVY-10150: Eliminate ambiguities while parsing non-static class creator
---
 src/antlr/GroovyParser.g4                                    | 12 +++++++++---
 .../java/org/apache/groovy/parser/antlr4/AstBuilder.java     |  6 +++---
 src/test/groovy/KeywordsInPropertyNamesTest.groovy           |  2 +-
 src/test/groovy/bugs/Groovy8947.groovy                       |  3 +++
 4 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index f971d33..5712a59 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -962,8 +962,9 @@ namePart
         |   block
         */
 
-        // let's allow common keywords as property names
-        |   keywords
+        // let's allow common keywords as property names excluding `new`, which is ambiguous when instantiate non-static inner class, e.g.
+        // `new Computer().new Cpu(4)`
+        |   keywordsWithoutNew
         )
     ;
 
@@ -1185,6 +1186,11 @@ builtInType
     ;
 
 keywords
+    :   NEW
+    |   keywordsWithoutNew
+    ;
+
+keywordsWithoutNew
     :   ABSTRACT
     |   AS
     |   ASSERT
@@ -1211,7 +1217,7 @@ keywords
     |   INSTANCEOF
     |   INTERFACE
     |   NATIVE
-    |   NEW
+//    |   NEW
     |   PACKAGE
     |   RETURN
     |   STATIC
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..64d5b6e 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -339,11 +339,11 @@ 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.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;
 
@@ -2725,8 +2725,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
             return configureAST(this.visitStringLiteral(ctx.stringLiteral()), ctx);
         } else if (asBoolean(ctx.dynamicMemberName())) {
             return configureAST(this.visitDynamicMemberName(ctx.dynamicMemberName()), ctx);
-        } else if (asBoolean(ctx.keywords())) {
-            return configureAST(new ConstantExpression(ctx.keywords().getText()), ctx);
+        } else if (asBoolean(ctx.keywordsWithoutNew())) {
+            return configureAST(new ConstantExpression(ctx.keywordsWithoutNew().getText()), ctx);
         }
 
         throw createParsingFailedException("Unsupported name part: " + ctx.getText(), ctx);
diff --git a/src/test/groovy/KeywordsInPropertyNamesTest.groovy b/src/test/groovy/KeywordsInPropertyNamesTest.groovy
index b2fe103..f629d64 100644
--- a/src/test/groovy/KeywordsInPropertyNamesTest.groovy
+++ b/src/test/groovy/KeywordsInPropertyNamesTest.groovy
@@ -130,7 +130,7 @@ class KeywordsInPropertyNamesTest extends GroovyTestCase {
         assert map.in == 'trouble'
         assert map.instanceof == 'abuse'
         assert map.interface == 'with'
-        assert map.new == 'car'
+        assert map.'new' == 'car'
         assert map.package == 'wrapped'
         assert map.return == 'home'
         assert map.super == 'duper'
diff --git a/src/test/groovy/bugs/Groovy8947.groovy b/src/test/groovy/bugs/Groovy8947.groovy
index d7f8c6c..bf8592a 100644
--- a/src/test/groovy/bugs/Groovy8947.groovy
+++ b/src/test/groovy/bugs/Groovy8947.groovy
@@ -45,6 +45,9 @@ final class Groovy8947 {
             assert 4 == new Computer().new Cpu(4).coreNumber
             assert 4 == Computer.newCpuInstance(4).coreNumber
             assert 0 == new HashSet(new ArrayList()).size()
+            
+            def cpu = new Computer().new Cpu(4)
+            assert 4 == cpu.coreNumber
         '''
     }