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

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 82a4089e17 GROOVY-8946: STC: purge first assignment type of closure 
shared variable
82a4089e17 is described below

commit 82a4089e17caee98f36dae3cb35c221456afe9fe
Author: Eric Milles <[email protected]>
AuthorDate: Wed Nov 29 15:15:05 2023 -0600

    GROOVY-8946: STC: purge first assignment type of closure shared variable
    
    3_0_X backport
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |  1 +
 .../asm/sc/ClosuresStaticCompileTest.groovy        | 85 +++++++++++-----------
 .../asm/sc/StaticCompileFlowTypingTest.groovy      | 46 +++++++++++-
 3 files changed, 84 insertions(+), 48 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 648d1066dd..d9d8a8d04e 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2649,6 +2649,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                         entry.getKey().putNodeMetaData(marker, value);
                     }
                 }
+                entry.getKey().removeNodeMetaData(DECLARATION_INFERRED_TYPE); 
// GROOVY-8946
             }
         }
     }
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy 
b/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy
index ce7a420b91..e7fa9f3b4b 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/ClosuresStaticCompileTest.groovy
@@ -23,17 +23,18 @@ import groovy.transform.stc.ClosuresSTCTest
 /**
  * Unit tests for static compilation: closures.
  */
-class ClosuresStaticCompileTest extends ClosuresSTCTest implements 
StaticCompilationTestSupport {
+final class ClosuresStaticCompileTest extends ClosuresSTCTest implements 
StaticCompilationTestSupport {
 
     // GROOVY-5584
     void testEachOnMapClosure() {
         assertScript '''
-                def test() {
-                    def result = ""
-                    [a:1, b:3].each { key, value -> result += "$key$value" }
-                    assert result == "a1b3"
-                }
-                test()'''
+            def test() {
+                def result = ""
+                [a:1, b:3].each { key, value -> result += "$key$value" }
+                assert result == "a1b3"
+            }
+            test()
+        '''
     }
 
     // GROOVY-5811
@@ -65,48 +66,44 @@ class ClosuresStaticCompileTest extends ClosuresSTCTest 
implements StaticCompila
     // GROOVY-6522
     void testShouldCallClosure() {
         assertScript '''
-class Sample {
-
-    Closure formatFirstName
-    Closure formatLastName
-
-    void doStuff (String fname, String lname, Closure callback) {
-        formatFirstName(fname) { String fnameError, String formattedFname ->
-            formatLastName(lname) { String lnameError, String formattedLname ->
-                String errors = "${fnameError ? "${fnameError}, " : 
''}${lnameError ?: ''}"
-                callback(errors, formattedFname, formattedLname)
+            class Sample {
+                Closure formatFirstName, formatLastName
+
+                void doStuff (String fname, String lname, Closure callback) {
+                    formatFirstName(fname) { String fnameError, String 
formattedFname ->
+                        formatLastName(lname) { String lnameError, String 
formattedLname ->
+                            String errors = "${fnameError ? "${fnameError}, " 
: ''}${lnameError ?: ''}"
+                            callback(errors, formattedFname, formattedLname)
+                        }
+                    }
+                }
             }
-        }
-    }
-
-}
 
-Closure ffn = { String fname, Closure callback ->
-    String firstInitial = fname?.substring(0,1)
-
-    if (!firstInitial)
-        callback('invalid first name', null)
-    else
-        callback(null, firstInitial.toLowerCase())
-}
-
-Closure fln = { String lname, Closure callback ->
-    String lastPrefix = lname?.size() > 2 ? lname.substring(0,3) : null
+            Closure ffn = { String fname, Closure callback ->
+                String firstInitial = fname?.substring(0,1)
+                if (!firstInitial)
+                    callback('invalid first name', null)
+                else
+                    callback(null, firstInitial.toLowerCase())
+            }
 
-    if (!lastPrefix)
-        callback('invalid last name', null)
-    else
-        callback(null, lastPrefix.toLowerCase())
-}
+            Closure fln = { String lname, Closure callback ->
+                String lastPrefix = lname?.size() > 2 ? lname.substring(0,3) : 
null
+                if (!lastPrefix)
+                    callback('invalid last name', null)
+                else
+                    callback(null, lastPrefix.toLowerCase())
+            }
 
-Sample sample = new Sample(formatFirstName: ffn, formatLastName: fln)
+            Sample sample = new Sample(formatFirstName: ffn, formatLastName: 
fln)
 
-sample.doStuff('John', 'Doe') { String errors, String formattedFname, String 
formattedLname ->
-    if (errors)
-        println errors
-    else
-        println "${formattedFname}.${formattedLname}"
-}'''
+            sample.doStuff('John', 'Doe') { String errors, String 
formattedFname, String formattedLname ->
+                if (errors)
+                    println errors
+                else
+                    println "${formattedFname}.${formattedLname}"
+            }
+        '''
     }
 
     void testMethodVersusPropertyOnCompoundAssignmentTarget() {
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
index 4b48fe48c4..0b6cfbb7b2 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/StaticCompileFlowTypingTest.groovy
@@ -18,12 +18,10 @@
  */
 package org.codehaus.groovy.classgen.asm.sc
 
-import groovy.transform.CompileStatic
 import org.junit.Test
 
 import static groovy.test.GroovyAssert.assertScript
 
-@CompileStatic
 final class StaticCompileFlowTypingTest {
 
     @Test
@@ -42,7 +40,8 @@ final class StaticCompileFlowTypingTest {
         '''
     }
 
-    @Test // GROOVY-9344
+    // GROOVY-9344
+    @Test
     void testFlowTyping2() {
         assertScript '''
             class A {}
@@ -61,7 +60,8 @@ final class StaticCompileFlowTypingTest {
         '''
     }
 
-    @Test // GROOVY-9344
+    // GROOVY-9344
+    @Test
     void testFlowTyping3() {
         assertScript '''
             class A {}
@@ -80,6 +80,44 @@ final class StaticCompileFlowTypingTest {
         '''
     }
 
+    // GROOVY-8946
+    @Test
+    void testFlowTyping4() {
+        assertScript '''
+            /*@GrabResolver(name='grails', 
root='https://repo.grails.org/grails/core')
+            @Grapes([
+                @Grab('javax.servlet:javax.servlet-api:3.0.1'),
+                @Grab('org.grails.plugins:converters:3.3.+'),
+                @Grab('org.grails:grails-web:3.3.+'),
+                @Grab('org.slf4j:slf4j-nop:1.7.33')
+            ])
+            @GrabExclude('org.codehaus.groovy:*')
+            import static grails.converters.JSON.parse
+            */
+            class JSONElement {
+                def getProperty(String name) {
+                    if (name == 'k') return [1,2]
+                }
+            }
+            JSONElement parse(String json) {
+                new JSONElement()
+            }
+
+            @groovy.transform.CompileStatic
+            def test() {
+                def json = parse('[{"k":1},{"k":2}]')
+                def vals = json['k']
+                assert vals == [1,2]
+                boolean result = 'k'.tokenize('.').every { token -> // 'k' 
represents a path like 'a.b.c.d'
+                    json = json[token]
+                }
+                assert result
+                return json // Cannot cast object '[1, 2]' with class 
'java.util.ArrayList' to class 'org.grails.web.json.JSONElement'
+            }
+            test()
+        '''
+    }
+
     @Test
     void testInstanceOf() {
         assertScript '''

Reply via email to