Scott Murphy Heiberg created GROOVY-12518:
---------------------------------------------

             Summary: SC: a super property fails at runtime in a closure, and 
when incremented or compound-assigned
                 Key: GROOVY-12518
                 URL: https://issues.apache.org/jira/browse/GROOVY-12518
             Project: Groovy
          Issue Type: Bug
          Components: Static compilation
    Affects Versions: 6.0.0
            Reporter: Scott Murphy Heiberg


Under {{@CompileStatic}}, a property read or written through {{super}} fails at 
runtime in two cases: inside a closure or lambda, and as the target of {{++}}, 
{{--}} or a compound assignment such as {{+=}} when the subclass declares the 
same property.

{code:groovy}
class Base {
    int n = 1
    String name = 'base'
    String getP() { 'p:base' }
}
@groovy.transform.CompileStatic
class Sub extends Base {
    int n = 10
    String name = 'sub'
    String getP() { 'p:sub' }
    String getter() { def c = { -> super.p }; c() }
    String read() { def c = { -> super.name }; c() }
    String write() { def c = { -> super.name = 'w' }; c(); super.name }
    int inc() { super.n++ }
    int add() { super.n += 5 }
}
new Sub().getter() // VerifyError
new Sub().read()   // VerifyError
new Sub().write()  // VerifyError
new Sub().inc()    // MissingPropertyException: No such property: n for class: 
Sub
new Sub().add()    // MissingPropertyException: No such property: n for class: 
Sub
{code}

{code}
java.lang.VerifyError: Bad invokespecial instruction: current class isn't 
assignable to reference class.
{code}

In a closure the getter or setter of the superclass is called with 
{{invokespecial}} from the closure class, which the JVM rejects. A super method 
call in a closure, {{super.m()}}, already goes through a {{super$}} helper 
method of the enclosing class; property access does not. For {{++}} and {{--}} 
the property is read and written through 
{{ScriptBytecodeAdapter.getPropertyOnSuper}} and {{setPropertyOnSuper}}, and 
for a compound assignment it is read through {{getPropertyOnSuper}}; these 
dynamic calls fail with {{MissingPropertyException}} for a statically compiled 
class that declares the same property.

The same code without {{@CompileStatic}}, and with {{@TypeChecked}}, returns 
{{p:base}}, {{base}}, {{w}}, {{1}} and {{6}}. Seen in 4.0.33, 5.0.8, 6.0.0 and 
master. Related: GROOVY-7138 fixed {{super.m()}} in a closure with the 
{{super$}} helper methods.

Expected: under {{@CompileStatic}}, {{super.name}} reads and writes the 
superclass property in a closure or lambda, and {{super.n++}}, {{++super.n}} 
and {{super.n += 5}} update it, in the class and in a closure, as they do in 
dynamic Groovy.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to