Scott Murphy Heiberg created GROOVY-12578:
---------------------------------------------
Summary: A closure's own method runs twice when neither the
delegate nor the owner can take the call
Key: GROOVY-12578
URL: https://issues.apache.org/jira/browse/GROOVY-12578
Project: Groovy
Issue Type: Bug
Components: groovy-runtime
Affects Versions: 6.0.0
Reporter: Scott Murphy Heiberg
For an implicit-this call in a closure body to a method the closure inherits,
such as {{toString()}} or a default Groovy method like {{with}}, {{tap}} or
{{identity}}, {{ClosureMetaClass}} tries the delegate and the owner first and
keeps the closure's own method as the fallback. When neither can take the call,
it invokes the fallback, discards the result and throws
{{MissingMethodException}}; invokedynamic catches it and calls the method again
through {{GroovyObject.invokeMethod}}, so the method runs twice:
{code:groovy}
class C { Closure<Integer> withCount() { { -> int n = 0; with { n++ }; n } } }
Closure<Integer> c = new C().withCount().rehydrate(null, null, null)
c.resolveStrategy = Closure.OWNER_ONLY
assert c() == 1 // 2
{code}
Called through the meta class directly ({{c.metaClass.invokeMethod(...)}}), the
call throws {{MissingMethodException}} after running the method. A closure
without an owner and with {{OWNER_ONLY}}, or with {{DELEGATE_ONLY}} and no
delegate, reaches the fallback. Expected: the fallback's result is returned.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)