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

   Under `@CompileStatic`, a closure or lambda in trait code that reads a super 
trait's static accessor or static property as a property calls the super trait 
interface's static forwarder. The forwarder 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 { private static int count = 1; static int getCnt() { count } }
   @groovy.transform.CompileStatic
   trait U extends T { String m() { def c = { -> cnt }; c() } }
   class C implements U {}
   assert new C().m() == '1' // MissingMethodException: No signature of static 
method: T__count$get for class: T
   ```
   
   Writing the property in a closure (`cnt = n`, `cnt++`, `s = 'y'`) is 
rejected under `@TypeChecked` and `@CompileStatic` with "Cannot set read-only 
property". Dynamic Groovy and the method form `getCnt()` work.
   
   A name like this inside a closure is left unchanged by the trait 
transformation (GROOVY-8049, GROOVY-9386), so that the closure's delegate can 
still provide it. That is kept.
   - **Closures:** when the type checker resolves the name to a static method 
of a trait through the closure's owner, `StaticInvocationWriter` now calls the 
trait helper (the GROOVY-12590 path). It passes the class of the closure's 
`thisObject`, which the trait transformation sets to `$self`, or `$static$self` 
in a static trait method.
   - **Lambdas:** a lambda has no delegate or `thisObject`, so 
`TraitReceiverTransformer` rewrites the name to `$self.name` or 
`$static$self.name` there, as for a property of the trait itself, and the 
lambda captures it.
   - **Setters:** in trait code, `StaticTypeCheckingVisitor` now also finds the 
static setters of a super trait, since a static interface method is not 
inherited by the receiver type.
   
   `p.with { cnt }` still reads `p.cnt` when `p` has the property. This PR is 
stacked on #3115 (GROOVY-12590).
   
   ## Tests
   
   `TraitASTTransformationTest.testSuperTraitStaticAccessorAsPropertyInClosure` 
runs dynamic, `@TypeChecked` and `@CompileStatic`. It covers getters, an isser, 
setters, `++`, `+=`, nested closures, static and instance methods, a 
grand-super trait, static properties, lambdas, per-class state and 
delegate-first resolution. The `@TypeChecked` and `@CompileStatic` variants 
fail without the change, and each of the three main-code changes is needed for 
them to pass. The `groovy.transform.stc`, 
`org.codehaus.groovy.classgen.asm.sc`, `org.codehaus.groovy.transform.traitx`, 
`gls`, `groovy.bugs` and `bugs` packages and `groovy.ThisAndSuperTest` pass. 
The Checkstyle and CodeNarc gates pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to