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]