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 2018/04/12 00:40:59 UTC
groovy git commit: Support creating instances of non-static inner
classes of Java style
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 <su...@apache.org>
Authored: Thu Apr 12 08:40:48 2018 +0800
Committer: sunlan <su...@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