codeconsole opened a new pull request, #3185:
URL: https://github.com/apache/groovy/pull/3185
GROOVY-11858 changed `ClosureMetaClass.invokeMethod` to defer a method found
on the closure's metaclass (an Object extension method such as `with`, `tap` or
`sprintf`, called with implicit this from the closure body), so that delegate
and owner are tried first. When neither can take the call, the fallback ran the
deferred method but did not return its result, and then threw
`MissingMethodException`:
```groovy
int count = 0
def c = { -> with { ++count } }
c.resolveStrategy = Closure.DELEGATE_ONLY
c.delegate = null
assert c() == 1 // 2 on 6.0.0
assert count == 1 // 2 on 6.0.0
```
From compiled code, the indy `MissingMethodException` handler retries
through `GroovyObject.invokeMethod`, so the method runs a second time. A direct
`MetaClass.invokeMethod(sender, ...)` call throws instead. The fallback now
returns the result, which restores the 4.0.x and 5.0.x behaviour. 6.0.0 is
affected.
## Tests
`ClosureDelegationTest.testClosureExtensionCalledOnceWhenDelegateAndOwnerUnavailable`
(null delegate, self delegate, `dehydrate`, `rehydrate` with `OWNER_ONLY`),
`testClosureExtensionCalledOnceWhenDelegateAndOwnerUnavailableTypeChecked` and
`testClosureExtensionResultReturnedByMetaClass` fail without the change.
`groovy.lang.*Closure*`, `groovy.*Closure*`, `org.codehaus.groovy.runtime.*`,
`gls.invocation.*`, `groovy.ThisAndSuperTest`, `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]