Scott Murphy Heiberg created GROOVY-12661:
---------------------------------------------

             Summary: A @PackedClosures closure silently ignores the delegate, 
owner and thisObject passed to rehydrate instead of failing fast like 
setDelegate
                 Key: GROOVY-12661
                 URL: https://issues.apache.org/jira/browse/GROOVY-12661
             Project: Groovy
          Issue Type: Bug
    Affects Versions: 6.0.0, 7.0.0-alpha-1
            Reporter: Scott Murphy Heiberg


With {{@PackedClosures}} under dynamic compilation, 
{{PackedClosure.setDelegate}} refuses a delegate other than the owner, because 
the hoisted body binds its free names to the owner at compile time. 
{{Closure.rehydrate}} writes the delegate, owner and thisObject fields on the 
copy directly, so it bypasses that guard. The packed body keeps calling the 
original owner, and the new delegate or owner is silently ignored.

{code:groovy}
class D { String foo() { 'delegate' } }

@groovy.transform.PackedClosures
class O {
    String foo() { 'owner' }
    def m(D d) {
        def c = { -> foo() }
        println c.rehydrate(d, d, d)()
        println c.rehydrate(d, this, this).delegate == d
        c.delegate = d
    }
}
new O().m(new D())
{code}

*Actual:* prints {{owner}} and {{true}}, then the last line throws 
UnsupportedOperationException ("Cannot set a delegate on a @PackedClosures 
closure ..."). Rehydrating onto another owner of the same class also returns 
the original owner's result.

*Expected:* rehydrate refuses a delegate, owner or this object the packed body 
cannot honour, with the same UnsupportedOperationException as setDelegate. 
Without the annotation the closure prints {{delegate}}.

Cause: PackedClosure guards setDelegate and setResolveStrategy but not 
rehydrate, which sets the fields without calling setDelegate.

Verified on 6.0.0 and master.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to