Paul King created GROOVY-12567:
----------------------------------

             Summary: Dynamic super from an instance method cannot reach a 
static method of the superclass that the subclass hides
                 Key: GROOVY-12567
                 URL: https://issues.apache.org/jira/browse/GROOVY-12567
             Project: Groovy
          Issue Type: Bug
            Reporter: Paul King


When a subclass declares a static method with the same signature as a static 
method of its superclass (hiding it), {{super.m()}} in an instance method of 
the subclass fails in dynamic Groovy and under {{@TypeChecked}}. Under 
{{@CompileStatic}} it calls the superclass's method, as Java does. The same 
call works from a static method of the subclass, and when the subclass doesn't 
hide the method.

{code:groovy}
class B {
    static m() { 'B.m' }
}
class D extends B {
    static m() { 'D.m' }
    def test() { super.m() }
}
assert new D().test() == 'B.m'
// dynamic and @TypeChecked:
// MissingMethodException: No signature of method: m for class: B is applicable 
for argument types: () values: []
{code}

This affects property access through static accessors too:

||{{D}} hides, {{test()}} does||dynamic and 
{{@TypeChecked}}||{{@CompileStatic}}||
|{{super.m()}}|MissingMethodException|{{B.m}}|
|{{super.m('a')}}|MissingMethodException|{{B.m}}|
|{{super.p}} (static {{getP()}})|MissingPropertyException: No such property: p 
for class: D|{{B.p}}|
|{{super.p = 'a'}} (static {{setP(String)}})|MissingPropertyException: Cannot 
get write-only property: p for class: D|calls {{B.setP}}|

The last row's message talks about getting a property during a write; 4.0.33 
reported "No such property: p for class: D" there.

The same calls work in dynamic Groovy when the subclass doesn't hide the 
method, or when {{test()}} is static.

When the superclass overloads the hidden method, the call doesn't fail; it 
reaches the wrong overload:

{code:groovy}
class Base {
    static List log = []
    static void setX(int i) { log << 'int:' + i }
    static void setX(String s) { log << 'str:' + s }
}
class D extends Base {
    static void setX(String s) { }
    def test() { super.x = 'a'; log }
}
assert new D().test() == ['str:a']
// dynamic and @TypeChecked: [int:97]  ('a' coerced to a char, then to int)
// with super.x = 'ab': GroovyCastException: Cannot cast object 'ab' with class 
'java.lang.String' to class 'int'
// super.setX('a'): MissingMethodException (4.0.33: NullPointerException)
{code}

*Expected:* from an instance method, {{super.m()}}, {{super.p}} and {{super.p = 
v}} call the superclass's static method, as they do from a static method and 
under {{@CompileStatic}}, and as {{super.m()}} does in Java.



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

Reply via email to