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

   With closure packing (`@PackedClosures` or 
`-Dgroovy.target.closure.pack=true`), the escape walk in 
`ClosureWriter.collectEscapingClosures` marked only a closure literal that is 
the stored, appended or returned value itself. A literal composed with `>>` or 
`<<` was packed even when the composition escapes:
   
   ```groovy
   class Holder { Closure handler }
   
   @groovy.transform.PackedClosures
   class C {
       void install(Holder h, Closure c) { h.handler = c >> { x -> x + 1 } }
       Closure make(Closure c) { return { x -> x + 1 } << c }
   }
   
   def h = new Holder()
   new C().install(h, { x -> x * 2 })
   h.handler.delegate = 'd'   // UnsupportedOperationException: Cannot set a 
delegate on a @PackedClosures closure
   ```
   
   `ComposedClosure` keeps a clone of each operand, and the clone of a packed 
closure is still packed. It passes `setDelegate` on to them, so the literal 
escapes with the composition. Seen in 6.0.0 too.
   
   The walk now follows a value that is marked as escaping through `>>` and 
`<<`, nested compositions included, and through one-argument `rightShift` and 
`leftShift` calls. This covers a store to a field, property or index, a `<<` 
append, a `return`, and a list or map literal. A composition used only in the 
method still packs, for example `(c >> { x -> x + 1 })(n)`. A standalone 
`leftShift(...)` call is still not an escape.
   
   Under `@CompileStatic`, `BinaryExpressionTransformer` turns `c >> { ... }` 
into a `rightShift` call before class generation, and the walk follows that 
form. Returned compositions, compositions stored to a field of the same class, 
and compositions in collection literals are therefore declined in every mode. A 
composition stored through a property setter or appended with `<<` is rewritten 
into a setter or `leftShift` call; under `@CompileStatic` those shapes are 
declined only together with #3171 (GROOVY-12650), which runs the escape walk 
before that rewrite.
   
   ## Tests
   
   `PackedClosuresTransformTest.composedClosuresEscapeWhereTheCompositionDoes` 
(dynamic and `@TypeChecked`), 
`PackedClosuresTransformTest.compileStaticComposedEscapesAreDeclined` and a new 
'returned composed' row in `PackedClosureBoundariesTest.boundaries` fail 
without the change. The closure-packing test classes, 
`org.codehaus.groovy.classgen.asm.sc.*` and `groovy.transform.stc.*` (including 
`ClosuresSTCTest`) pass. The Checkstyle and CodeNarc gates pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to