Eclipse - `open call hierarchy` got wrong result
Asked Answered
E

2

18

Here is my sample java code:

public class Test {
    public static void foo() {
        Foo.InnerKey key = new Foo.InnerKey();
        getInstance().query(key);
    }

    public static void bar() {
        Bar.InnerKey key = new Bar.InnerKey();
        getInstance().query(key);
    }

    public static MyIF getInstance(){
        // TODO code to get instance
        return null;
    }

}


interface MyIF {
    public void query(Foo.InnerKey key); // Method to open call hierarchy
    public void query(Bar.InnerKey key);
}


class Foo {
    static class InnerKey  {}
}

class Bar {
    static class InnerKey {}
}

When I open call hierarchy of method query(Foo.InnerKey key) from Eclipse(kepler), I got both foo & bar methods, which bar is not expected.

enter image description here

But in netbeans(7.3.1), the result of call hierarchy is OK:

enter image description here

Is it a bug of Eclipse? Thanks.

Epididymis answered 11/3, 2014 at 6:17 Comment(9)
Eclipse might have a bug?! could've fooled me...Sipe
@KepaniHaole I've tested eclipse 3.5 & 4.3, the same result. No one reported this bug before?Epididymis
i was mainly being sarcastic -- it's totally possible that this is an existing bug that nobody has noticed / reportedSipe
Might be since InnerKey is a static variable?Alita
@Alita But, there is no problem in netbeans...Epididymis
Reproduced it - definitely looks like a bug. It's generating the right code though - if you add an implementation, it calls the right methods. I suggest you report the bug.Amphistylar
@Epididymis Did you already report this bug? Otherwise I'll report it together with the Javadoc bug.Tenfold
@Tenfold I just reported it bugs.eclipse.org/bugs/show_bug.cgi?id=431357 But just simply link to StackOverflow. I think you are the best man to report this bug.(I don't familiar with eclipse core development)Epididymis
Hi, there is a patch for this bug. Thanks for eclipse.org bugs.eclipse.org/bugs/attachment.cgi?id=245177&action=editEpididymis
T
10

This is definitely a JDT bug that should be reported. And the bug is not directly related to the call hierarchy, but instead to the org.eclipse.jdt.core search API, when searching for method references, where the parameter is a member type of another type (as e.g. Foo.InnerKey). Therefore this bug manifests itself for every JDT functionality, that relies on finding method references by using the JDT search engine. For example you will also get wrong results when showing the references to MyIF#query(Foo.InnerKey) or when using the Java search, to search for the methodMyIF#query(Foo.InnerKey). In these cases the search engine will not only return references to MyIF#query(Foo.InnerKey), as would be expected, but also to MyIF#query(Bar.InnerKey).

The relevant code, where this bug occurs, is in org.eclipse.jdt.internal.core.search.matching.MethodLocator#matchMethod(MethodBinding, boolean). And it seems, that the bug was introduced by fixing JDT Bug 41018.

Here is a snippet of the relevant code in the class MethodLocator:

protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
    [...]
    // verify each parameter
    for (int i = 0; i < parameterCount; i++) {
        TypeBinding argType = method.parameters[i];
        int newLevel = IMPOSSIBLE_MATCH;
        if (argType.isMemberType()) {
            // only compare source name for member type (bug 41018)
            newLevel = CharOperation.match(this.pattern.parameterSimpleNames[i], argType.sourceName(), this.isCaseSensitive)
                ? ACCURATE_MATCH
                : IMPOSSIBLE_MATCH;
        } else {
            // TODO (frederic) use this call to refine accuracy on parameter types
            // newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType);
            newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], argType);
            [...]
        }
    }
    [...]
}

The problem here is the if (argType.isMemberType()) statement, that was introduced to fix Bug 41018. The comment also states that for member types only the source name gets compared. If this if-statement is removed, the bug goes away and the call hierarchy shows the correct references (but I guess this would of course re-introduce bug 41018 - I didn't test this).

Edit

On a side note, there also seems to be a bug when displaying the source codes Javadoc for MyIF#query(Bar.InnerKey) - both when using the Javadoc-Hover over the method or when showing the method in the Javadoc view.

public interface MyIF {
    /**
     * Javadoc for: query(Foo.InnerKey key)
     */
    public void query(Foo.InnerKey key); // Method to open call hierarchy
    /**
     * Javadoc for: query(Bar.InnerKey key)
     */
    public void query(Bar.InnerKey key);
}

When hovering over a query method reference in the Test class (e.g. getInstance().query(key)), both methods are found and one is able to select one (without the ability to differentiate between the two).

When opening the Javadoc view and selecting any of the query method references in the Test class, the Javadoc view always displays only the Javadoc of the first found method in the source class (i.e. MyIF#query(Foo.InnerKey)).

This doesn't seem to be directly related to the bug described above, and it will also not be resolved, when removing the if-statement mentioned above...

Tenfold answered 21/3, 2014 at 8:17 Comment(2)
Thank you very much. After remove the if (argType.isMemberType()) statement, both call hierarchy & search result are OK! But i can't reproduce the Bug 41018 in my eclipse 3.5 (maybe something goes wrong).Epididymis
@Epididymis I just had a look at it and Bug 41018 is really re-introduced when the if (argType.isMemberType()) statement is removed. To reproduce it, check out the second "simplified snippet" from Knut, and open the references of "methodA". No references will be found although the method is clearly referenced in the same class. I recommend reporting this as a new bug and linking it to Bug 41018 and also to this Stack Overflow question, so the jdt developers can have a look at it. Btw: nice find, andy!Tenfold
B
1

I think it may be the same issue as this existing bug (although your example is simpler, IMO). I suggest you add a comment and your example to that bug report.

Also, could be related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836 which is suspected as a culprit for another, https://bugs.eclipse.org/bugs/show_bug.cgi?id=394475

Boliviano answered 20/3, 2014 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.