[ 
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.

  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.

PR: https://github.com/apache/groovy/pull/3044


> 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.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to