Scott Murphy Heiberg created GROOVY-12666:
---------------------------------------------
Summary: Rehydrating a @CompileStatic packed closure ignores the
new this object and keeps calling the original owner
Key: GROOVY-12666
URL: https://issues.apache.org/jira/browse/GROOVY-12666
Project: Groovy
Issue Type: Bug
Affects Versions: 6.0.0, 7.0.0-alpha-1
Reporter: Scott Murphy Heiberg
{code:groovy}
import groovy.transform.CompileStatic
import groovy.transform.PackedClosures
class D {}
@CompileStatic
@PackedClosures
class O {
String name
String foo() { 'foo ' + name }
List run(O b) {
Closure c1 = { -> foo() }
Closure c2 = { -> name }
[c1.rehydrate(null, b, b)(), c2.rehydrate(null, b, b)(),
c1.rehydrate(new D(), new D(), new D())()]
}
}
println new O(name: 'a').run(new O(name: 'b'))
{code}
*Actual:* {{[foo a, a, foo a]}}. The same happens without the annotation when
compiling with {{-Dgroovy.target.closure.pack=true}}.
*Expected*, as with the closure class compiled without packing: {{[foo b, b]}},
then a ClassCastException from the third call, because D is not an O.
A @CompileStatic closure class runs its body against getThisObject(). A packed
closure dispatches its hoisted method to the receiver captured at construction,
and Closure.rehydrate only replaces the visible owner, delegate and this
object, so the new this object is silently ignored.
Verified on 6.0.0 and master.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)