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 2019/08/02 14:25:26 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-8002: propagate source
position to method in chain assignment
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new ac6c3ad GROOVY-8002: propagate source position to method in chain assignment
ac6c3ad is described below
commit ac6c3ad4b15c32952fd7e9a47164bd1136493dad
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Jul 20 13:20:11 2019 -0500
GROOVY-8002: propagate source position to method in chain assignment
(cherry picked from commit 9c55d50c886b249c6da9f470562bfe7dd208b01c)
---
.../groovy/ast/expr/MethodCallExpression.java | 21 +++++++
.../asm/sc/StaticPropertyAccessHelper.java | 2 +
src/test/groovy/bugs/Groovy8002.groovy | 65 ++++++++++++++++++++++
3 files changed, 88 insertions(+)
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
index a15cb2f..f0250a8 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
@@ -209,4 +209,25 @@ public class MethodCallExpression extends Expression implements MethodCall {
public MethodNode getMethodTarget() {
return target;
}
+
+ @Override
+ public void setSourcePosition(ASTNode node) {
+ super.setSourcePosition(node);
+ // GROOVY-8002: propagate position to (possibly new) method expression
+ if (node instanceof MethodCall) {
+ if (node instanceof MethodCallExpression) {
+ method.setSourcePosition(((MethodCallExpression) node).getMethod());
+ } else if (node.getLineNumber() > 0) {
+ method.setLineNumber(node.getLineNumber());
+ method.setColumnNumber(node.getColumnNumber());
+ method.setLastLineNumber(node.getLineNumber());
+ method.setLastColumnNumber(node.getColumnNumber() + getMethodAsString().length());
+ }
+ if (arguments != null) {
+ arguments.setSourcePosition(((MethodCall) node).getArguments());
+ }
+ } else if (node instanceof PropertyExpression) {
+ method.setSourcePosition(((PropertyExpression) node).getProperty());
+ }
+ }
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java
index b36801b..67f75f6 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticPropertyAccessHelper.java
@@ -35,6 +35,7 @@ import java.util.Arrays;
* @since 2.4.0
*/
public abstract class StaticPropertyAccessHelper {
+
public static Expression transformToSetterCall(
Expression receiver,
MethodNode setterMethod,
@@ -114,6 +115,7 @@ public abstract class StaticPropertyAccessHelper {
public Expression transformExpression(final ExpressionTransformer transformer) {
PoppingMethodCallExpression trn = new PoppingMethodCallExpression(receiver.transformExpression(transformer), setter, (TemporaryVariableExpression) tmp.transformExpression(transformer));
trn.copyNodeMetaData(this);
+ trn.setSourcePosition(this);
trn.setImplicitThis(isImplicitThis());
trn.setSafe(isSafe());
trn.setSpreadSafe(isSpreadSafe());
diff --git a/src/test/groovy/bugs/Groovy8002.groovy b/src/test/groovy/bugs/Groovy8002.groovy
new file mode 100644
index 0000000..2f628bc
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8002.groovy
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+package groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class Groovy8002 {
+
+ @Test
+ void testSourcePositionOfMethodInChainAssignmentCS() {
+ assertScript '''
+ import groovy.transform.*
+ import static org.codehaus.groovy.control.CompilePhase.*
+
+ class B {
+ private String z
+ void setZero(String zero) { z = zero }
+ }
+
+ @CompileStatic
+ class C {
+ String x
+ B b = new B()
+ @ASTTest(phase=CLASS_GENERATION, value={
+ def expr = node.code.statements[-1].expression.rightExpression.@call
+ assert expr.class.simpleName == 'PoppingMethodCallExpression'
+ assert expr.lineNumber > 0 && expr.columnNumber > 0
+
+ def zero = expr.method // "zero" in "x = b.zero = 'X'"
+ assert zero.lineNumber > 0
+ assert zero.columnNumber > 0
+ assert zero.lastLineNumber == zero.lineNumber
+ assert zero.lastColumnNumber == zero.columnNumber + 4
+ })
+ C() {
+ x = b.zero = 'X'
+ }
+ }
+
+ def c = new C()
+ assert c.x == 'X'
+ assert c.b.@z == 'X'
+ '''
+ }
+}