[ 
https://issues.apache.org/jira/browse/GROOVY-12590?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135474#comment-18135474
 ] 

ASF GitHub Bot commented on GROOVY-12590:
-----------------------------------------

codeconsole opened a new pull request, #3115:
URL: https://github.com/apache/groovy/pull/3115

   Under `@CompileStatic`, trait code that uses property syntax for a static 
accessor of the trait calls the trait interface's static forwarder, which 
passes the trait itself to the trait helper as the receiver class, so an 
accessor that reads trait state fails:
   
   ```groovy
   @groovy.transform.CompileStatic
   trait T {
       static boolean flag = true
       static boolean isReady() { flag }
       static String sm() { ready ? 'yes' : 'no' }
   }
   class C implements T {}
   assert C.sm() == 'yes' // MissingMethodException: No signature of static 
method: T__flag$get for class: T
   ```
   
   `@TypeChecked` and dynamic Groovy work, and so does the direct call 
`isReady()`, which the trait transformation turns into 
`T$Trait$Helper.isReady($static$self)`. The same failure occurs in instance 
trait methods, in closures and lambdas, for a static setter written as an 
assignment, a compound assignment or `++`/`--`, and for accessors of a super 
trait.
   
   `StaticInvocationWriter` now writes a call to a static method of a trait 
whose receiver is the trait helper's `$static$self` or `$self` parameter as a 
call to the trait helper, passing `$static$self` or `$self.getClass()` as the 
receiver class, as the method call form does. `StaticTypesCallSiteWriter` keeps 
`$static$self` as the receiver of a static getter instead of replacing it with 
the trait class, which the getter half of `cnt++` goes through. An explicit 
`T.isReady()` is not changed.
   
   ## Tests
   
   `TraitASTTransformationTest.testTraitStaticAccessorReadAsProperty`, 
`testTraitStaticAccessorWrittenAsProperty` and 
`testSuperTraitStaticAccessorAsProperty` run dynamic, `@TypeChecked` and 
`@CompileStatic`; the `@CompileStatic` variant of each fails without the 
change. 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.
   
   Seen in 6.0.0; 5.0.8 and 4.0.33 reject the code at compile time.
   




> SC calls a trait's static accessor read as a property on the trait instead of 
> the implementing class
> ----------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12590
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12590
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 6.0.0
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> {code:groovy}
> @groovy.transform.CompileStatic
> trait T {
>     static boolean flag = true
>     static boolean isReady() { flag }
>     static String sm() { ready ? 'yes' : 'no' }
>     static Closure getG() { { -> flag } }
>     static Object sg() { g.call() }
> }
> class C implements T {}
> assert C.sm() == 'yes'
> assert C.sg() == true
> {code}
> Actual: groovy.lang.MissingMethodException: No signature of static method: 
> T__flag$get for class: T is applicable for argument types: () values: []
> Expected: both assertions pass, as they do with @TypeChecked or without an 
> annotation, and as they do when the accessor is called directly 
> ({{isReady()}}, {{getG()}}).
> The same happens in instance trait methods, in closures and lambdas, and when 
> a static accessor is written with property syntax ({{cnt = 1}}, {{cnt += 1}}, 
> {{cnt++}} for a static {{setCnt(int)}}), including for an accessor of a super 
> trait. Under static compilation the property resolves to the static method 
> that the trait interface declares, which forwards to the trait helper with 
> the trait itself as the receiver class, so the accessor cannot reach the 
> implementing class's trait state. The direct method call passes the 
> implementing class to the helper instead.
> Seen in 6.0.0 and master. 5.0.8 rejects the code with "No such property: 
> ready for Class or static property for class: T", and 4.0.33 with "Access to 
> T#ready is forbidden".



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to