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.
But in netbeans(7.3.1), the result of call hierarchy is OK:
Is it a bug of Eclipse? Thanks.
In the Java perspective, Call Hierarchy view shows callers and callees for the selected Java member. In the JavaScript perspective, Call Hierarchy view shows callers and callees for the selected JS member. Both Java and JavaScript perspectives (as well as their views) are the part of the Eclipse-based IDE.
Press Ctrl+Shift+H -or- from the Menu Bar go to Navigate | Open Type in Hierarchy. The "Open Type in Hierarchy" dialog is displayed.
To find the references of a method, eclipse has a plugin called Open Call Hierarchy(Ctrl+Alt+H).
Right click and select References > Project or References > Workspace from the pop-up menu. Show activity on this post. This will show you a Search view containing the hierarchy of class and method which using this method.
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With