[ 
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)

Reply via email to