codeconsole opened a new pull request, #3194:
URL: https://github.com/apache/groovy/pull/3194
The closures returned by `trampoline()`, `memoize*()`, `curry()`, `>>`/`<<`
and `asWritable()` do not report or forward the delegation settings of the
closure they wrap:
```groovy
class D { def m() { 'delegate' } }
class O {
def m() { 'owner' }
def run() {
def c = { x -> m() }
assert c.curry(1).thisObject.is(this) // null
def t = c.trampoline()
t.resolveStrategy = Closure.DELEGATE_FIRST
t.delegate = new D()
assert t(1) == 'delegate' // 'owner'
}
}
new O().run()
```
Seen in 4.0.33, 5.0.8 and 6.0.0 too.
- `TrampolineClosure` passed the wrapped closure's delegate as its
`thisObject`, so its `delegate` reported the owner. It now takes the wrapped
closure's `thisObject` and forwards `getDelegate`, `setDelegate`,
`getResolveStrategy` and `setResolveStrategy` to the wrapped closure, as
`ComposedClosure` does. Its `clone()` copies the wrapped closure, so
`with`/`tap`, which clone and then set the delegate, leave the original
trampoline unchanged. Its parameter count and types now come from the wrapped
closure's getters; before, a trampolined writable or composed closure reported
a single `Object[]` parameter.
- `Memoize.MemoizeFunction` gets the same forwarding, `thisObject` and
`clone()`. The copy shares the cache.
- `CurriedClosure`, `ComposedClosure` and `Closure.WritableClosure` forward
`getThisObject` to the closure they call. `getOwner()` of these three still
returns the wrapped closure, which they call through.
One commit per wrapper.
Merging: with #3186 (GROOVY-12665, wrapper rehydrate/dehydrate) this merges
cleanly. With #3190 (GROOVY-12669, memoize rehydrate/dehydrate) one hunk in
`MemoizeFunction` conflicts: keep #3190's `cacheFactory` field and constructor
parameter, make `closure` non-final (needed by `clone()` here), and call
`super(closure.getOwner(), closure.getThisObject())`.
## Tests
These fail without the change:
- `ClosureCurryTest.testThisObject`
- `ClosureComposeTest.testThisObject`
- `ClosureTest.testWritableClosureThisObject` (includes a `@CompileStatic`
case)
- `TrampolineTest`: `testDelegateAndThisObject`,
`testSetDelegateAndResolveStrategy`, `testWith`,
`testParametersOfWrappedClosure`
- `AbstractMemoizeTestCase`: `testDelegateAndThisObject`,
`testSetDelegateAndResolveStrategy`, `testWith`, run by `MemoizeTest`,
`MemoizeAtMostTest`, `MemoizeAtLeastTest` and `MemoizeBetweenTest`
`groovy.lang.*Closure*`, `groovy.*Closure*`,
`org.codehaus.groovy.runtime.*Closure*`,
`org.codehaus.groovy.runtime.trampoline.*`,
`org.codehaus.groovy.runtime.memoize.*`, `MemoizedASTTransformationTest`,
`gls.closures.*`, `groovy.transform.stc.*` and
`org.codehaus.groovy.classgen.asm.sc.*` pass. The Checkstyle and CodeNarc gates
pass.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]