[
https://issues.apache.org/jira/browse/GROOVY-12511?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Scott Murphy Heiberg updated GROOVY-12511:
------------------------------------------
Description:
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.
PR: https://github.com/apache/groovy/pull/3044
was:
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.
> 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
> Priority: Major
>
> 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.
> PR: https://github.com/apache/groovy/pull/3044
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)