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

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

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

   In a trait instance method, `TraitReceiverTransformer` rewrites a closure's 
call to a static or private trait method as `T$Trait$Helper.m($self or (Class) 
$self.getClass(), x)`. Both synthesized calls kept the default implicit-this 
flag, so static compilation resolved them against the closure's delegate:
   
   ```groovy
   @groovy.transform.CompileStatic
   trait V {
       static String who() { this.simpleName }
       def m() { new Object().with { who() } }
   }
   class E implements V {}
   assert new E().m() == 'E' // was 'Object': getDelegate().getClass()
   ```
   
   ```groovy
   class Dg { String who(Class c) { 'delegate' } }
   @groovy.transform.CompileStatic
   trait T {
       static String who() { this.simpleName }
       def m() { new Dg().with { who() } }
   }
   class C implements T {}
   assert new C().m() == 'C' // was 'delegate': Dg.who(Class) got the added 
self argument
   ```
   
   Dynamic Groovy and `@TypeChecked` return `'E'` and `'C'`.
   
   `TraitReceiverTransformer` now builds `$self.getClass()` in one place, 
`selfGetClass()`, as an explicit call on `$self`, as static field access 
already did. In a closure, the rewritten call on the trait helper is also 
explicit. Whether a delegate method of the same signature should win over a 
private or static trait method is #3138 (GROOVY-12611); the tests here use a 
delegate without such a method, so they hold either way.
   
   ## Tests
   
   These `TraitWithClosureOrLambda` tests fail without the change: 
`testInvokeTraitStaticMethodFromDelegateClosureInInstanceMethod`, 
`testInvokeSuperTraitStaticMethodFromDelegateClosureInInstanceMethod` and 
`testInvokeTraitMethodFromDelegateClosureNotOnDelegateWithSelfParameter`. They 
cover dynamic, `@TypeChecked` and `@CompileStatic` code, explicit and implicit 
`this`, a lambda, a `@Virtual` static, a super-trait static, a private method 
and two implementing classes. 
`testReadTraitStaticFieldFromDelegateClosureInInstanceMethod` covers static 
field and property access from a delegate closure. The 
`org.codehaus.groovy.transform.traitx`, `groovy.transform.stc` and 
`org.codehaus.groovy.classgen.asm.sc` tests, `groovy.ThisAndSuperTest`, and the 
`*Trait*` and `bugs` tests pass. The Checkstyle and CodeNarc gates pass.
   




> SC resolves calls that the trait transformation adds in a closure against the 
> closure's delegate
> ------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12624
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12624
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 6.0.0
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> {code:groovy}
> @groovy.transform.CompileStatic
> trait V {
>     static String who() { this.simpleName }
>     def m() { new Object().with { who() } }
> }
> class E implements V {}
> assert new E().m() == 'E'
> class Dg {
>     String who(Class c) { 'delegate' }
> }
> @groovy.transform.CompileStatic
> trait T {
>     static String who() { this.simpleName }
>     def m() { new Dg().with { who() } }
> }
> class C implements T {}
> assert new C().m() == 'C'
> {code}
> Actual: under static compilation the first m() returns 'Object' (the 
> delegate's class), also when who is declared in a super trait or called as 
> this.who(). The second m() returns 'delegate': it calls Dg.who(Class) with 
> the self argument that the trait transformation added.
> Expected: 'E' and 'C', as dynamic Groovy and @TypeChecked return.
> Cause: TraitReceiverTransformer rewrites the call to a trait helper call with 
> the receiver class as first argument. Both the outer helper call and the 
> inner getClass() call keep the default implicit-this flag, so the static 
> compiler resolves them against the closure's delegate.
> Seen on master; 5.0.8 and 6.0.0 reported the same.



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

Reply via email to