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

   Under `@CompileStatic`, `owner` and `delegate` (and `getOwner()` and 
`getDelegate()`) inside a lambda nested in a closure or another lambda were 
typed as `Closure`:
   
   ```groovy
   @CompileStatic
   class C {
       String name = 'n'
       def q() {
           Supplier<Supplier<Object>> s = () -> { name; (Supplier<Object>) (() 
-> { name; owner.maximumNumberOfParameters }) }
           s.get().get() // GroovyCastException: Cannot cast object 'C@…' with 
class 'C' to class 'groovy.lang.Closure'
       }
       def t() {
           def c = { -> Supplier<String> s = () -> { name; owner.name }; 
s.get() }
           c() // No such property: name for class: groovy.lang.Closure
       }
   }
   ```
   
   Seen in 4.0.33, 5.0.8 and 6.0.0 too.
   
   A native lambda is constructed with the enclosing `this` as its owner 
(`ClosureWriter.loadThis` reads `getThisObject()` inside a generated function), 
so its owner is the enclosing instance at any depth. The type checker 
(`StaticTypeCheckingVisitor.hasClosureOwner`) now types `owner` and `delegate` 
in such a lambda as the enclosing class, as it already did for a top-level 
lambda. A lambda counts as native when it is statically compiled and its target 
type is a functional interface, the same rule 
`StaticTypesLambdaWriter.writeLambda` uses. Closures and lambdas compiled as 
closures (type-checked code, or no functional-interface target) still get 
`Closure`, since their owner is the enclosing closure or lambda.
   
   With #3193 (GROOVY-12672) also merged, a nested lambda that reads `owner` 
but no instance member works at run time too (without it, such a lambda gets a 
static `doCall`). The two merge cleanly, and cleanly with #3189 (GROOVY-12668).
   
   ## Tests
   
   `LambdaTest.testNestedLambdaOwnerDelegateThisObject` and 
`ClosuresStaticCompileTest.testNestedLambdaDelegateOwner` fail without the 
change. `LambdaTest.testClosureOwnerInNestedFunction` and 
`ClosuresSTCTest.testNestedLambdaDelegateOwner` check that closures, lambdas 
compiled as closures and type-checked lambdas keep the `Closure` owner. 
`groovy.transform.stc.*` and `org.codehaus.groovy.classgen.asm.sc.*` 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