Scott Murphy Heiberg created GROOVY-12670:
---------------------------------------------
Summary: Closure packing (groovy.target.closure.pack) packs a
dynamic closure that names this, so a rehydrated copy still answers for the
original owner
Key: GROOVY-12670
URL: https://issues.apache.org/jira/browse/GROOVY-12670
Project: Groovy
Issue Type: Bug
Affects Versions: 6.0.0, 7.0.0-alpha-1
Reporter: Scott Murphy Heiberg
With {{-Dgroovy.target.closure.pack=true}}, dynamic code (no annotation) packs
a closure literal whose body has no free name. The check accepts an explicit
this, a method call on this, this.@field, this.&method, Outer.this and
Outer.super.
{code:groovy}
class D { String foo() { 'D.foo' }; String toString() { 'D' } }
class O {
String name
String foo() { 'foo ' + name }
String toString() { 'O:' + name }
List run(O b, D d) {
Closure c = { -> this }
Closure e = { -> this.foo() }
[c.rehydrate(null, b, b)(), c.rehydrate(null, d, d)(),
e.rehydrate(null, b, b)(), e.rehydrate(null, d, d)()]
}
}
println new O(name: 'a').run(new O(name: 'b'), new D())
{code}
*Actual* (with the flag): {{[O:a, O:a, foo a, foo a]}}
*Expected* (as without the flag): {{[O:b, D, foo b, D.foo]}}
A closure class reads an explicit this from getThisObject(), which rehydrate
replaces. The packed closure's body is hoisted into a method of the owner class
and keeps the instance it was created on. The syntactic no-free-name check
({{ClosureWriter.isSyntacticallyDelegateIndependent}}) should treat a body that
names this as not packable.
Verified on 6.0.0 and master.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)