codeconsole opened a new pull request, #3173:
URL: https://github.com/apache/groovy/pull/3173
With closure packing enabled (`-Dgroovy.target.closure.pack=true` or
`@PackedClosures`), a closure written in a constructor or in an instance
initializer block was packed even when it escapes:
```groovy
class P { P(List<Closure> s) { s << { x -> x } } } // packed:
PackedClosure$Fixed1
class Q { Closure f; { f = { x -> x } } } // packed:
PackedClosure$Fixed1
```
`ClosureWriter` asked `WriterController.getMethodNode()` for the enclosing
method, and that is null while a constructor is being written. The escape gate,
the serialization gate and the `@PackedClosures` mode lookup therefore saw
nothing. This applies to dynamic, `@TypeChecked` and `@CompileStatic` code.
Instance initializer blocks are inlined into each constructor by the Verifier,
so they were affected as well. Under `@PackedClosures` the escaped closure then
failed the packed adapter's runtime guard as soon as a delegate was set on it.
`ClosureWriter.enclosingMethod()` now returns the constructor node when
there is no method node, and the escape walk, the serialization walk and the
mode lookup use it. `@PackedClosures` can now be placed on a constructor; its
scope includes the initializer blocks inlined into it. A field initializer
keeps its own decline reason.
Seen in 6.0.0 too.
Merging with #3171 (GROOVY-12650): `annotatedMode()` conflicts textually
(resolve as `return annotatedMode(enclosingMethod(),
controller.getClassNode());`), and #3171's marking would then also need to
cover constructors and object initializer statements under `@CompileStatic`.
Until both are in, the `@CompileStatic` rows for `<<` in a constructor and in
an initializer block are left out of `constructorAndInitializerEscapesDecline`.
## Tests
`PackedClosureBoundariesTest.constructorAndInitializerEscapesDecline`
(field, property and append stores and a Serializable cast, in a constructor
and in an initializer block, dynamic, `@TypeChecked` and `@CompileStatic`),
`PackedClosuresTransformTest.escapingClosuresInConstructorsAndInitializersAreDeclined`
and
`PackedClosuresTransformTest.modeOnAConstructorGovernsItsBodyAndInitializers`
fail without the change.
`PackedClosureBoundariesTest.constructorAndInitializerLocalClosuresPack` checks
that non-escaping closures still pack. The packing test classes,
`org.codehaus.groovy.classgen.asm.sc.*` and `groovy.transform.stc.*` 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]