groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject groovy git commit: Support creating instances of non-static inner classes of Java style
Date Thu, 12 Apr 2018 00:40:59 GMT
Repository: groovy
Updated Branches:
  refs/heads/master d033d1ce5 -> bc254b19f


Support creating instances of non-static inner classes of Java style


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/bc254b19
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/bc254b19
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/bc254b19

Branch: refs/heads/master
Commit: bc254b19f2d585da5430ea5fa81b72e0761efd31
Parents: d033d1c
Author: sunlan <sunlan@apache.org>
Authored: Thu Apr 12 08:40:48 2018 +0800
Committer: sunlan <sunlan@apache.org>
Committed: Thu Apr 12 08:40:48 2018 +0800

----------------------------------------------------------------------
 src/antlr/GroovyParser.g4                       | 21 ++++---
 .../apache/groovy/parser/antlr4/AstBuilder.java | 20 ++++++-
 .../parser/antlr4/GroovyParserTest.groovy       |  4 ++
 .../groovy/parser/antlr4/SyntaxErrorTest.groovy |  4 ++
 .../resources/core/NonStaticClass_01x.groovy    | 59 ++++++++++++++++++++
 .../resources/fail/NonStaticClass_01x.groovy    | 33 +++++++++++
 6 files changed, 132 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/bc254b19/src/antlr/GroovyParser.g4
----------------------------------------------------------------------
diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index 385fd11..aef9289 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -816,7 +816,7 @@ expression
         right=expression                                                                
   #shiftExprAlt
 
     // boolean relational expressions (level 7)
-    |   left=expression nls op=(AS | INSTANCEOF | NOT_INSTANCEOF) nls type           #relationalExprAlt
+    |   left=expression nls op=(AS | INSTANCEOF | NOT_INSTANCEOF) nls type              
   #relationalExprAlt
     |   left=expression nls op=(LE | GE | GT | LT | IN | NOT_IN)  nls right=expression  
   #relationalExprAlt
 
     // equality/inequality (==/!=) (level 8)
@@ -927,7 +927,7 @@ commandArgument
  *  (Compare to a C lvalue, or LeftHandSide in the JLS section 15.26.)
  *  General expressions are built up from path expressions, using operators like '+' and
'='.
  *
- *  t   0: primary, 1: namePart, 2: arguments, 3: closure, 4: indexPropertyArgs, 5: namedPropertyArgs
+ *  t   0: primary, 1: namePart, 2: arguments, 3: closure, 4: indexPropertyArgs, 5: namedPropertyArgs,
6: non-static inner class creator
  */
 pathExpression returns [int t]
     :   primary (pathElement { $t = $pathElement.t; })*
@@ -950,7 +950,9 @@ pathElement returns [int t]
         )
         namePart
         { $t = 1; }
-
+    |
+        DOT nls NEW creator[1]
+        { $t = 6; }
     |   arguments
         { $t = 2; }
 
@@ -1021,7 +1023,7 @@ primary
         identifier typeArguments?                                                       
   #identifierPrmrAlt
     |   literal                                                                         
   #literalPrmrAlt
     |   gstring                                                                         
   #gstringPrmrAlt
-    |   NEW nls creator                                                                 
   #newPrmrAlt
+    |   NEW nls creator[0]                                                              
   #newPrmrAlt
     |   THIS                                                                            
   #thisPrmrAlt
     |   SUPER                                                                           
   #superPrmrAlt
     |   parExpression                                                                   
   #parenPrmrAlt
@@ -1058,11 +1060,14 @@ mapEntryLabel
     |   primary
     ;
 
-creator
+/**
+ *  t 0: general creation; 1: non-static inner class creation
+ */
+creator[int t]
     :   createdName
-        (   nls arguments anonymousInnerClassDeclaration[0]?
-        |   (annotationsOpt LBRACK expression RBRACK)+ dimsOpt
-        |   dims nls arrayInitializer
+        (   {0 == $t || 1 == $t}? nls arguments anonymousInnerClassDeclaration[0]?
+        |   {0 == $t}?            (annotationsOpt LBRACK expression RBRACK)+ dimsOpt
+        |   {0 == $t}?            dims nls arrayInitializer
         )
     ;
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/bc254b19/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 0776856..2372d44 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -2293,6 +2293,13 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object>
implements Groov
             }
         }
 
+        if (asBoolean(ctx.creator())) {
+            CreatorContext creatorContext = ctx.creator();
+            creatorContext.putNodeMetaData(ENCLOSING_INSTANCE_EXPRESSION, baseExpr);
+
+            return configureAST(this.visitCreator(creatorContext), ctx);
+        }
+
         if (asBoolean(ctx.indexPropertyArgs())) { // e.g. list[1, 3, 5]
             Tuple2<Token, Expression> tuple = this.visitIndexPropertyArgs(ctx.indexPropertyArgs());
             boolean isSafeChain = isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN);
@@ -3147,9 +3154,19 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object>
implements Groov
     @Override
     public Expression visitCreator(CreatorContext ctx) {
         ClassNode classNode = this.visitCreatedName(ctx.createdName());
-        Expression arguments = this.visitArguments(ctx.arguments());
 
         if (asBoolean(ctx.arguments())) { // create instance of class
+            Expression arguments = this.visitArguments(ctx.arguments());
+            Expression enclosingInstanceExpression = ctx.getNodeMetaData(ENCLOSING_INSTANCE_EXPRESSION);
+
+            if (null != enclosingInstanceExpression) {
+                if (arguments instanceof ArgumentListExpression) {
+                    ((ArgumentListExpression) arguments).getExpressions().add(0, enclosingInstanceExpression);
+                } else if (arguments instanceof TupleExpression || arguments instanceof NamedArgumentListExpression)
{
+                    throw createParsingFailedException("Creating instance of non-static class
does not support named parameters", arguments);
+                }
+            }
+
             if (asBoolean(ctx.anonymousInnerClassDeclaration())) {
                 ctx.anonymousInnerClassDeclaration().putNodeMetaData(ANONYMOUS_INNER_CLASS_SUPER_CLASS,
classNode);
                 InnerClassNode anonymousInnerClassNode = this.visitAnonymousInnerClassDeclaration(ctx.anonymousInnerClassDeclaration());
@@ -4754,6 +4771,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object>
implements Groov
     private static final String ANONYMOUS_INNER_CLASS_SUPER_CLASS = "_ANONYMOUS_INNER_CLASS_SUPER_CLASS";
     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 CLASS_NAME = "_CLASS_NAME";
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/bc254b19/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
index 4701e77..8dae27e 100644
--- a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
+++ b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/GroovyParserTest.groovy
@@ -383,6 +383,10 @@ class GroovyParserTest extends GroovyTestCase {
         doRunAndTestAntlr4('core/String_01x.groovy');
     }
 
+    void "test groovy core - NonStaticClass"() {
+        doRunAndTestAntlr4('core/NonStaticClass_01x.groovy');
+    }
+
     void "test groovy core - BUG"() {
         doRunAndTestAntlr4('bugs/BUG-GROOVY-4757.groovy')
         doRunAndTestAntlr4('bugs/BUG-GROOVY-5652.groovy')

http://git-wip-us.apache.org/repos/asf/groovy/blob/bc254b19/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
index c23e8f4..0fdef50 100644
--- a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
+++ b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/SyntaxErrorTest.groovy
@@ -222,6 +222,10 @@ class SyntaxErrorTest extends GroovyTestCase {
         TestUtils.doRunAndShouldFail('fail/String_02x.groovy');
     }
 
+    void "test groovy core - NonStaticClass"() {
+        TestUtils.doRunAndShouldFail('fail/NonStaticClass_01x.groovy');
+    }
+
     /**************************************/
     static unzipScriptAndShouldFail(String entryName, List ignoreClazzList, Map<String,
String> replacementsMap=[:], boolean toCheckNewParserOnly = false) {
         ignoreClazzList.addAll(TestUtils.COMMON_IGNORE_CLASS_LIST)

http://git-wip-us.apache.org/repos/asf/groovy/blob/bc254b19/subprojects/parser-antlr4/src/test/resources/core/NonStaticClass_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/core/NonStaticClass_01x.groovy b/subprojects/parser-antlr4/src/test/resources/core/NonStaticClass_01x.groovy
new file mode 100644
index 0000000..007978a
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/core/NonStaticClass_01x.groovy
@@ -0,0 +1,59 @@
+/*
+ *  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.
+ */
+
+public class Y {
+    public class X {
+        def name
+
+        public X(String name) {
+            this.name = name
+        }
+    }
+
+    public static Y createY() {
+        return new Y()
+    }
+
+    public static X createX(Y y) {
+        return y.new X('Daniel')
+    }
+
+    public static X createX() {
+        return createY().new X('Daniel')
+    }
+
+    public static String getXName() {
+        return createY().new X('Daniel').name
+    }
+
+    public static String getXName2() {
+        return createY().
+                        new X('Daniel')
+                                        .name
+    }
+}
+
+def createY() {
+    return new Y()
+}
+
+assert 'Daniel' == Y.createX(new Y()).name
+assert 'Daniel' == Y.createX().name
+assert 'Daniel' == Y.getXName()
+assert 'Daniel' == Y.getXName2()

http://git-wip-us.apache.org/repos/asf/groovy/blob/bc254b19/subprojects/parser-antlr4/src/test/resources/fail/NonStaticClass_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/fail/NonStaticClass_01x.groovy b/subprojects/parser-antlr4/src/test/resources/fail/NonStaticClass_01x.groovy
new file mode 100644
index 0000000..5774e6e
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/fail/NonStaticClass_01x.groovy
@@ -0,0 +1,33 @@
+/*
+ *  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.
+ */
+
+public class Y {
+    public class X {
+        def name
+
+        public X(String name) {
+            this.name = name
+        }
+    }
+
+    public static X createX(Y y) {
+        return y.new X(name:'Daniel')
+    }
+}
+assert 'Daniel' == Y.createX(new Y()).name


Mime
View raw message