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)

Reply via email to