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

   An explicit `this.m()` inside a closure or lambda in a trait method does not 
reach the implementing instance:
   
   ```groovy
   @groovy.transform.CompileStatic
   trait T {
       String getName() { 'T' }
       String m() { Closure<String> c = { -> this.getName() }; c() }
   }
   class C implements T { String getName() { 'C' } }
   assert new C().m() == 'C'
   ```
   
   Under static compilation this throws `ClassCastException: class 
java.lang.Class cannot be cast to class T$Trait$Helper`; lambdas fail the same 
way. Dynamic Groovy and `@TypeChecked` call the helper's static `getName` with 
a null self and return `'T'`. With arguments they throw 
`MissingMethodException`, and for a super-trait method 
`NoSuchElementException`. 4.0.33, 5.0.8 and 6.0.0 behave the same.
   
   `TraitReceiverTransformer.transformMethodCallOnThis` kept the original 
`this` receiver for every call inside a closure. That is needed for an implicit 
`m()`, which must go through the closure's owner and delegate. An explicit 
`this.m()` never goes through the delegate, in a trait or a plain class. It now 
gets `$self` (or `$static$self`) as its receiver, as the call outside a closure 
and a bare `this` inside a closure already do.
   
   In a static trait method, `this.getSimpleName()` inside a closure now uses 
the implementing class, not `T$Trait$Helper`, matching the same call outside 
the closure. This composes with #3129 (GROOVY-12602), which fixes implicit-this 
calls in lambdas.
   
   ## Tests
   
   The new `testInvokeTraitMethodOnExplicitThisFromTraitClosure`, 
`testInvokeTraitMethodOnExplicitThisFromTraitLambda`, 
`testInvokeMethodOnExplicitThisFromStaticTraitMethodClosure` and 
`testInvokeTraitMethodOnExplicitThisFromTraitClosureOrLambda` in 
`TraitWithClosureOrLambda` fail without the change. Together they cover own and 
super-trait methods, arguments, private and static methods, nested closures, 
`with`, safe calls, a DELEGATE_FIRST closure, native lambdas and lambdas typed 
Closure, in dynamic, `@TypeChecked` and `@CompileStatic` modes. 
`org.codehaus.groovy.transform.traitx.*`, `groovy.transform.stc.*`, 
`org.codehaus.groovy.classgen.asm.sc.*`, `groovy.ThisAndSuperTest`, 
`gls.closures.*` and `TraitsSpecificationTest` 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