codeconsole opened a new pull request, #3090:
URL: https://github.com/apache/groovy/pull/3090
Under `@CompileStatic`, a closure assigned to a subscript or a property
whose type is a functional interface was stored unconverted when the method
that stores it declares its parameter with a type parameter: `putAt` of a
`Map<String, Function<String, String>>` or a `List<Supplier<String>>`, or the
setter or field of a `Holder<T>` property for a `Holder<Supplier<String>>`.
```groovy
@CompileStatic
Map<String, Function<String, String>> make() {
Map<String, Function<String, String>> map = [:]
map['shout'] = { String s -> s + '!' }
map
}
make().shout.apply('hi') // MissingMethodException: the map held the closure
```
`map?['k'] = { ... }`, `map.k = { ... }`, `holder.value = { ... }`,
`box.@field = { ... }` and the named constructor argument `new
Holder<Supplier<String>>(value: { ... })` all stored the closure itself. An
assignment to a variable converts it, since the writer casts the value to the
variable's type.
The static compilation transformer now casts a closure value assigned to a
subscript or property of a functional interface type to that type, before the
assignment becomes a `putAt` or setter call. For a named constructor argument,
the type checker records the property's type, which the map-style constructor
call passes on to the assignment it makes. The value of the assignment is the
converted closure, as stored.
## Tests
`ClosuresStaticCompileTest.testClosureAssignedToASubscriptOrPropertyIsConvertedToItsInterface`
fails without the change. 11,625 tests in the `groovy`, `gls`, `bugs` and
STC/SC packages pass, and the Checkstyle and CodeNarc gates pass.
Seen in 4.0.33, 5.0.8 and 6.0.0.
--
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]