You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2023/05/28 14:53:25 UTC

[groovy] branch master updated: GROOVY-11068: de-reference closure shared variable

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 40231c26be GROOVY-11068: de-reference closure shared variable
40231c26be is described below

commit 40231c26be588c971a3fc36061f8ea88feeb0d2f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun May 28 09:23:47 2023 -0500

    GROOVY-11068: de-reference closure shared variable
---
 .../groovy/classgen/AsmClassGenerator.java         |  9 ++++---
 .../transform/stc/MethodReferenceTest.groovy       | 29 +++++++++++++++++++---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 2049d46850..d56efbfd25 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -1208,7 +1208,7 @@ public class AsmClassGenerator extends ClassGenerator {
                 ClassNode classNode = controller.getClassNode();
 
                 if (isThisExpression(objectExpression)) {
-                    if (controller.isInGeneratedFunction()) { // params are stored as fields
+                    if (controller.isInGeneratedFunction()) { // params/variables are stored as fields
                         if (expression.isImplicitThis()) fieldNode = classNode.getDeclaredField(name);
                     } else {
                         fieldNode = classNode.getDeclaredField(name);
@@ -1322,7 +1322,8 @@ public class AsmClassGenerator extends ClassGenerator {
         if (field.isHolder() && !controller.isInGeneratedFunctionConstructor()) {
             mv.visitFieldInsn(GETSTATIC, getFieldOwnerName(field), field.getName(), BytecodeHelper.getTypeDescription(type));
             mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "get", "()Ljava/lang/Object;", false);
-            operandStack.push(ClassHelper.OBJECT_TYPE);
+            operandStack.push(ClassHelper.OBJECT_TYPE); // erased return type
+            operandStack.doGroovyCast(field.getOriginType()); // GROOVY-11068
         } else {
             mv.visitFieldInsn(GETSTATIC, getFieldOwnerName(field), field.getName(), BytecodeHelper.getTypeDescription(type));
             operandStack.push(type);
@@ -1343,7 +1344,8 @@ public class AsmClassGenerator extends ClassGenerator {
         OperandStack operandStack = controller.getOperandStack();
         if (field.isHolder() && !controller.isInGeneratedFunctionConstructor()) {
             mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "get", "()Ljava/lang/Object;", false);
-            operandStack.push(ClassHelper.OBJECT_TYPE);
+            operandStack.push(ClassHelper.OBJECT_TYPE); // erased return type
+            operandStack.doGroovyCast(field.getOriginType()); // GROOVY-11068
         } else {
             operandStack.push(type);
         }
@@ -1446,6 +1448,7 @@ public class AsmClassGenerator extends ClassGenerator {
             PropertyExpression pexp = thisPropX(true, variableName);
             pexp.getObjectExpression().setSourcePosition(expression);
             pexp.getProperty().setSourcePosition(expression);
+            pexp.setType(expression.getType());
             pexp.copyNodeMetaData(expression);
             pexp.visit(this);
         }
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index 00692446b6..40bf98d361 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -322,6 +322,29 @@ final class MethodReferenceTest {
         '''
     }
 
+    @Test // instance::instanceMethod -- GROOVY-11068
+    void testConsumerII3() {
+        assertScript shell, '''
+            @Grab('org.apache.pdfbox:pdfbox:2.0.28')
+            import org.apache.pdfbox.pdmodel.*
+            @Grab('io.vavr:vavr:0.10.4')
+            import io.vavr.control.Try
+
+            @CompileStatic
+            def test(PDDocument doc) {
+                extraPages().forEach {
+                    it.forEach(doc::addPage) // expect operand PDDocument
+                }
+            }
+
+            Try<Iterable<PDPage>> extraPages() {
+                Try.success([new PDPage()])
+            }
+
+            test(new PDDocument())
+        '''
+    }
+
     @Test // instance::instanceMethod -- GROOVY-9813
     void testFunctionII() {
         String asList = '''
@@ -741,7 +764,7 @@ final class MethodReferenceTest {
                 }
                 private static class Y extends B {
                     Y(A a) {
-                      super(a)
+                        super(a)
                     }
                 }
             }
@@ -809,7 +832,7 @@ final class MethodReferenceTest {
             void test() {
                 IntFunction<Integer[]> f = Integer[]::new;
                 def result = [1, 2, 3].stream().toArray(f)
-                result == new Integer[] {1, 2, 3}
+                assert result == new Integer[] {1, 2, 3}
             }
 
             test()
@@ -822,7 +845,7 @@ final class MethodReferenceTest {
             @CompileStatic
             void test() {
                 def result = [1, -2, 3].stream().map(Math::abs).collect(Collectors.toList())
-                assert [1, 2, 3] == result
+                assert result == [1, 2, 3]
             }
 
             test()