[
https://issues.apache.org/jira/browse/GROOVY-12610?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135622#comment-18135622
]
ASF GitHub Bot commented on GROOVY-12610:
-----------------------------------------
codeconsole opened a new pull request, #3137:
URL: https://github.com/apache/groovy/pull/3137
Under `@TypeChecked`, property access to a private instance field of a
superclass, made through a subclass that is nested in that superclass, compiled
and then failed at run time:
```groovy
class Base {
private String z = 'x'
@groovy.transform.TypeChecked
static class Sub extends Base {
def m() { this.z }
}
}
new Base.Sub().m() // MissingPropertyException: No such property: z for
class: Base$Sub
```
The same happened for `z`, `super.z`, closure and lambda forms, writes,
`that.z`, and access from another nested class of `Base`, in 4.0.33, 5.0.8 and
6.0.0 too. The type checker admitted the access by the nest-mate rule that
static compilation relies on. Type-checked code is dispatched dynamically,
though, and the metaclass of a subclass does not list a private field of its
superclass, so the access could never succeed.
`StaticTypeCheckingVisitor.isFieldAccessible` now rejects such access when
the code is not statically compiled. The rule applies when the field is a
private instance field, the access goes through `super` or a subclass receiver,
and the current class is neither the declaring class nor an inner class whose
chain of enclosing instances leads to it. The error is the one the checker
already gives when `Base` and `Sub` are siblings nested in another class: "No
such property: z for class: Base$Sub". `@CompileStatic` still accesses the
field directly. A non-static inner subclass still compiles, since dynamic
lookup falls back to its enclosing instance. Attribute access (`.@z`) and
access from the declaring class are unchanged.
## Tests
`FieldsAndPropertiesSTCTest.testPrivateFieldOfSuperclassViaStaticNestedSubclass`
fails without the change.
`FieldsAndPropertiesSTCTest.testPrivateFieldOfSuperclassViaInnerSubclassOrDeclaringClass`
and the `FieldsAndPropertiesStaticCompileTest` override cover the shapes that
must keep compiling under type checking and static compilation. The bare `z`
forms are left out of the static compilation test until #3127 (GROOVY-12600)
fixes their VerifyError. `groovy.transform.stc.*`,
`org.codehaus.groovy.classgen.asm.sc.*`, `gls.*`,
`org.codehaus.groovy.transform.traitx.*`, `groovy.ThisAndSuperTest` and
`bugs.*` pass. The Checkstyle and CodeNarc gates pass.
> STC accepts access to a private superclass field through a nested subclass
> under @TypeChecked, which fails at run time
> ----------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12610
> URL: https://issues.apache.org/jira/browse/GROOVY-12610
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 4.0.33, 5.0.8, 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> class Base {
> private String z = 'x'
> @groovy.transform.TypeChecked
> static class Sub extends Base {
> def m() { this.z } // also: z, super.z, closures, lambdas, writes,
> that.z
> }
> }
> new Base.Sub().m()
> {code}
> Actual: the code compiles, then fails with MissingPropertyException: No such
> property: z for class: Base$Sub. Dynamic Groovy fails the same way.
> Expected: under @TypeChecked, a compile error "No such property: z for class:
> Base$Sub", as already reported when Base and Sub are both nested in another
> class. @CompileStatic keeps accepting the code, because it accesses the field
> directly from a nest-mate.
> Cause: the type checker uses the nest-mate accessibility rule of static
> compilation for @TypeChecked code too. Type-checked code is dispatched
> dynamically, and the metaclass of a subclass does not list a private field of
> its superclass.
> Seen in 4.0.33, 5.0.8 and 6.0.0.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)