You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2019/11/03 18:32:28 UTC

[groovy] branch GROOVY-8507 created (now 5ac71d7)

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

emilles pushed a change to branch GROOVY-8507
in repository https://gitbox.apache.org/repos/asf/groovy.git.


      at 5ac71d7  GROOVY-8507, GROOVY-9301: support comma on last enum value in more cases

This branch includes the following new commits:

     new 5ac71d7  GROOVY-8507, GROOVY-9301: support comma on last enum value in more cases

The 1 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.



[groovy] 01/01: GROOVY-8507, GROOVY-9301: support comma on last enum value in more cases

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

emilles pushed a commit to branch GROOVY-8507
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 5ac71d7a5bee39efe7ac0e1dd408705c82a97b3d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Nov 3 12:15:26 2019 -0600

    GROOVY-8507, GROOVY-9301: support comma on last enum value in more cases
    
    and reduce ambiguity within (antlr2) enumConstants loop
---
 src/main/antlr2/org/codehaus/groovy/antlr/groovy.g |  15 +-
 .../groovy/antlr/EnumSourceParsingTest.java        | 284 +++++++++++++++++----
 2 files changed, 240 insertions(+), 59 deletions(-)

diff --git a/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g b/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g
index 3f29054..41d5e29 100644
--- a/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g
+++ b/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g
@@ -1128,26 +1128,33 @@ enumBlock  {Token first = LT(1);}
         {#enumBlock = #(create(OBJBLOCK,"OBJBLOCK",first,LT(1)), #enumBlock);}
     ;
 
-/** Guard for enumConstants.  */
+/** Guard for enumConstants. */
 enumConstantsStart
     :   annotationsOpt IDENT (LCURLY | LPAREN | nls (SEMI | COMMA | declarationStart | RCURLY))
     ;
 
-/** Comma-separated list of one or more enum constant definitions.  */
+/** Comma-separated list of one or more enum constant definitions. */
 enumConstants
     :
         enumConstant
         ( options {generateAmbigWarnings=false;} :
-            (nls ( options {generateAmbigWarnings=false;} : SEMI! | RCURLY | declarationStart | constructorStart)) => {break;}
+            (nls (SEMI | enumConstantsEnd)) => {break;} // GROOVY-4438, GROOVY-9184
         |
             nls! COMMA! (
+                (nls enumConstantsEnd) => {break;} // GROOVY-8507, GROOVY-9301
+            |
                 (nls annotationsOpt IDENT) => nls! enumConstant
             |
-                (nls (SEMI! | RCURLY | classField)) => {break;}
+                (nls classField) => {break;}
             )
         )*
     ;
 
+enumConstantsEnd
+    options {generateAmbigWarnings=false;}
+    :   RCURLY | declarationStart | constructorStart | typeDefinitionStart
+    ;
+
 // An annotation field
 annotationField!  {Token first = LT(1);}
     :   mods:modifiersOpt!
diff --git a/src/test/org/codehaus/groovy/antlr/EnumSourceParsingTest.java b/src/test/org/codehaus/groovy/antlr/EnumSourceParsingTest.java
index 8a6d2a3..fd24cb4 100644
--- a/src/test/org/codehaus/groovy/antlr/EnumSourceParsingTest.java
+++ b/src/test/org/codehaus/groovy/antlr/EnumSourceParsingTest.java
@@ -28,93 +28,116 @@ public final class EnumSourceParsingTest extends SourceParserTest {
     public void testParseEnumConstants() {
         parse(getMethodName(), new StringReader(
             "enum E {\n" +
-            "    ONE, TWO, THREE\n" +
-            "}"));
+            "    X, Y, Z\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumConstantsMultiLine() {
         parse(getMethodName(), new StringReader(
             "enum E {\n" +
-            "    ONE,\n" +
-            "    TWO,\n" +
-            "    THREE,\n" +
-            "}"));
+            "    X,\n" +
+            "    Y,\n" +
+            "    Z,\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumConstantsMultiLine2() {
         parse(getMethodName(), new StringReader(
-            "enum ParseCode\n" +
+            "enum E\n" +
             "{\n" +
-            "    COMPLETE,\n" +
-            "    INCOMPLETE,\n" +
-            "    ERROR\n" +
-            "}"));
+            "    X,\n" +
+            "    Y,\n" +
+            "    Z\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumImplementsMultiLine() {
         parse(getMethodName(), new StringReader(
-            "enum ParseCode implements I\n" +
+            "enum E implements I\n" +
             "{\n" +
-            "    COMPLETE,\n" +
-            "    INCOMPLETE,\n" +
-            "    ERROR\n" +
-            "}"));
+            "    X,\n" +
+            "    Y,\n" +
+            "    Z\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumImplementsMultiLine2() {
         parse(getMethodName(), new StringReader(
-            "enum ParseCode\n" +
+            "enum E\n" +
             "implements I\n" +
             "{\n" +
-            "    COMPLETE,\n" +
-            "    INCOMPLETE,\n" +
-            "    ERROR\n" +
-            "}"));
+            "    X,\n" +
+            "    Y,\n" +
+            "    Z\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumConstantsOneLiner() {
         parse(getMethodName(), new StringReader(
-            "enum One { ONE, TWO, THREE }"));
+            "enum E { X, Y, Z }\n")
+        );
     }
 
     public void testParseEnumImplements() {
         parse(getMethodName(), new StringReader(
-            "enum Two implements I1 {\n" +
-            "ONE, TWO, THREE\n" +
-            "}"));
+            "enum E implements I {\n" +
+            "    X, Y, Z\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumWithValues() {
         parse(getMethodName(), new StringReader(
-            "enum Three1 {\n" +
-            "    ONE(1), TWO(2)\n\n" +
-            "    Three1(val) {\n" +
-            "        value = val\n" +
+            "enum E {\n" +
+            "    X(1), Y(2)\n\n" +
+            "    E(value) {\n" +
+            "        this.value = value\n" +
             "    }\n\n" +
-            "    private final int value" +
-            "}"));
+            "    private final int value\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumWithValues2() {
         parse(getMethodName(), new StringReader(
-            "enum Three1 {\n" +
-            "    @Annotation ONE(1), TWO(2)\n\n" +
-            "    Three1(val) {\n" +
-            "        value = val\n" +
+            "enum E {\n" +
+            "    @Annotation X(1), Y(2)\n\n" +
+            "    E(value) {\n" +
+            "        this.value = value\n" +
             "    }\n\n" +
-            "    private final int value" +
-            "}"));
+            "    private final int value\n" +
+            "}\n")
+        );
     }
 
     public void testParseEnumWithValues3() {
         parse(getMethodName(), new StringReader(
-            "enum NonFinal {\n" +
-            "    One(1), Two(2)\n" +
+            "enum E {\n" +
+            "    X(1), Y(2)\n" +
             "    Object value\n" + // different parsing without leading keyword
-            "    NonFinal(value) {\n" +
+            "    E(value) {\n" +
+            "        this.value = value\n" +
+            "    }\n" +
+            "}\n")
+        );
+    }
+
+    // GROOVY-9301
+    public void testParseEnumWithValues3a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X(1), Y(2),\n" + // trailing comma
+            "    Object value\n" +
+            "    E(value) {\n" +
             "        this.value = value\n" +
             "    }\n" +
-            "}\n"));
+            "}\n")
+        );
     }
 
     public void testParseEnumWithValues4() {
@@ -127,26 +150,55 @@ public final class EnumSourceParsingTest extends SourceParserTest {
             "    CLUBS(Color.BLACK),\n" +
             "    DIAMONDS(Color.RED),\n" +
             "    HEARTS(Color.RED),\n" +
-            "    SPADES(Color.BLACK),\n" +
+            "    SPADES(Color.BLACK),\n" + // trailing comma
             "    \n" +
             "    final Color color\n" +
             "    Suit(Color color) {\n" +
             "        this.color = color\n" +
             "    }\n" +
-            "}\n"));
+            "}\n")
+        );
     }
 
-    public void testParseEnumWithMethodDefinitions() {
+    public void testParseEnumWithMethodDefinitions1() {
         parse(getMethodName(), new StringReader(
-            "enum Four {\n" +
-            "    ONE, TWO, THREE\n\n" +
-            "    def someMethod() { }\n" +
+            "enum E {\n" +
+            "    X, Y, Z\n\n" +
+            "    def m1() { }\n" +
             "    public m2(args) { }\n" +
             "    int m3(String arg) { }\n" +
-            "}"));
+            "}\n")
+        );
+    }
+
+    public void testParseEnumWithMethodDefinitions2() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n\n" +
+            "    def <T> T m() { }\n" +
+            "}\n")
+        );
+    }
+
+    public void testParseEnumWithMethodDefinitions2a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n\n" +
+            "    final <T> T m() { }\n" +
+            "}\n")
+        );
     }
 
-    public void testParseEnumWithAnnotatedMethodDefinition() {
+    public void testParseEnumWithMethodDefinitions2b() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n\n" +
+            "    public <T> T m() { }\n" +
+            "}\n")
+        );
+    }
+
+    public void testParseEnumWithAnnotatedMethodDefinition1() {
         parse(getMethodName(), new StringReader(
             "enum Orientation {\n" +
             "    LANDSCAPE, PORTRAIT\n" +
@@ -155,16 +207,138 @@ public final class EnumSourceParsingTest extends SourceParserTest {
             "    String toString() {\n" +
             "        name().toLowerCase().capitalize()\n" +
             "    }\n" +
-            "}\n"));
+            "}\n")
+        );
+    }
+
+    // GROOVY-9301
+    public void testParseEnumWithAnnotatedMethodDefinition2() {
+        parse(getMethodName(), new StringReader(
+            "enum Orientation {\n" +
+            "    LANDSCAPE, PORTRAIT,\n" + // trailing comma
+            "    \n" +
+            "    @Override\n" +
+            "    String toString() {\n" +
+            "        name().toLowerCase().capitalize()\n" +
+            "    }\n" +
+            "}\n")
+        );
+    }
+
+    // GROOVY-9301
+    public void testParseEnumWithAnnotatedMethodDefinition3() {
+        parse(getMethodName(), new StringReader(
+            "enum Orientation {\n" +
+            "    LANDSCAPE, PORTRAIT,\n" + // trailing comma
+            "    \n" +
+            "    @Deprecated <T> T whatever() {\n" +
+            "    }\n" +
+            "}\n")
+        );
     }
 
     public void testParseCompleteEnum() {
         parse(getMethodName(), new StringReader(
-            "enum Five {\n" +
-            "    ONE { double eval(int v) { return (double) v } }, \n" +
-            "    TWO {\n" +
+            "enum E {\n" +
+            "    X { double eval(int v) { return (double) v } }, \n" +
+            "    Y {\n" +
             "        double eval(int v) { return (double) v + 1 }\n" +
-            "    }, THREE\n" +
-            "}"));
+            "    }, Z\n" +
+            "}")
+        );
+    }
+
+    public void testParseEnumWithInnerClass1() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n" +
+            "    class C { }\n" +
+            "}\n")
+        );
+    }
+
+    // GROOVY-8507
+    public void testParseEnumWithInnerClass1a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z,\n" + // trailing comma
+            "    class C { }\n" +
+            "}\n")
+        );
+    }
+
+    public void testParseEnumWithInnerClass2() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n" +
+            "    enum E2 { A, B, C }\n" +
+            "}\n")
+        );
+    }
+
+    // GROOVY-8507
+    public void testParseEnumWithInnerClass2a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z,\n" + // trailing comma
+            "    enum Another { A, B, C }\n" +
+            "}\n")
+        );
+    }
+
+    public void testParseEnumWithInnerClass3() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n" +
+            "    interface I { }\n" +
+            "}\n")
+        );
+    }
+
+    // GROOVY-8507
+    public void testParseEnumWithInnerClass3a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z,\n" + // trailing comma
+            "    interface I { }\n" +
+            "}\n")
+        );
+    }
+
+    public void _FIXME_testParseEnumWithInnerClass4() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n" +
+            "    @interface A { }\n" +
+            "}\n")
+        );
+    }
+
+    public void _FIXME_testParseEnumWithInnerClass4a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z,\n" + // trailing comma
+            "    @interface A { }\n" +
+            "}\n")
+        );
+    }
+
+    public void testParseEnumWithInnerClass5() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z\n" +
+            "    trait T { }\n" +
+            "}\n")
+        );
+    }
+
+    // GROOVY-8507
+    public void testParseEnumWithInnerClass5a() {
+        parse(getMethodName(), new StringReader(
+            "enum E {\n" +
+            "    X, Y, Z,\n" + // trailing comma
+            "    trait T { }\n" +
+            "}\n")
+        );
     }
 }