[ 
https://issues.apache.org/jira/browse/GROOVY-12650?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18137318#comment-18137318
 ] 

ASF GitHub Bot commented on GROOVY-12650:
-----------------------------------------

codeconsole opened a new pull request, #3171:
URL: https://github.com/apache/groovy/pull/3171

   Closure packing (GEP-27) should decline a closure literal that visibly 
escapes its method: stored to a field, property or index, appended with `<<`, 
returned, or placed in a collection literal. Under `@CompileStatic` it packed 
two of these shapes:
   
   ```groovy
   class H { Closure value }
   @groovy.transform.CompileStatic def m() {
       List<Closure> l = []
       l << { 1 }          // packed
       def h = new H()
       h.value = { 2 }     // packed
       [l[0].getClass().name, h.value.getClass().name]
   }
   ```
   
   With `-Dgroovy.target.closure.pack=true` this returns two 
`PackedClosure$FixedIt`; dynamic Groovy and `@TypeChecked` return two closure 
classes. The escape walk in `ClosureWriter` runs at class generation. Under 
static compilation, `BinaryExpressionTransformer` has already turned the `<<` 
into a `leftShift` call and the store into a setter call, and the walk only 
recognises the binary-expression forms.
   
   `StaticCompilationTransformer` now calls 
`ClosureWriter.markEscapingClosures` before it transforms each method body. 
This runs the same escape walk over the untransformed code and marks the 
escaping closure literals. The escape gate honours the mark, then still runs 
its own walk at class generation, which also sees the implicit `return`s the 
Verifier adds later. The marking only runs when the flag or a non-DISABLED 
`@PackedClosures` requests packing. Because declines go through the same gate, 
WARN/STRICT report these closures with the usual "escapes its method" reason.
   
   ## Tests
   
   
`PackedClosuresTransformTest.escapingClosuresAreDeclinedTheSameUnderCompileStatic`,
 `compileStaticReportsAnEscapeHiddenByARewrite` and 
`compileStaticFlagPathDeclinesAnEscapeHiddenByARewrite` fail without the 
change. The first runs every escape shape under dynamic, `@TypeChecked` and 
`@CompileStatic`, and checks that an explicit `leftShift(...)` call and an 
owner-local closure still pack. The closure-packing test classes, 
`org.codehaus.groovy.classgen.asm.sc.*` and `groovy.transform.stc.*` pass. The 
Checkstyle and CodeNarc gates pass.
   




> Closure packing packs closures that escape via << or a setter store under 
> @CompileStatic
> ----------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12650
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12650
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 7.0.0-alpha-1
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> {code:groovy}
> // -Dgroovy.target.closure.pack=true, or @PackedClosures on the class/method
> class H { Closure value }
> @groovy.transform.CompileStatic def m() {
>     List<Closure> l = []
>     l << { 1 }
>     def h = new H()
>     h.value = { 2 }
>     [l[0].getClass().name, h.value.getClass().name]
> }
> m()
> {code}
> *Actual:* {{[org.codehaus.groovy.runtime.PackedClosure$FixedIt, 
> org.codehaus.groovy.runtime.PackedClosure$FixedIt]}}. Both escaping closures 
> are packed.
> *Expected:* {{[Script1$_m_closure1, Script1$_m_closure2]}}. Both closures 
> escape the method and should be declined from packing, as they are in dynamic 
> Groovy and under {{@TypeChecked}}.
> The packing escape check ({{ClosureWriter.collectEscapingClosures}}) walks 
> the method body at class generation. Under static compilation, 
> {{BinaryExpressionTransformer}} has already rewritten the {{<<}} into a 
> {{leftShift}} call and the setter-backed property store into a setter call, 
> so the walk no longer recognises them as escapes. Other escape shapes 
> (subscript, map and field stores, named constructor arguments, stores to a 
> property of the same class) are already declined under {{@CompileStatic}}.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to