correct sibling filtering for inherited methods in call hierarchy (IDEADEV-41005)

This commit is contained in:
Dmitry Jemerov
2009-12-03 19:13:27 +03:00
parent 0434983f0f
commit 2a26d606e0
26 changed files with 173 additions and 4 deletions
@@ -176,6 +176,10 @@ public final class CallHierarchyNodeDescriptor extends HierarchyNodeDescriptor i
myReferences.add(reference);
}
public boolean hasReference(PsiReference reference) {
return myReferences.contains(reference);
}
public void navigate(boolean requestFocus) {
if (!myNavigateToReference) {
if (myElement instanceof Navigatable && ((Navigatable)myElement).canNavigate()) {
@@ -73,9 +73,15 @@ public final class CallerMethodsTreeStructure extends HierarchyTreeStructure {
}
if (qualifier != null && !methodToFind.hasModifierProperty(PsiModifier.STATIC)) {
final PsiType qualifierType = qualifier.getType();
if (qualifierType == null) return true;
if (!TypeConversionUtil.isAssignable(qualifierType, originalType)) {
return true;
if (qualifierType instanceof PsiClassType && !TypeConversionUtil.isAssignable(qualifierType, originalType) && methodToFind != method) {
final PsiClass psiClass = ((PsiClassType)qualifierType).resolve();
if (psiClass != null) {
final PsiMethod callee = psiClass.findMethodBySignature(methodToFind, true);
if (callee != null && !methodsToFind.contains(callee)) {
// skip sibling methods
return true;
}
}
}
}
}
@@ -109,7 +115,7 @@ public final class CallerMethodsTreeStructure extends HierarchyTreeStructure {
d = new CallHierarchyNodeDescriptor(myProject, descriptor, element, false, true);
methodToDescriptorMap.put(key, d);
}
else {
else if (!d.hasReference(reference)) {
d.incrementUsageCount();
}
d.addReference(reference);
@@ -0,0 +1,6 @@
class A {
public static void main(String[] args) {
D d = new D();
d.xyzzy();
}
}
@@ -0,0 +1,4 @@
class B {
public void xyzzy() {
}
}
@@ -0,0 +1,2 @@
class D extends B {
}
@@ -0,0 +1,4 @@
<node text="B.xyzzy() ()" base="true">
<node text="A.main(String[]) ()">
</node>
</node>
@@ -0,0 +1,9 @@
class A {
public static void main(String[] args) {
D d = new D();
d.xyzzy();
C c = new C();
c.xyzzy();
}
}
@@ -0,0 +1,4 @@
class B {
public void xyzzy() {
}
}
@@ -0,0 +1,2 @@
class C extends B {
}
@@ -0,0 +1,4 @@
class D extends B {
public void xyzzy() {
}
}
@@ -0,0 +1,4 @@
<node text="D.xyzzy() ()" base="true">
<node text="A.main(String[])(2 usages) ()">
</node>
</node>
@@ -0,0 +1,9 @@
class A {
public static void main(String[] args) {
D d = new D();
d.xyzzy();
C c = new C();
c.xyzzy();
}
}
@@ -0,0 +1,4 @@
class B {
public void xyzzy() {
}
}
@@ -0,0 +1,4 @@
class C extends B {
public void xyzzy() {
}
}
@@ -0,0 +1,4 @@
class D extends B {
public void xyzzy() {
}
}
@@ -0,0 +1,4 @@
<node text="D.xyzzy() ()" base="true">
<node text="A.main(String[]) ()">
</node>
</node>
@@ -0,0 +1,9 @@
class A {
public static void main(String[] args) {
D d = new D();
d.xyzzy();
CChild c = new CChild();
c.xyzzy();
}
}
@@ -0,0 +1,4 @@
class B {
public void xyzzy() {
}
}
@@ -0,0 +1,4 @@
class C extends B {
public void xyzzy() {
}
}
@@ -0,0 +1,2 @@
class CChild extends C {
}
@@ -0,0 +1,4 @@
class D extends B {
public void xyzzy() {
}
}
@@ -0,0 +1,4 @@
<node text="D.xyzzy() ()" base="true">
<node text="A.main(String[]) ()">
</node>
</node>
@@ -0,0 +1,4 @@
class A {
public static void main() {
}
}
@@ -0,0 +1,5 @@
class B {
public void xyzzy() {
A.main();
}
}
@@ -0,0 +1,4 @@
<node text="A.main() ()" base="true">
<node text="B.xyzzy() ()">
</node>
</node>
@@ -0,0 +1,55 @@
package com.intellij.ide.hierarchy;
import com.intellij.JavaTestUtil;
import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.ProjectScope;
import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestBase;
/**
* @author yole
*/
public class JavaCallHierarchyTest extends HierarchyViewTestBase {
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath();
}
@Override
protected String getBasePath() {
return "ide/hierarchy/call/" + getTestName(false);
}
private void doJavaCallTypeHierarchyTest(final String classFqn, final String methodName, final String... fileNames) throws Exception {
doHierarchyTest(new Computable<HierarchyTreeStructure>() {
public HierarchyTreeStructure compute() {
final PsiClass psiClass = JavaPsiFacade.getInstance(getProject()).findClass(classFqn, ProjectScope.getProjectScope(getProject()));
final PsiMethod method = psiClass.findMethodsByName(methodName, false) [0];
return new CallerMethodsTreeStructure(getProject(), method, HierarchyBrowserBaseEx.SCOPE_PROJECT);
}
}, fileNames);
}
public void testIdeaDev41005() throws Exception {
doJavaCallTypeHierarchyTest("B", "xyzzy", "B.java", "D.java", "A.java");
}
public void testIdeaDev41005_Inheritance() throws Exception {
doJavaCallTypeHierarchyTest("D", "xyzzy", "B.java", "D.java", "A.java", "C.java");
}
public void testIdeaDev41005_Sibling() throws Exception {
doJavaCallTypeHierarchyTest("D", "xyzzy", "B.java", "D.java", "A.java", "C.java");
}
public void testIdeaDev41005_SiblingUnderInheritance() throws Exception {
doJavaCallTypeHierarchyTest("D", "xyzzy", "B.java", "D.java", "A.java", "C.java", "CChild.java");
}
public void testIdeaDev41232() throws Exception {
doJavaCallTypeHierarchyTest("A", "main", "B.java", "A.java");
}
}