Scott Murphy Heiberg created GROOVY-12511:
---------------------------------------------
Summary: SC: private method of the enclosing class is called on
the wrong instance from an inner or anonymous subclass
Key: GROOVY-12511
URL: https://issues.apache.org/jira/browse/GROOVY-12511
Project: Groovy
Issue Type: Bug
Components: Static compilation
Affects Versions: 6.0.0
Reporter: Scott Murphy Heiberg
A class nested in {{Box}} that also extends {{Box}} does not inherit the
private members of {{Box}} (JLS 8.2). An unqualified call to a private method
of {{Box}} inside it therefore refers to the enclosing {{Box}} instance, as if
written {{Box.this.im()}}. javac, dynamic Groovy and {{@TypeChecked}} call it
on the enclosing instance. {{@CompileStatic}} calls it on {{this}}, the
subclass instance.
{code:groovy}
@groovy.transform.CompileStatic
class Box {
String id = 'outer'
private String im() { 'im:' + id }
class Sub extends Box {
Sub() { id = 'sub' }
String test() { im() }
}
String anon() {
new Box() {
{ id = 'anon' }
String test() { im() }
}.test()
}
}
def box = new Box()
[new Box.Sub(box).test(), box.anon()]
{code}
Result:
* {{@CompileStatic}}: {{im:sub}}, {{im:anon}}
* dynamic Groovy and {{@TypeChecked}}: {{im:outer}}, {{im:outer}}
* javac (the same classes in Java): {{im:outer}} for both
The same happens when the call is inside a closure or lambda in the subclass,
and for {{this.im()}} in the anonymous class ({{im:anon}} under
{{@CompileStatic}}, {{im:outer}} in dynamic Groovy; javac rejects {{this.im()}}
with "cannot find symbol"). A private field read the same way, {{f}} inside
{{Sub}}, gives the enclosing instance's field in dynamic Groovy,
{{@TypeChecked}} and javac, and the subclass instance's own copy under
{{@CompileStatic}}.
Seen in 4.0.33, 5.0.8, 6.0.0 and master.
Expected: {{@CompileStatic}} calls the private method (and reads the private
field) on the enclosing instance, like the other modes and javac.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)