codeconsole opened a new pull request, #3189:
URL: https://github.com/apache/groovy/pull/3189
Under `@CompileStatic`, an implicit-this call inside a lambda resolved to a
method of `groovy.lang.Closure` even when the enclosing class declares a method
of that name:
```groovy
@CompileStatic class C {
String getDelegate() { 'Cd' }
String memoizeAtMost(int i) { 'C' + i }
def m() {
Supplier<Object> s = () -> getDelegate()
Supplier<Object> t = () -> memoizeAtMost(2)
[s.get(), t.get()]
}
}
```
`new C().m()` returned the lambda's delegate and a memoized closure instead
of `[Cd, C2]`, as 4.0 did (5.0.8 and 6.0.0 are affected). With `curry`,
`rcurry` or `ncurry` declared in the class, it failed to compile as an
ambiguous reference to `Closure#curry`. Since GROOVY-11386,
`StaticTypeCheckingVisitor.visitMethodCallExpression` tries `Closure`'s methods
before the owner and the delegate, for lambdas as well as closures.
A lambda in statically compiled code follows Java semantics. The type
checker now skips the `Closure` lookup in such a lambda when the delegate, the
owner or the enclosing class has an applicable method (`isNativeLambda`,
`hasReceiverMethod`). `Closure`'s methods remain the fallback, so
`getThisObject()` still works in a lambda when the class does not declare it. A
lambda in dynamic or `@TypeChecked` code is compiled as a closure, and at run
time the closure's own methods come first, so the type checker keeps resolving
to them there. Closures are unchanged, including a closure inside a lambda.
Merges cleanly with #3183 (GROOVY-12662), which changes the line below the
one this adds a condition to. A 5.0.x or 6.0.x backport needs a replacement for
`isStaticDispatchScope()`, which is new in 7.0.0.
## Tests
`LambdaTest.testLambdaCallsEnclosingClassMethodNamedLikeClosureMethod`,
`testLambdaCallsEnclosingClassCurryMethod`,
`testLambdaCallsEnclosingClassStaticMethodNamedLikeClosureMethod` and
`testNestedLambdaAndClosureCallMethodNamedLikeClosureMethod` fail without the
change. `testLambdaCallsClosureMethodWithoutEnclosingClassMethod` and
`testDynamicLambdaCallsClosureMethodBeforeEnclosingClassMethod` cover the
`Closure` fallback and the dynamic and `@TypeChecked` behaviour.
`groovy.transform.stc.*`, `org.codehaus.groovy.classgen.asm.sc.*`,
`org.codehaus.groovy.transform.traitx.*`, `gls.*` and `groovy.bugs.*` 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]