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

   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 in a ternary or elvis 
branch, or behind a call that wraps or copies it, was packed even when that 
value escapes:
   
   ```groovy
   class Holder { Closure handler }
   
   @groovy.transform.PackedClosures
   class C {
       void install(Holder h, boolean b) { h.handler = b ? { Integer x -> x + 1 
} : null }
       Closure make() { return { Integer x, Integer y -> x + y }.curry(1) }
   }
   
   def h = new Holder()
   new C().install(h, true)
   h.handler.delegate = 'd'   // UnsupportedOperationException: Cannot set a 
delegate on a @PackedClosures closure
   ```
   
   `CurriedClosure` (from `curry`, `rcurry`, `ncurry`) and the `asWritable` 
wrapper pass `setDelegate` on to the closure they hold. `clone`, `dehydrate` 
and `rehydrate` return a copy, and the copy of a packed closure is still 
packed. Seen in 6.0.0 too.
   
   The walk now follows a value marked as escaping through both branches of a 
ternary or elvis, through a cast to `Object` or a `Closure` type, and into the 
receiver of `curry`, `rcurry`, `ncurry`, `asWritable`, `clone`, `dehydrate` and 
`rehydrate`. This covers a store to a field, property or index, a `<<` append, 
a `return` (implicit or explicit), and a list or map literal. `trampoline` and 
the `memoize` family are not followed: their wrappers keep a delegate of their 
own and never pass it on, so a packed closure inside them behaves as an 
unpacked one does. A SAM coercion is not followed either. Uses inside the 
method still pack, for example `(b ? { .. } : { .. })(1)` and `{ .. 
}.curry(1)(2)`.
   
   Under `@CompileStatic` a property store or `<<` append is rewritten into a 
setter or `leftShift` call before class generation; those two shapes are 
declined there only together with #3171 (GROOVY-12650). Returns, stores to a 
field of the same class, and collection literals are declined in every mode.
   
   Merging with the other escape-walk PRs: with #3177 (GROOVY-12656) it merges 
cleanly; afterwards its composition branches can call `markValue` instead of 
`mark` so a ternary inside a composition is followed too. With #3172 
(GROOVY-12651) one hunk in `visitBinaryExpression` conflicts: keep #3172's 
operator conditions and call `markValue` in both branches.
   
   ## Tests
   
   
`PackedClosuresTransformTest.conditionalAndWrappedClosuresEscapeWhereTheirValueDoes`
 (dynamic and `@TypeChecked`), 
`PackedClosuresTransformTest.compileStaticConditionalAndWrappedEscapesAreDeclined`,
 and a new 'returned from a ternary' 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