[
https://issues.apache.org/jira/browse/GROOVY-12609?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135621#comment-18135621
]
ASF GitHub Bot commented on GROOVY-12609:
-----------------------------------------
codeconsole opened a new pull request, #3136:
URL: https://github.com/apache/groovy/pull/3136
A sub-trait refers to a public field of a super trait by its remapped name
(`T__name`, see GROOVY-11641 and GROOVY-11663). Under `@TypeChecked` and
`@CompileStatic` that worked only for a static field outside of closures:
```groovy
@groovy.transform.TypeChecked
trait T {
public static String shared = 'x'
public String f = 'i'
}
@groovy.transform.TypeChecked
trait U extends T {
static m() { def c = { T__shared }; c() } // The variable [T__shared] is
undeclared.
def n() { T__f } // No such property: T__f for
class: U
}
class C implements U {}
```
Dynamic Groovy runs both. 5.0.8 and 6.0.0 fail the same way.
`TraitReceiverTransformer` turns a dynamic variable of trait code into a
property of the trait receiver, but not inside a closure (GROOVY-8049,
GROOVY-9386). It now does so in a closure too when the name is the remapped
name of a field of a super trait. The check follows a super trait's `extends`
clause when that trait is not transformed yet.
`TraitTypeCheckingExtension.handleUnresolvedProperty` now resolves the
remapped name of an instance field of a super trait through the field helper
getter, as it already did for static fields through the static field helper. It
does this only on the instance receiver, so an instance field used in a static
method is still an error. The type is corrected through the type arguments of
the super trait.
## Tests
`TraitASTTransformationTest.testTraitAccessToInheritedStaticFieldInClosure`,
`testTraitAccessToInheritedInstanceField`,
`testTraitAccessToIndirectlyInheritedFields` and
`testTraitAccessToPrecompiledInheritedFields` run dynamic, `@TypeChecked` and
`@CompileStatic`; their `@TypeChecked` and `@CompileStatic` variants fail
without the change. `testTraitAccessToInheritedInstanceFieldInStaticContext`
checks that an instance field is still rejected in a static method. The
`groovy.transform.stc`, `org.codehaus.groovy.classgen.asm.sc`,
`org.codehaus.groovy.transform.traitx` and `gls` packages and
`groovy.ThisAndSuperTest` pass. The Checkstyle and CodeNarc gates pass.
> STC rejects the remapped name of a super trait field in a closure or for an
> instance field ("The variable [T__x] is undeclared" / "No such property:
> T__x")
> -----------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12609
> URL: https://issues.apache.org/jira/browse/GROOVY-12609
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 4.0.33, 5.0.8, 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> @groovy.transform.TypeChecked // or @CompileStatic
> trait T {
> public static String shared = 'x'
> public String f = 'i'
> }
> @groovy.transform.TypeChecked
> trait U extends T {
> static m() { def c = { T__shared }; c() }
> def n() { T__f }
> }
> class C implements U {}
> assert C.m() == 'x'
> assert new C().n() == 'i'
> {code}
> Actual: compilation fails with "[Static type checking] - The variable
> [T__shared] is undeclared." and "[Static type checking] - No such property:
> T__f for class: U". The same happens for writes, lambdas, an instance field
> in a closure, and a precompiled super trait.
> Expected: both compile and return x and i, as they do in dynamic Groovy. The
> remapped name is the documented way to use a super trait's field
> (GROOVY-11641, GROOVY-11663).
> The trait transformation leaves a dynamic variable in a closure as it is, so
> the GROOVY-11663 handling of the remapped name on the trait receiver never
> sees it. That handling also only looks for static field getters.
> Seen in 5.0.8 and 6.0.0; 4.0.33 reports the closure case the same way.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)