Scott Murphy Heiberg created GROOVY-12673:
---------------------------------------------
Summary: Closure wrappers (trampoline, memoize, curry, compose,
asWritable) report the wrong delegate or thisObject and ignore delegate and
resolveStrategy changes
Key: GROOVY-12673
URL: https://issues.apache.org/jira/browse/GROOVY-12673
Project: Groovy
Issue Type: Bug
Affects Versions: 5.0.8, 4.0.33, 6.0.0, 7.0.0-alpha-1
Reporter: Scott Murphy Heiberg
{code:groovy}
class D { def m() { 'delegate' } }
class O {
def m() { 'owner' }
def run() {
def c = { x -> m() }
assert c.curry(1).thisObject.is(this) // fails: null (also for c
>> {...}, and c.asWritable().getThisObject())
def t = c.trampoline()
assert t.thisObject.is(this) // fails: the delegate of c
t.resolveStrategy = Closure.DELEGATE_FIRST
t.delegate = new D()
assert t(1) == 'delegate' // fails: 'owner'
def m = { x -> m() }.memoize()
m.resolveStrategy = Closure.DELEGATE_FIRST
m.delegate = new D()
assert m(1) == 'delegate' // fails: 'owner'
}
}
new O().run()
{code}
*Actual:* curried and composed closures report a null thisObject. A writable
closure's getThisObject() returns null, so the property read under
@CompileStatic gives null too. A trampolined closure reports the wrapped
closure's delegate as its thisObject and its owner as its delegate. A memoized
closure reports the owner as its delegate and null as its thisObject. Setting
delegate or resolveStrategy on a trampolined or memoized closure has no effect
on the call. {{c.asWritable().trampoline()}} also reports one Object[]
parameter instead of the parameters of c.
*Expected:* a wrapper reports the delegate, resolve strategy and thisObject of
the closure it wraps, and setting delegate or resolveStrategy on it applies to
that closure, as ComposedClosure and CurriedClosure already do for delegate and
resolveStrategy.
Cause: TrampolineClosure passes original.getDelegate() as thisObject, and
neither TrampolineClosure nor Memoize.MemoizeFunction forwards the delegate and
resolve strategy. CurriedClosure, ComposedClosure and WritableClosure do not
forward getThisObject. TrampolineClosure reads the wrapped closure's parameter
fields instead of its getters.
Verified on 4.0.33, 5.0.8, 6.0.0 and master.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)