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 2017/07/14 18:52:51 UTC
groovy git commit: Support property and field with same name
Repository: groovy
Updated Branches:
refs/heads/master 2817e7e64 -> 72a7f35e2
Support property and field with same name
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/72a7f35e
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/72a7f35e
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/72a7f35e
Branch: refs/heads/master
Commit: 72a7f35e2715ab962adb5ef114f0b33dc956cece
Parents: 2817e7e
Author: sunlan <su...@apache.org>
Authored: Sat Jul 15 02:52:16 2017 +0800
Committer: sunlan <su...@apache.org>
Committed: Sat Jul 15 02:52:45 2017 +0800
----------------------------------------------------------------------
.../apache/groovy/parser/antlr4/AstBuilder.java | 118 ++++++++++++-------
.../groovy/parser/antlr4/SyntaxErrorTest.groovy | 3 +
.../resources/core/ClassDeclaration_01.groovy | 7 +-
.../resources/core/FieldDeclaration_01x.groovy | 10 +-
.../resources/fail/FieldDeclaration_01x.groovy | 1 +
.../resources/fail/FieldDeclaration_02x.groovy | 24 ++++
.../resources/fail/FieldDeclaration_03x.groovy | 25 ++++
.../resources/fail/FieldDeclaration_04x.groovy | 25 ++++
8 files changed, 167 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/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 649f080..369ecae 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
@@ -1538,7 +1538,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
VariableExpression variableExpression = (VariableExpression) declarationExpression.getLeftExpression();
String fieldName = variableExpression.getName();
- validateDuplicatedField(ctx, classNode, fieldName);
int modifiers = modifierManager.getClassMemberModifiersOpValue();
@@ -1553,60 +1552,93 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
modifiers |= Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
}
- if (classNode.isInterface() || modifierManager.containsVisibilityModifier()) {
- FieldNode fieldNode =
- classNode.addField(
- fieldName,
- modifiers,
- variableType,
- initialValue);
- modifierManager.attachAnnotations(fieldNode);
+ if (isFieldDeclaration(modifierManager, classNode)) {
+ declareField(ctx, modifierManager, variableType, classNode, i, variableExpression, fieldName, modifiers, initialValue);
+ } else {
+ declareProperty(ctx, modifierManager, variableType, classNode, i, variableExpression, fieldName, modifiers, initialValue);
+ }
+ }
- groovydocManager.handle(fieldNode, ctx);
+ return null;
+ }
- if (0 == i) {
- this.configureAST(fieldNode, ctx, initialValue);
- } else {
- this.configureAST(fieldNode, variableExpression, initialValue);
- }
+ private void declareProperty(VariableDeclarationContext ctx, ModifierManager modifierManager, ClassNode variableType, ClassNode classNode, int i, VariableExpression variableExpression, String fieldName, int modifiers, Expression initialValue) {
+ if (classNode.hasProperty(fieldName)) {
+ throw createParsingFailedException("The property '" + fieldName + "' is declared multiple times", ctx);
+ }
- } else {
- PropertyNode propertyNode =
- classNode.addProperty(
- fieldName,
- modifiers | Opcodes.ACC_PUBLIC,
- variableType,
- initialValue,
- null,
- null);
+ PropertyNode propertyNode;
+ FieldNode fieldNode = classNode.getDeclaredField(fieldName);
- FieldNode fieldNode = propertyNode.getField();
- fieldNode.setModifiers(modifiers & ~Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE);
- fieldNode.setSynthetic(!classNode.isInterface());
- modifierManager.attachAnnotations(fieldNode);
+ if (fieldNode != null && !classNode.hasProperty(fieldName)) {
+ classNode.getFields().remove(fieldNode);
- groovydocManager.handle(fieldNode, ctx);
- groovydocManager.handle(propertyNode, ctx);
+ propertyNode = new PropertyNode(fieldNode, modifiers | Opcodes.ACC_PUBLIC, null, null);
+ classNode.addProperty(propertyNode);
+ } else {
+ propertyNode =
+ classNode.addProperty(
+ fieldName,
+ modifiers | Opcodes.ACC_PUBLIC,
+ variableType,
+ initialValue,
+ null,
+ null);
- if (0 == i) {
- this.configureAST(fieldNode, ctx, initialValue);
- this.configureAST(propertyNode, ctx, initialValue);
- } else {
- this.configureAST(fieldNode, variableExpression, initialValue);
- this.configureAST(propertyNode, variableExpression, initialValue);
- }
- }
+ fieldNode = propertyNode.getField();
}
- return null;
+ fieldNode.setModifiers(modifiers & ~Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE);
+ fieldNode.setSynthetic(!classNode.isInterface());
+ modifierManager.attachAnnotations(fieldNode);
+
+ groovydocManager.handle(fieldNode, ctx);
+ groovydocManager.handle(propertyNode, ctx);
+
+ if (0 == i) {
+ this.configureAST(fieldNode, ctx, initialValue);
+ this.configureAST(propertyNode, ctx, initialValue);
+ } else {
+ this.configureAST(fieldNode, variableExpression, initialValue);
+ this.configureAST(propertyNode, variableExpression, initialValue);
+ }
}
- private void validateDuplicatedField(VariableDeclarationContext ctx, ClassNode classNode, String fieldName) {
- if (null == classNode.getDeclaredField(fieldName)) {
- return;
+ private void declareField(VariableDeclarationContext ctx, ModifierManager modifierManager, ClassNode variableType, ClassNode classNode, int i, VariableExpression variableExpression, String fieldName, int modifiers, Expression initialValue) {
+ FieldNode existingFieldNode = classNode.getDeclaredField(fieldName);
+ if (null != existingFieldNode && !existingFieldNode.isSynthetic()) {
+ throw createParsingFailedException("The field '" + fieldName + "' is declared multiple times", ctx);
}
- throw createParsingFailedException("The field '" + fieldName + "' is declared multiple times", ctx);
+ FieldNode fieldNode;
+ PropertyNode propertyNode = classNode.getProperty(fieldName);
+
+ if (null != propertyNode && propertyNode.getField().isSynthetic()) {
+ classNode.getFields().remove(propertyNode.getField());
+ fieldNode = new FieldNode(fieldName, modifiers, variableType, classNode.redirect(), initialValue);
+ propertyNode.setField(fieldNode);
+ classNode.addField(fieldNode);
+ } else {
+ fieldNode =
+ classNode.addField(
+ fieldName,
+ modifiers,
+ variableType,
+ initialValue);
+ }
+
+ modifierManager.attachAnnotations(fieldNode);
+ groovydocManager.handle(fieldNode, ctx);
+
+ if (0 == i) {
+ this.configureAST(fieldNode, ctx, initialValue);
+ } else {
+ this.configureAST(fieldNode, variableExpression, initialValue);
+ }
+ }
+
+ private boolean isFieldDeclaration(ModifierManager modifierManager, ClassNode classNode) {
+ return classNode.isInterface() || modifierManager.containsVisibilityModifier();
}
@Override
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/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 672edfa..432be7b 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
@@ -173,6 +173,9 @@ class SyntaxErrorTest extends GroovyTestCase {
void "test groovy core - FieldDeclaration"() {
TestUtils.doRunAndShouldFail('fail/FieldDeclaration_01x.groovy');
+ TestUtils.doRunAndShouldFail('fail/FieldDeclaration_02x.groovy');
+ TestUtils.doRunAndShouldFail('fail/FieldDeclaration_03x.groovy');
+ TestUtils.doRunAndShouldFail('fail/FieldDeclaration_04x.groovy');
}
/**************************************/
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/subprojects/parser-antlr4/src/test/resources/core/ClassDeclaration_01.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/core/ClassDeclaration_01.groovy b/subprojects/parser-antlr4/src/test/resources/core/ClassDeclaration_01.groovy
index 05c8bc3..875006f 100644
--- a/subprojects/parser-antlr4/src/test/resources/core/ClassDeclaration_01.groovy
+++ b/subprojects/parser-antlr4/src/test/resources/core/ClassDeclaration_01.groovy
@@ -70,4 +70,9 @@ class OutputTransforms {
class OutputTransforms2 {
@Lazy static localTransforms = loadOutputTransforms()
-}
\ No newline at end of file
+}
+
+class XX {
+ def x
+ private x = 1
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/subprojects/parser-antlr4/src/test/resources/core/FieldDeclaration_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/core/FieldDeclaration_01x.groovy b/subprojects/parser-antlr4/src/test/resources/core/FieldDeclaration_01x.groovy
index 658f98d..4a83e9f 100644
--- a/subprojects/parser-antlr4/src/test/resources/core/FieldDeclaration_01x.groovy
+++ b/subprojects/parser-antlr4/src/test/resources/core/FieldDeclaration_01x.groovy
@@ -22,7 +22,13 @@ class Base {
}
class FieldHolder extends Base {
- def num = 1
+ def num
+ private num = 1
}
-assert 1 == new FieldHolder().num
+class FieldHolder2 extends FieldHolder {
+ private num = 2
+ def num
+}
+
+assert 2 == new FieldHolder2().num
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_01x.groovy b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_01x.groovy
index 4546576..0a6d064 100644
--- a/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_01x.groovy
+++ b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_01x.groovy
@@ -21,3 +21,4 @@ class FieldHolder {
def num = 1
def num = 1
}
+FieldHolder.class
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_02x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_02x.groovy b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_02x.groovy
new file mode 100644
index 0000000..e765dc0
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_02x.groovy
@@ -0,0 +1,24 @@
+/*
+ * 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 FieldHolder {
+ private num = 1
+ private num = 1
+}
+FieldHolder.class
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_03x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_03x.groovy b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_03x.groovy
new file mode 100644
index 0000000..4e4d21c
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_03x.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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 FieldHolder {
+ def num
+ private num = 1
+ private num = 1
+}
+FieldHolder.class
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/72a7f35e/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_04x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_04x.groovy b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_04x.groovy
new file mode 100644
index 0000000..0302a9a
--- /dev/null
+++ b/subprojects/parser-antlr4/src/test/resources/fail/FieldDeclaration_04x.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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 FieldHolder {
+ private num = 1
+ private num = 1
+ def num
+}
+FieldHolder.class
\ No newline at end of file