You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2018/10/09 05:00:14 UTC
groovy git commit: GROOVY-8764: Closure inside an anonymous class
uses wrong outside class instance with @CS
Repository: groovy
Updated Branches:
refs/heads/GROOVY_2_5_X 484adf6fc -> eee7844bb
GROOVY-8764: Closure inside an anonymous class uses wrong outside class instance with @CS
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/eee7844b
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/eee7844b
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/eee7844b
Branch: refs/heads/GROOVY_2_5_X
Commit: eee7844bb8ecf0f2b66d58cea328c5b9aadde75c
Parents: 484adf6
Author: Paul King <pa...@asert.com.au>
Authored: Tue Oct 9 16:00:05 2018 +1100
Committer: Paul King <pa...@asert.com.au>
Committed: Tue Oct 9 16:00:05 2018 +1100
----------------------------------------------------------------------
.../groovy/classgen/asm/ClosureWriter.java | 4 +-
.../classgen/asm/sc/StaticInvocationWriter.java | 22 +++++++++-
src/test/groovy/bugs/Groovy8764Bug.groovy | 44 ++++++++++++++++++++
3 files changed, 67 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/eee7844b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
index 60fe447..6c896c0 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
@@ -253,10 +253,10 @@ public class ClosureWriter {
BlockStatement block = new BlockStatement();
// this block does not get a source position, because we don't
// want this synthetic constructor to show up in corbertura reports
- VariableExpression outer = new VariableExpression("_outerInstance");
+ VariableExpression outer = new VariableExpression("_outerInstance", outerClass);
outer.setSourcePosition(expression);
block.getVariableScope().putReferencedLocalVariable(outer);
- VariableExpression thisObject = new VariableExpression("_thisObject");
+ VariableExpression thisObject = new VariableExpression("_thisObject", classNode);
thisObject.setSourcePosition(expression);
block.getVariableScope().putReferencedLocalVariable(thisObject);
TupleExpression conArgs = new TupleExpression(outer, thisObject);
http://git-wip-us.apache.org/repos/asf/groovy/blob/eee7844b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index d7f4884..d480578 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -283,7 +283,27 @@ public class StaticInvocationWriter extends InvocationWriter {
// it's a static extension method
argumentList.add(0, ConstantExpression.NULL);
} else {
- argumentList.add(0, receiver);
+ ClassNode classNode = controller.getClassNode();
+ boolean isThisOrSuper = false;
+ if (receiver instanceof VariableExpression) {
+ isThisOrSuper = ((VariableExpression) receiver).isThisExpression() || ((VariableExpression) receiver).isSuperExpression();
+ }
+ Expression fixedReceiver = null;
+ if (isThisOrSuper && classNode instanceof InnerClassNode && controller.isInClosure()) {
+ ClassNode current = classNode.getOuterClass();
+ fixedReceiver = new VariableExpression("thisObject", current);
+ // adjust for multiple levels of nesting if needed
+ while (current instanceof InnerClassNode && !classNode.equals(current)) {
+ FieldNode thisField = current.getField("this$0");
+ current = current.getOuterClass();
+ if (thisField != null) {
+ fixedReceiver = new PropertyExpression(fixedReceiver, "this$0");
+ fixedReceiver.setType(current);
+ }
+ }
+ }
+
+ argumentList.add(0, fixedReceiver != null ? fixedReceiver : receiver);
}
Parameter[] parameters = node.getParameters();
http://git-wip-us.apache.org/repos/asf/groovy/blob/eee7844b/src/test/groovy/bugs/Groovy8764Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8764Bug.groovy b/src/test/groovy/bugs/Groovy8764Bug.groovy
new file mode 100644
index 0000000..7248667
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8764Bug.groovy
@@ -0,0 +1,44 @@
+/*
+ * 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
+
+class Groovy8764Bug extends GroovyTestCase {
+ void testDgmMethodInClosureInInnerClass() {
+ assertScript '''
+ import groovy.transform.*
+
+ @CompileStatic
+ class GroovyTest {
+ public boolean hasMeta = false
+ void test() {
+ new Runnable() {
+ void run() {
+ def c = { hasMeta = hasProperty('metaClass') /* implicit this for hasProperty DGM method */ }
+ c()
+ }
+ }.run()
+ }
+ }
+
+ def gt = new GroovyTest()
+ gt.test()
+ assert gt.hasMeta
+ '''
+ }
+}