[
https://issues.apache.org/jira/browse/GROOVY-12596?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135562#comment-18135562
]
ASF GitHub Bot commented on GROOVY-12596:
-----------------------------------------
codeconsole opened a new pull request, #3123:
URL: https://github.com/apache/groovy/pull/3123
In trait code, reading a static accessor of the trait with `this.` is
rejected by the type checker:
```groovy
@groovy.transform.TypeChecked // or @CompileStatic
trait T {
private static boolean flag = true
static boolean isReady() { flag }
boolean check() { this.ready }
}
class C implements T {}
assert new C().check()
```
```
[Static type checking] - static method of interface T can only be accessed
with class qualifier
```
Dynamic Groovy runs this, and `this.isReady()` compiles. 6.0.0 reports the
same error. The trait transform turns `this.ready` into `$self.ready` (or
`$static$self.ready` in a static method), whose receiver has the trait type, or
the type `Class` of a sub-trait. `checkInterfaceStaticCall` treated that
receiver as an instance (or the wrong class) qualifying a static interface
method. The implicit form `ready` hit the same check, but its error was dropped
because the generated expression has no source position.
`checkInterfaceStaticCall` now skips the check when the method is declared
by a trait and the receiver is the trait helper's `$self` or `$static$self`
parameter. A variable of trait type (`T t; t.ready`) is still rejected.
This PR is stacked on #3115 (GROOVY-12590). The type checking change does
not depend on it, but under `@CompileStatic` an accessor that reads trait state
is only called with the implementing class once #3115 is in, and the tests
check that.
## Tests
`TraitASTTransformationTest.testThisStaticAccessorOfTrait` and
`testThisStaticAccessorOfTrait2` fail without the change. They cover getters,
is-getters and setters through `this.`, closures, lambdas, static methods of a
sub-trait, and per-class trait state, in dynamic, `@TypeChecked` and
`@CompileStatic` mode. `testStaticAccessorOfTraitThroughInstance` checks that
access through another instance is still an error. `groovy.transform.stc.*`,
`org.codehaus.groovy.classgen.asm.sc.*`,
`org.codehaus.groovy.transform.traitx.*`, `bugs.*`, `groovy.bugs.*`, `gls.*`
and `groovy.ThisAndSuperTest` pass. The Checkstyle and CodeNarc gates pass.
> STC rejects "this.name" for a static accessor of a trait in trait code
> ("static method of interface T can only be accessed with class qualifier")
> -------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12596
> URL: https://issues.apache.org/jira/browse/GROOVY-12596
> 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 {
> private static boolean flag = true
> static boolean isReady() { flag }
> boolean check() { this.ready }
> }
> class C implements T {}
> assert new C().check()
> {code}
> Actual:
> {noformat}
> [Static type checking] - static method of interface T can only be accessed
> with class qualifier
> {noformat}
> Expected: the script compiles and {{check()}} returns true, as it does in
> dynamic Groovy and with the method form {{this.isReady()}}.
> The same error is reported for a getX accessor ({{this.name}} for {{static
> String getName()}}), inside a closure or lambda, and for {{this.cnt}} in a
> static method of a sub-trait when the accessor is declared by the super
> trait. Trait code compiles {{this.ready}} to a property read on the trait
> helper's self parameter, which has the trait type. The check for static
> interface members then treats it as an instance-qualified access to a static
> interface method, although in trait code {{this}} stands for the implementing
> class, which has the accessor.
> 6.0.0 reports the same error. 4.0.33 and 5.0.8 reject the code with "No such
> property: ready for class: T".
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)