codeconsole opened a new pull request, #3050:
URL: https://github.com/apache/groovy/pull/3050
In a class nested in `Outer`, the type checker accepted `sub.@f`, where `f`
is a private field of `Outer` and `sub` is typed as a subclass of `Outer`.
Dynamic Groovy and `@TypeChecked` threw `MissingFieldException`, because the
meta-class of a subclass offers no private field of its superclass, and javac
rejects it ("f has private access in Outer"); `@CompileStatic` read the field.
With `f` declared in a nested class `Box` and `Sub extends Box`, or with a
top-level subclass, the same access was already rejected. Both modes now report
"Cannot access field: f of class: Outer", also for writes, compound
assignments, closures, lambdas, `new Sub().@f` and a receiver typed as a deeper
subclass.
```groovy
@TypeChecked
class Outer {
private String f = 'outer'
static class Sub extends Outer {
String read(Sub sub) { sub.@f } // threw MissingFieldException; now
"Cannot access field: f of class: Outer"
}
}
```
Split out of #3044, and builds on it: the rule reuses the check for a
private member reached through a subclass (GROOVY-12510, GROOVY-12511) and the
exception for a variable declared with the field's class (GROOVY-12513). Until
#3044 is merged, this pull request also shows its commits; the one to review is
"GROOVY-12523: STC: reject x.@name for a private field of a superclass when the
type of x is a subclass". `Sub.this.@f` inside `Sub` is rejected too once
GROOVY-12514 (#3049) makes `Sub.this` compile there; whichever of the two is
merged second adds that case to the tests.
## Behaviour change
Under `@CompileStatic`, which read the field directly, such code stops
compiling; `((Outer) sub).@f` reads it. `this.@f` and `super.@f`, which read
the field directly in every mode, keep working, as do `sub.@f` in `Outer`
itself and a receiver declared as `Outer`. Private static fields are left
alone, as private static methods are. 5.0.8, 6.0.0 and master compile such
code; 4.0.33 failed at run time in every mode. The object orientation guide now
says that within a subclass only `this.@name` and `super.@name` reach such a
field.
## Tests
`FieldsAndPropertiesSTCTest` (also run by
`FieldsAndPropertiesStaticCompileTest`): thirteen rejected forms and a script
with the forms that keep working; the statically compiled test also reads the
field through a cast. They fail without the change. 15,011 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). In that
run the new test also failed, on a `Sub.this.@f` case that needs GROOVY-12514;
with that case removed, `FieldsAndPropertiesSTCTest` and
`FieldsAndPropertiesStaticCompileTest` pass. `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.
--
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]