[
https://issues.apache.org/jira/browse/GROOVY-12523?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132042#comment-18132042
]
ASF GitHub Bot commented on GROOVY-12523:
-----------------------------------------
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.
> STC: x.@name is accepted for a private field of a superclass when the type of
> x is a subclass
> ---------------------------------------------------------------------------------------------
>
> Key: GROOVY-12523
> URL: https://issues.apache.org/jira/browse/GROOVY-12523
> Project: Groovy
> Issue Type: Bug
> Components: Static Type Checker
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> In a class nested in {{Outer}}, the type checker accepts {{sub.@f}}, where
> {{f}} is a private field of {{Outer}} and {{sub}} is typed as a subclass of
> {{Outer}}:
> {code:groovy}
> @groovy.transform.TypeChecked
> class Outer {
> private String f = 'outer'
> static class Sub extends Outer {
> String read(Sub sub) { sub.@f }
> }
> }
> new Outer.Sub().read(new Outer.Sub()) // MissingFieldException: No such
> field: f for class: Outer$Sub
> {code}
> Dynamic Groovy and {{@TypeChecked}} throw {{MissingFieldException}}, because
> the meta-class of a subclass offers no private field of its superclass.
> {{@CompileStatic}} reads the field. javac rejects {{sub.f}} ("f has private
> access in Outer"), since a private field is not a member of a subclass (JLS
> 8.2). With {{f}} declared in a nested class {{Box}} and {{Sub extends Box}},
> or with a top-level subclass, the type checker already rejects {{sub.@f}}
> with "Cannot access field". Seen in 5.0.8, 6.0.0 and master; 4.0.33 failed at
> run time in every mode.
> Expected: "Cannot access field: f of class: Outer", also for writes,
> closures, lambdas and {{new Sub().@f}}. {{this.@f}}, {{super.@f}}, {{((Outer)
> sub).@f}} and {{sub.@f}} inside {{Outer}} keep compiling.
> PR: https://github.com/apache/groovy/pull/3044
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)