mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Consider polymorphic method calls in call hierarchy, bug 156689.
This commit is contained in:
parent
0d7a561440
commit
0ce745690b
4 changed files with 271 additions and 18 deletions
|
@ -16,6 +16,7 @@ import junit.framework.Test;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.swt.widgets.Tree;
|
import org.eclipse.swt.widgets.Tree;
|
||||||
import org.eclipse.swt.widgets.TreeItem;
|
import org.eclipse.swt.widgets.TreeItem;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
import org.eclipse.ui.IPageLayout;
|
import org.eclipse.ui.IPageLayout;
|
||||||
import org.eclipse.ui.IViewPart;
|
import org.eclipse.ui.IViewPart;
|
||||||
import org.eclipse.ui.IWorkbenchPage;
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
|
@ -29,6 +30,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.callhierarchy.CHViewPart;
|
import org.eclipse.cdt.internal.ui.callhierarchy.CHViewPart;
|
||||||
import org.eclipse.cdt.internal.ui.callhierarchy.CallHierarchyUI;
|
import org.eclipse.cdt.internal.ui.callhierarchy.CallHierarchyUI;
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
|
|
||||||
|
|
||||||
public class CallHierarchyBugs extends CallHierarchyBaseTest {
|
public class CallHierarchyBugs extends CallHierarchyBaseTest {
|
||||||
|
@ -143,9 +145,108 @@ public class CallHierarchyBugs extends CallHierarchyBaseTest {
|
||||||
CallHierarchyUI.open(workbenchWindow, (ICElement) obj);
|
CallHierarchyUI.open(workbenchWindow, (ICElement) obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openEditor(IFile file) throws WorkbenchException {
|
private CEditor openEditor(IFile file) throws WorkbenchException {
|
||||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||||
IDE.openEditor(page, file, true);
|
IEditorPart editor= IDE.openEditor(page, file, true);
|
||||||
runEventQueue(0);
|
runEventQueue(0);
|
||||||
|
return (CEditor) editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class Base {
|
||||||
|
// public:
|
||||||
|
// virtual void vmethod();
|
||||||
|
// void method();
|
||||||
|
// };
|
||||||
|
// class Derived : public Base {
|
||||||
|
// public:
|
||||||
|
// void vmethod();
|
||||||
|
// void method();
|
||||||
|
// }
|
||||||
|
// void vrefs() {
|
||||||
|
// Base* b= 0;
|
||||||
|
// b->vmethod(); b->method();
|
||||||
|
// }
|
||||||
|
// void regRefs() {
|
||||||
|
// Base* b= 0;
|
||||||
|
// b->Base::vmethod(); b->Base::method();
|
||||||
|
// }
|
||||||
|
public void testPolyMorphicMethodCalls_156689() throws Exception {
|
||||||
|
String content= getContentsForTest(1)[0].toString();
|
||||||
|
IFile file= createFile(getProject(), "SomeClass.cpp", content);
|
||||||
|
waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
|
||||||
|
final CHViewPart ch= (CHViewPart) activateView(CUIPlugin.ID_CALL_HIERARCHY);
|
||||||
|
final IWorkbenchWindow workbenchWindow = ch.getSite().getWorkbenchWindow();
|
||||||
|
|
||||||
|
// open editor, check outline
|
||||||
|
CEditor editor= openEditor(file);
|
||||||
|
int idx = content.indexOf("vmethod");
|
||||||
|
editor.selectAndReveal(idx, 0);
|
||||||
|
openCallHierarchy(editor);
|
||||||
|
|
||||||
|
Tree chTree= checkTreeNode(ch, 0, "Base::vmethod()").getParent();
|
||||||
|
checkTreeNode(chTree, 0, 0, "regRefs()");
|
||||||
|
checkTreeNode(chTree, 0, 1, "vrefs()");
|
||||||
|
checkTreeNode(chTree, 0, 2, null);
|
||||||
|
|
||||||
|
idx = content.indexOf("vmethod", idx+1);
|
||||||
|
editor.selectAndReveal(idx, 0);
|
||||||
|
openCallHierarchy(editor);
|
||||||
|
|
||||||
|
chTree= checkTreeNode(ch, 0, "Derived::vmethod()").getParent();
|
||||||
|
checkTreeNode(chTree, 0, 0, "vrefs()");
|
||||||
|
checkTreeNode(chTree, 0, 1, null);
|
||||||
|
|
||||||
|
idx = content.indexOf(" method")+1;
|
||||||
|
editor.selectAndReveal(idx, 0);
|
||||||
|
openCallHierarchy(editor);
|
||||||
|
|
||||||
|
chTree= checkTreeNode(ch, 0, "Base::method()").getParent();
|
||||||
|
checkTreeNode(chTree, 0, 0, "regRefs()");
|
||||||
|
checkTreeNode(chTree, 0, 1, "vrefs()");
|
||||||
|
checkTreeNode(chTree, 0, 2, null);
|
||||||
|
|
||||||
|
idx = content.indexOf(" method", idx+1)+1;
|
||||||
|
editor.selectAndReveal(idx, 0);
|
||||||
|
openCallHierarchy(editor);
|
||||||
|
|
||||||
|
chTree= checkTreeNode(ch, 0, "Derived::method()").getParent();
|
||||||
|
checkTreeNode(chTree, 0, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// class Base {
|
||||||
|
// public:
|
||||||
|
// virtual void vmethod();
|
||||||
|
// };
|
||||||
|
// class Derived : public Base {
|
||||||
|
// public:
|
||||||
|
// void vmethod();
|
||||||
|
// }
|
||||||
|
// void vrefs() {
|
||||||
|
// Base* b= 0;
|
||||||
|
// b->vmethod();
|
||||||
|
// }
|
||||||
|
public void testReversePolyMorphicMethodCalls_156689() throws Exception {
|
||||||
|
String content= getContentsForTest(1)[0].toString();
|
||||||
|
IFile file= createFile(getProject(), "SomeClass.cpp", content);
|
||||||
|
waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
|
||||||
|
final CHViewPart ch= (CHViewPart) activateView(CUIPlugin.ID_CALL_HIERARCHY);
|
||||||
|
final IWorkbenchWindow workbenchWindow = ch.getSite().getWorkbenchWindow();
|
||||||
|
|
||||||
|
// open editor, check outline
|
||||||
|
CEditor editor= openEditor(file);
|
||||||
|
int idx = content.indexOf("vrefs");
|
||||||
|
editor.selectAndReveal(idx, 0);
|
||||||
|
openCallHierarchy(editor, false);
|
||||||
|
|
||||||
|
Tree chTree= checkTreeNode(ch, 0, "vrefs()").getParent();
|
||||||
|
TreeItem item= checkTreeNode(chTree, 0, 0, "Base::vmethod()");
|
||||||
|
checkTreeNode(chTree, 0, 1, null);
|
||||||
|
|
||||||
|
expandTreeItem(item);
|
||||||
|
checkTreeNode(item, 0, "Base::vmethod()");
|
||||||
|
checkTreeNode(item, 1, "Derived::vmethod()");
|
||||||
|
checkTreeNode(item, 2, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,9 +65,9 @@ public class CppCallHierarchyTest extends CallHierarchyBaseTest {
|
||||||
IFile headerFile= createFile(getProject(), "testMethods.h", header);
|
IFile headerFile= createFile(getProject(), "testMethods.h", header);
|
||||||
IFile sourceFile= createFile(getProject(), "testMethods.cpp", source);
|
IFile sourceFile= createFile(getProject(), "testMethods.cpp", source);
|
||||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||||
CEditor editor= (CEditor) IDE.openEditor(page, sourceFile);
|
|
||||||
waitForIndexer(fIndex, sourceFile, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
waitForIndexer(fIndex, sourceFile, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
|
||||||
|
CEditor editor= (CEditor) IDE.openEditor(page, sourceFile);
|
||||||
editor.selectAndReveal(source.indexOf("method"), 2);
|
editor.selectAndReveal(source.indexOf("method"), 2);
|
||||||
openCallHierarchy(editor);
|
openCallHierarchy(editor);
|
||||||
Tree tree = getCHTreeViewer().getTree();
|
Tree tree = getCHTreeViewer().getTree();
|
||||||
|
@ -188,10 +188,9 @@ public class CppCallHierarchyTest extends CallHierarchyBaseTest {
|
||||||
IFile sourceFile1= createFile(getProject(), "testMethods1.cpp", source1);
|
IFile sourceFile1= createFile(getProject(), "testMethods1.cpp", source1);
|
||||||
IFile sourceFile2= createFile(getProject(), "testMethods2.cpp", source2);
|
IFile sourceFile2= createFile(getProject(), "testMethods2.cpp", source2);
|
||||||
|
|
||||||
CEditor editor= openFile(sourceFile1);
|
|
||||||
CCorePlugin.getIndexManager().reindex(fCProject);
|
|
||||||
waitForIndexer(fIndex, sourceFile2, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
waitForIndexer(fIndex, sourceFile2, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
|
||||||
|
|
||||||
|
CEditor editor= openFile(sourceFile1);
|
||||||
editor.selectAndReveal(source1.indexOf("method3"), 2);
|
editor.selectAndReveal(source1.indexOf("method3"), 2);
|
||||||
openCallHierarchy(editor);
|
openCallHierarchy(editor);
|
||||||
TreeViewer tv = getCHTreeViewer();
|
TreeViewer tv = getCHTreeViewer();
|
||||||
|
@ -380,5 +379,4 @@ public class CppCallHierarchyTest extends CallHierarchyBaseTest {
|
||||||
checkTreeNode(node, 0, "cfunc()");
|
checkTreeNode(node, 0, "cfunc()");
|
||||||
checkTreeNode(node, 1, null);
|
checkTreeNode(node, 1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -13,8 +13,8 @@ package org.eclipse.cdt.internal.ui.callhierarchy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
@ -22,7 +22,7 @@ import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.WorkingSetFilterUI;
|
import org.eclipse.cdt.internal.ui.viewsupport.WorkingSetFilterUI;
|
||||||
|
|
||||||
public class CElementSet {
|
public class CElementSet {
|
||||||
private Set fSet= new HashSet();
|
private Set fSet= new LinkedHashSet();
|
||||||
private int fHashCode;
|
private int fHashCode;
|
||||||
|
|
||||||
CElementSet( ICElement[] elements) {
|
CElementSet( ICElement[] elements) {
|
||||||
|
|
|
@ -11,15 +11,31 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.ui.callhierarchy;
|
package org.eclipse.cdt.internal.ui.callhierarchy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.core.index.IIndexName;
|
import org.eclipse.cdt.core.index.IIndexName;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.model.ISourceReference;
|
import org.eclipse.cdt.core.model.ISourceReference;
|
||||||
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
||||||
|
|
||||||
|
@ -43,18 +59,143 @@ public class CHQueries {
|
||||||
if (! (callee instanceof ISourceReference)) {
|
if (! (callee instanceof ISourceReference)) {
|
||||||
return EMPTY_NODES;
|
return EMPTY_NODES;
|
||||||
}
|
}
|
||||||
IBinding calleeBinding= IndexUI.elementToBinding(index, callee);
|
final ICProject project = callee.getCProject();
|
||||||
findCalledBy(index, calleeBinding, callee.getCProject(), result);
|
IIndexBinding calleeBinding= IndexUI.elementToBinding(index, callee);
|
||||||
|
if (calleeBinding != null) {
|
||||||
|
findCalledBy(index, calleeBinding, true, project, result);
|
||||||
|
IBinding[] overriddenBindings= getOverriddenBindings(index, calleeBinding);
|
||||||
|
for (int i = 0; i < overriddenBindings.length; i++) {
|
||||||
|
findCalledBy(index, overriddenBindings[i], false, project, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
return cp.createNodes(node, result);
|
return cp.createNodes(node, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void findCalledBy(IIndex index, IBinding callee, ICProject project, CalledByResult result)
|
private static IBinding[] getOverriddenBindings(IIndex index, IIndexBinding binding) {
|
||||||
|
if (binding instanceof ICPPMethod && !(binding instanceof ICPPConstructor)) {
|
||||||
|
try {
|
||||||
|
final ArrayList result= new ArrayList();
|
||||||
|
final ICPPMethod m= (ICPPMethod) binding;
|
||||||
|
final char[] mname= m.getNameCharArray();
|
||||||
|
final ICPPClassType mcl= m.getClassOwner();
|
||||||
|
final IFunctionType mft= m.getType();
|
||||||
|
boolean isVirtual= m.isVirtual();
|
||||||
|
ICPPMethod[] allMethods= mcl.getMethods();
|
||||||
|
for (int i = 0; i < allMethods.length; i++) {
|
||||||
|
ICPPMethod method = allMethods[i];
|
||||||
|
if (CharArrayUtils.equals(mname, method.getNameCharArray()) && !mcl.isSameType(method.getClassOwner())) {
|
||||||
|
if (mft.isSameType(method.getType())) {
|
||||||
|
isVirtual= isVirtual || method.isVirtual();
|
||||||
|
result.add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isVirtual) {
|
||||||
|
return (IBinding[]) result.toArray(new IBinding[result.size()]);
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// index bindings don't throw DOMExceptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IBinding[] getOverridingBindings(IIndex index, IBinding binding) throws CoreException {
|
||||||
|
if (binding instanceof ICPPMethod && !(binding instanceof ICPPConstructor)) {
|
||||||
|
try {
|
||||||
|
final ICPPMethod m= (ICPPMethod) binding;
|
||||||
|
if (isVirtual(m)) {
|
||||||
|
final ArrayList result= new ArrayList();
|
||||||
|
final char[] mname= m.getNameCharArray();
|
||||||
|
final ICPPClassType mcl= m.getClassOwner();
|
||||||
|
final IFunctionType mft= m.getType();
|
||||||
|
ICPPClassType[] subclasses= getSubClasses(index, mcl);
|
||||||
|
for (int i = 0; i < subclasses.length; i++) {
|
||||||
|
ICPPClassType subClass = subclasses[i];
|
||||||
|
ICPPMethod[] methods= subClass.getDeclaredMethods();
|
||||||
|
for (int j = 0; j < methods.length; j++) {
|
||||||
|
ICPPMethod method = methods[j];
|
||||||
|
if (CharArrayUtils.equals(mname, method.getNameCharArray()) &&
|
||||||
|
mft.isSameType(method.getType())) {
|
||||||
|
result.add(method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (IBinding[]) result.toArray(new IBinding[result.size()]);
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// index bindings don't throw DOMExceptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ICPPClassType[] getSubClasses(IIndex index, ICPPClassType mcl) throws CoreException {
|
||||||
|
List result= new LinkedList();
|
||||||
|
HashSet handled= new HashSet();
|
||||||
|
getSubClasses(index, mcl, result, handled);
|
||||||
|
result.remove(0);
|
||||||
|
return (ICPPClassType[]) result.toArray(new ICPPClassType[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getSubClasses(IIndex index, ICPPBinding classOrTypedef, List result, HashSet handled) throws CoreException {
|
||||||
|
try {
|
||||||
|
final String key = CPPVisitor.renderQualifiedName(classOrTypedef.getQualifiedName());
|
||||||
|
if (!handled.add(key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classOrTypedef instanceof ICPPClassType) {
|
||||||
|
result.add(classOrTypedef);
|
||||||
|
}
|
||||||
|
|
||||||
|
IIndexName[] names= index.findNames(classOrTypedef, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS);
|
||||||
|
for (int i = 0; i < names.length; i++) {
|
||||||
|
IIndexName indexName = names[i];
|
||||||
|
if (indexName.isBaseSpecifier()) {
|
||||||
|
IIndexName subClassDef= indexName.getEnclosingDefinition();
|
||||||
|
if (subClassDef != null) {
|
||||||
|
IBinding subClass= index.findBinding(subClassDef);
|
||||||
|
if (subClass instanceof ICPPBinding) {
|
||||||
|
getSubClasses(index, (ICPPBinding) subClass, result, handled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isVirtual(ICPPMethod m) {
|
||||||
|
try {
|
||||||
|
if (m.isVirtual()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final char[] mname= m.getNameCharArray();
|
||||||
|
final ICPPClassType mcl= m.getClassOwner();
|
||||||
|
final IFunctionType mft= m.getType();
|
||||||
|
ICPPMethod[] allMethods= mcl.getMethods();
|
||||||
|
for (int i = 0; i < allMethods.length; i++) {
|
||||||
|
ICPPMethod method = allMethods[i];
|
||||||
|
if (CharArrayUtils.equals(mname, method.getNameCharArray()) && mft.isSameType(method.getType())) {
|
||||||
|
if (method.isVirtual()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// index bindings don't throw DOMExceptions
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void findCalledBy(IIndex index, IBinding callee, boolean includeOrdinaryCalls, ICProject project, CalledByResult result)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
if (callee != null) {
|
|
||||||
IIndexName[] names= index.findNames(callee, IIndex.FIND_REFERENCES | IIndex.SEARCH_ACCROSS_LANGUAGE_BOUNDARIES);
|
IIndexName[] names= index.findNames(callee, IIndex.FIND_REFERENCES | IIndex.SEARCH_ACCROSS_LANGUAGE_BOUNDARIES);
|
||||||
for (int i = 0; i < names.length; i++) {
|
for (int i = 0; i < names.length; i++) {
|
||||||
IIndexName rname = names[i];
|
IIndexName rname = names[i];
|
||||||
|
if (includeOrdinaryCalls || rname.couldBePolymorphicMethodCall()) {
|
||||||
IIndexName caller= rname.getEnclosingDefinition();
|
IIndexName caller= rname.getEnclosingDefinition();
|
||||||
if (caller != null) {
|
if (caller != null) {
|
||||||
ICElement elem= IndexUI.getCElementForName(project, index, caller);
|
ICElement elem= IndexUI.getCElementForName(project, index, caller);
|
||||||
|
@ -80,7 +221,20 @@ public class CHQueries {
|
||||||
IIndexName name = refs[i];
|
IIndexName name = refs[i];
|
||||||
IBinding binding= index.findBinding(name);
|
IBinding binding= index.findBinding(name);
|
||||||
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
|
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
|
||||||
ICElement[] defs = IndexUI.findRepresentative(index, binding);
|
IBinding[] virtualOverriders= getOverridingBindings(index, binding);
|
||||||
|
ICElement[] defs;
|
||||||
|
if (virtualOverriders.length == 0) {
|
||||||
|
defs = IndexUI.findRepresentative(index, binding);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ArrayList list= new ArrayList();
|
||||||
|
list.addAll(Arrays.asList(IndexUI.findRepresentative(index, binding)));
|
||||||
|
for (int j = 0; j < virtualOverriders.length; j++) {
|
||||||
|
IBinding overrider = virtualOverriders[j];
|
||||||
|
list.addAll(Arrays.asList(IndexUI.findRepresentative(index, overrider)));
|
||||||
|
}
|
||||||
|
defs= (ICElement[]) list.toArray(new ICElement[list.size()]);
|
||||||
|
}
|
||||||
if (defs != null && defs.length > 0) {
|
if (defs != null && defs.length > 0) {
|
||||||
result.add(defs, name);
|
result.add(defs, name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue