[ 
https://issues.apache.org/jira/browse/GROOVY-12514?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132041#comment-18132041
 ] 

ASF GitHub Bot commented on GROOVY-12514:
-----------------------------------------

codeconsole opened a new pull request, #3049:
URL: https://github.com/apache/groovy/pull/3049

   This makes qualified `this` and `super` in nested classes (`N.this`, 
`N.super`, `Outer.super`) work under `@TypeChecked` and `@CompileStatic` as in 
Java. `Outer.super` from a closure or an inner class goes through the `super$` 
helper methods that statically compiled closures use for `super` calls, so the 
two bugs of those helpers that it runs into are fixed first: GROOVY-12516 and 
GROOVY-12518. Each issue has its own commit (GROOVY-12514 one for `this` and 
one for `super`, GROOVY-12518 two more, for overloaded setters and for 
extension accessors).
   
   These were split out of #3044, which keeps the private member fixes for 
nested classes, and they build on it: GROOVY-12512 there makes `Outer.super` 
without an enclosing instance (in a static nested class, or in an anonymous 
class in a static method) a compile error in every mode, and the support for 
`Outer.super` here relies on that check rather than repeating it. Until #3044 
is merged, this pull request also shows its commits; the seven to review start 
at "GROOVY-12514: STC: allow a qualified this that names the current nested 
class".
   
   Three cases combine this with other open pull requests, and the second of 
each pair to be merged adds their tests:
   
   - `Outer.super.sm()` for a static method that `Outer` hides needs 
GROOVY-12519 (#3045), as `super.sm()` does;
   - `Outer.super.x = v`, `++` and compound assignments with overloaded 
setters, in dynamic Groovy and under `@TypeChecked`, need GROOVY-12521 (#3047), 
as `super.x = v` does;
   - `super.text += v` under `@TypeChecked`, where the accessors are extension 
methods that the class overrides, needs GROOVY-12522 (#3048).
   
   ```groovy
   class Base { String p() { 'base' } }
   
   @CompileStatic
   class Outer extends Base {
       String p() { 'outer' }
       static class N extends Base {
           String p() { 'n' }
           String test() { N.super.p() }      // was "No such property: super"; 
now 'base' (GROOVY-12514)
       }
       class Inner {
           String test() { Outer.super.p() }  // was "No such property: super"; 
now 'base', on the enclosing instance (GROOVY-12517)
       }
   }
   ```
   
   ## GROOVY-12514: `N.this` and `N.super` within a nested class `N`
   
   `N.this`, which is `this`, failed under `@TypeChecked` and `@CompileStatic` 
with "No such property: this", and `N.super.m()` and `N.super.p` with "No such 
property: super", in static nested, inner and enum classes and in closures and 
lambdas there. Both now compile, as in javac. `N.super` means `super` in every 
mode: dynamic Groovy read `N.super.p` as `N.this.p`. In a static context they 
remain errors. `Top.this` and `Top.super` in a top-level class keep their error 
(GROOVY-4321, `StaticThisTest`).
   
   ## GROOVY-12517: `Outer.super` in a class nested in `Outer`
   
   In an inner class, an anonymous class, a closure or lambda in one of them, 
or an inner class of an inner class, `Outer.super.m()` and `Outer.super.p` 
failed under `@TypeChecked` and `@CompileStatic` with "No such property: 
super". They now call the superclass's member on the enclosing `Outer` 
instance, as in javac. Under `@CompileStatic` the calls go through `super$` 
helper methods of `Outer`, since only `Outer` may call its superclass's methods 
non-virtually. Property reads and writes, `++` and compound assignments work 
too. Dynamic Groovy read and wrote `Outer.super.p` as `Outer.this.p`; it now 
uses the superclass's property. Without an enclosing instance of `Outer` it 
stays an error.
   
   ## GROOVY-12516 and GROOVY-12518: `super` in closures under `@CompileStatic`
   
   - GROOVY-12516: two closures or lambdas of one class calling the same super 
method generated the `super$` helper twice, and the class failed to load with 
`ClassFormatError`. The helper is generated once.
   - GROOVY-12518: `super.p`, `super.name` and `super.name = v` in a closure or 
lambda failed with `VerifyError` (the superclass accessor was called with 
`invokespecial` from the closure class); they now go through `super$` helpers, 
like super method calls. `super.n++`, `++super.n` and `super.n += v` read the 
property through a dynamic call that failed with `MissingPropertyException` 
when the class declares the same property; they now call the superclass's 
accessors. When the superclass overloads the setter (`setX(int)` and 
`setX(String)`), the setter is the one the type checker selected for the value. 
When an accessor is an extension method, such as `getText()` and 
`setText(String)` of a `File`, `super.text += v` compiled to a dynamic property 
access; it now calls the extension methods directly.
   
   ## Behaviour changes
   
   Code that changes meaning in dynamic Groovy and under `@TypeChecked`, each 
time to javac's meaning: `N.super.p` inside `N` reads the superclass's property 
instead of `N.this.p` (GROOVY-12514); `Outer.super.p` and `Outer.super.f` in a 
class nested in `Outer` use the superclass's member instead of `Outer.this`'s 
(GROOVY-12517).
   
   Code that failed to compile and now compiles: GROOVY-12514 and GROOVY-12517. 
Code that failed at run time and now runs under `@CompileStatic`: GROOVY-12516 
and GROOVY-12518.
   
   ## Tests
   
   Each commit has tests that fail without it, marked with its JIRA key: 
`gls.innerClass.InnerClassTest`, `ClosuresSTCTest` (and 
`ClosuresStaticCompileTest`), `FieldsAndPropertiesSTCTest` (and 
`FieldsAndPropertiesStaticCompileTest`) and, for the overloaded setters and the 
extension accessors, `FieldsAndPropertiesStaticCompileTest` alone. 15,027 tests 
in the `groovy`, `gls`, `bugs`, `org.codehaus.groovy.classgen`, `transform`, 
`runtime`, `reflection`, `vmplugin`, `control` and `ast` packages and the stub 
generator tests pass, apart from `bugs.Groovy12363`, which fails on master too 
when it runs after `bugs.Groovy12142` in the same JVM (#3025 fixes it). 
`groovy-contracts`, `groovy-typecheckers`, `groovy-ginq`, 
`groovy-macro-library`, `groovy-json`, `groovy-xml` and `groovy-templates` pass 
their tests, and every subproject compiles its main and test sources. The 
Checkstyle and CodeNarc gates pass.
   
   ## Backport
   
   GROOVY-12514 and GROOVY-12517 change what `N.super.p` and `Outer.super.p` 
mean in dynamic Groovy, so whether to backport them is left to the maintainers; 
GROOVY-12516 and GROOVY-12518 only make code that failed run.
   




> STC: qualified this or super naming the current nested class (N.this, N.super 
> inside N) is rejected
> ---------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12514
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12514
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Static Type Checker
>    Affects Versions: 6.0.0
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> {{N.this}} inside a nested class {{N}} is {{this}}, and {{N.super.m()}} is 
> {{super.m()}}. The type checker rejects both:
> {code:groovy}
> class Base { String m() { 'base' } }
> @groovy.transform.CompileStatic
> class Box {
>     static class N extends Base {
>         String id = 'n'
>         String m() { 'n' }
>         String test() { N.this.id + ' ' + N.super.m() }
>     }
> }
> new Box.N().test()
> {code}
> {code}
> [Static type checking] - No such property: this for Class or static property 
> for class: Box$N
> [Static type checking] - No such property: super for Class or static property 
> for class: Box$N
> {code}
> (plus the errors that follow from them for {{id}} and {{m()}}). Dynamic 
> Groovy returns {{n base}}, and javac accepts the same code. The same errors 
> are reported under {{@TypeChecked}}, for an inner (non-static) class {{N}}, 
> for {{N.this.pm()}} and {{N.this.id = 'w'}}, for {{N.super.p}}, and inside a 
> closure or lambda in {{N}}. {{N.this}} inside an anonymous class created in 
> {{N}} already works, because {{N}} is an outer class there. Seen in 5.0.8, 
> 6.0.0 and master.
> In a top-level class, {{Top.this}} and {{Top.super}} are rejected in every 
> mode ("The usage of 'Class.this' and 'Class.super' is only allowed in 
> nested/inner classes."), as GROOVY-4321 decided and {{StaticThisTest}} pins, 
> so they are not part of this issue.
> Expected: under {{@TypeChecked}} and {{@CompileStatic}}, {{N.this}} and 
> {{N.super}} inside the nested class {{N}} mean {{this}} and {{super}}, as in 
> dynamic Groovy, except in a static context, where they stay an error.
> PR: https://github.com/apache/groovy/pull/3044



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

Reply via email to