You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2017/02/01 23:19:07 UTC

[jira] [Closed] (GROOVY-7655) Wrong method is chosen when using super with generics

     [ https://issues.apache.org/jira/browse/GROOVY-7655?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paul King closed GROOVY-7655.
-----------------------------

> Wrong method is chosen when using super with generics
> -----------------------------------------------------
>
>                 Key: GROOVY-7655
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7655
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.4.4
>            Reporter: Marius Vaitkus
>            Assignee: Jochen Theodorou
>             Fix For: 2.4.8, 2.5.0-beta-1
>
>         Attachments: generics_extension_test.groovy
>
>
> Given code:
> {code:title=generics_extension_test.groovy}
> interface ParamInterface{}
> class ParamImplementation implements ParamInterface{}
> class ParamExtension extends ParamImplementation {}
> class A<T extends ParamInterface> {
>     def getResult(T a) {
>         return "A"
>     }
> }
> class B<T extends ParamImplementation> extends A<T> {
>     def getResult(T b) {
>         return "B"
>     }
> }
> class C extends B<ParamExtension> {
>     @Override
>     def getResult(ParamExtension b) {
>         return super.getResult(b)
>     }
> }
> String result = new C().getResult(new ParamExtension())
> assert result == "B"
> {code}
> I get output:
> {code}
> Assertion failed: 
> assert result == "B"
>        |      |
>        A      false
> 	at generics_extension_test.run(generics_extension_test.groovy:31)
> {code}
> When calling super method, instead of looking for method in a class one hierarchy bellow, groovy goes through complex calculations for finding a better method. I debug'ed up to a point in 
> groovy.lang.MetaClassImpl#chooseMostSpecificParams
> where it turned out that distance for interface was 2 and distance for class that directly extends the method was much bigger, therefore the method from class A is chosen instead of method from class B. However, looking objectively, it would seem that B.getResult is a much better fit:
> C extends B and B extends A
> parameter hierarchy is shorter (ParamExtension -> ParamImplementation -> ParamInterface)



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)