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)