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

   With closure packing (`@PackedClosures` or 
`-Dgroovy.target.closure.pack=true`), the compile-time escape gate in 
`ClosureWriter.collectEscapingClosures` treated only `=` on a non-local target 
and `<<` as escapes. A literal stored or composed into a field, property or 
index by a compound assignment was packed:
   
   ```groovy
   @groovy.transform.PackedClosures
   class C {
       void install(Holder h) { h.handler ?= { x -> x * 2 } }
   }
   class Holder { Closure handler }
   
   def h = new Holder()
   new C().install(h)
   h.handler.delegate = 'some delegate'   // UnsupportedOperationException: 
Cannot set a delegate on a @PackedClosures closure
   ```
   
   `?=` and `??=` store the literal. `<<=` and `>>=` on a Closure slot store a 
`ComposedClosure`, which keeps a clone of the literal (still a packed adapter) 
and passes `setDelegate` on to it. `<<=` on a collection appends the literal, 
and `+=` stores a new collection that contains it. The walk now treats `?=`, 
`??=`, `>>=` and `+=` like `=` when the target is not a local, and `<<=` like 
`<<`. The other compound operators do not leave the literal in the stored value 
for the standard types, so they still pack, as do stores into a local.
   
   Under `@CompileStatic`, `<<=`, `>>=` and `+=` are rewritten into method 
calls before class generation, so they are declined only together with #3171 
(GROOVY-12650), which runs the escape walk before that rewrite. `?=` and `??=` 
keep their shape and are fixed here in every mode.
   
   ## Tests
   
   `PackedClosuresTransformTest.compoundAssignmentEscapesAreDeclined` (dynamic 
and `@TypeChecked`), 
`PackedClosuresTransformTest.compileStaticCompoundStoresAreDeclined` and two 
new rows in `PackedClosureBoundariesTest.boundaries` fail without the change. 
The 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