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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]