[
https://issues.apache.org/jira/browse/GROOVY-12576?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Scott Murphy Heiberg updated GROOVY-12576:
------------------------------------------
Description:
Under {{@CompileStatic}}, an implicit-this call to a method of {{Object}} in a
closure or lambda is made on the closure itself:
{code:groovy}
@groovy.transform.CompileStatic
class C {
String m() { new StringBuilder().with { append('w'); toString() } }
}
assert new C().m() == 'w' // C$_m_closure1@1b2c3d4
{code}
4.0.33 returns {{'w'}}. The type checker looks up the methods of {{Closure}}
before the delegate and the owner, and that lookup also returns the methods
{{Closure}} inherits from {{Object}}. With {{with}}, {{tap}}, {{identity}} or a
{{@DelegatesTo(strategy = DELEGATE_FIRST)}} method this ignores the delegate;
in a plain closure it ignores the owner, and in a lambda the enclosing
instance, which Java and dynamic Groovy both use. This happens in methods,
constructors, field initializers and static initializers.
Dynamic Groovy tries the closure first only for methods that {{Closure}} or
{{GroovyObject}} declare; a method the closure inherits from elsewhere goes to
the delegate or the owner according to the resolve strategy. Expected: the same
under static compilation. Methods declared by {{Closure}}, such as
{{getDelegate()}}, still resolve against the closure, and a closure without a
this object (from {{dehydrate()}}) uses its own method.
PR: https://github.com/apache/groovy/pull/3102
was:
Under {{@CompileStatic}}, an implicit-this call to a method of {{Object}} in a
closure or lambda is made on the closure itself:
{code:groovy}
@groovy.transform.CompileStatic
class C {
String m() { new StringBuilder().with { append('w'); toString() } }
}
assert new C().m() == 'w' // C$_m_closure1@1b2c3d4
{code}
4.0.33 returns {{'w'}}. The type checker looks up the methods of {{Closure}}
before the delegate and the owner, and that lookup also returns the methods
{{Closure}} inherits from {{Object}}. With {{with}}, {{tap}}, {{identity}} or a
{{@DelegatesTo(strategy = DELEGATE_FIRST)}} method this ignores the delegate;
in a plain closure it ignores the owner, and in a lambda the enclosing
instance, which Java and dynamic Groovy both use. This happens in methods,
constructors, field initializers and static initializers.
Dynamic Groovy tries the closure first only for methods that {{Closure}} or
{{GroovyObject}} declare; a method the closure inherits from elsewhere goes to
the delegate or the owner according to the resolve strategy. Expected: the same
under static compilation. Methods declared by {{Closure}}, such as
{{getDelegate()}}, still resolve against the closure, and a closure without a
this object (from {{dehydrate()}}) uses its own method.
> SC: toString(), hashCode(), equals() and getClass() in a closure ignore the
> delegate and the owner
> --------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12576
> URL: https://issues.apache.org/jira/browse/GROOVY-12576
> Project: Groovy
> Issue Type: Bug
> Components: Static compilation
> Affects Versions: 5.0.8, 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> Under {{@CompileStatic}}, an implicit-this call to a method of {{Object}} in
> a closure or lambda is made on the closure itself:
> {code:groovy}
> @groovy.transform.CompileStatic
> class C {
> String m() { new StringBuilder().with { append('w'); toString() } }
> }
> assert new C().m() == 'w' // C$_m_closure1@1b2c3d4
> {code}
> 4.0.33 returns {{'w'}}. The type checker looks up the methods of {{Closure}}
> before the delegate and the owner, and that lookup also returns the methods
> {{Closure}} inherits from {{Object}}. With {{with}}, {{tap}}, {{identity}} or
> a {{@DelegatesTo(strategy = DELEGATE_FIRST)}} method this ignores the
> delegate; in a plain closure it ignores the owner, and in a lambda the
> enclosing instance, which Java and dynamic Groovy both use. This happens in
> methods, constructors, field initializers and static initializers.
> Dynamic Groovy tries the closure first only for methods that {{Closure}} or
> {{GroovyObject}} declare; a method the closure inherits from elsewhere goes
> to the delegate or the owner according to the resolve strategy. Expected: the
> same under static compilation. Methods declared by {{Closure}}, such as
> {{getDelegate()}}, still resolve against the closure, and a closure without a
> this object (from {{dehydrate()}}) uses its own method.
> PR: https://github.com/apache/groovy/pull/3102
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)