1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

In call hierarchy, show virtual overriders for the input method, bug 246064.

This commit is contained in:
Markus Schorn 2009-10-16 11:45:52 +00:00
parent 67fe42e072
commit 37c899ffc2
3 changed files with 76 additions and 21 deletions

View file

@ -443,4 +443,39 @@ public class CallHierarchyBugs extends CallHierarchyBaseTest {
checkTreeNode(chTree, 0, 1, null);
}
// class Base {
// public:
// virtual void dosomething() {}
// };
//
// class Derived : public Base {
// public:
// void dosomething() { }
// };
//
// void test() {
// Base *dbPtr = new Derived();
// dbPtr->dosomething();
// delete dbPtr;
// }
public void testCallsToFromVirtualMethod_246064() throws Exception {
final StringBuffer[] contents = getContentsForTest(1);
final String content = contents[0].toString();
IFile f2= createFile(getProject(), "testCallsToFromVirtualMethod_246064.cpp", content);
waitForIndexer(fIndex, f2, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
final CHViewPart ch= (CHViewPart) activateView(CUIPlugin.ID_CALL_HIERARCHY);
// open editor, check outline
CEditor editor= openEditor(f2);
int idx = content.indexOf("dosomething();");
editor.selectAndReveal(idx, 0);
openCallHierarchy(editor, false);
Tree chTree= checkTreeNode(ch, 0, "Base::dosomething()").getParent();
checkTreeNode(chTree, 0, 0, "Base::dosomething()");
checkTreeNode(chTree, 0, 1, "Derived::dosomething()");
checkTreeNode(chTree, 0, 2, null);
}
}

View file

@ -18,13 +18,16 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.swt.widgets.Display;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IMethod;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IVariable;
import org.eclipse.cdt.ui.CUIPlugin;
@ -130,6 +133,18 @@ public class CHContentProvider extends AsyncTreeContentProvider {
});
}
ITranslationUnit tu= CModelUtil.getTranslationUnit(element);
if (!fComputeReferencedBy && element instanceof IMethod) {
IIndexName methodName= IndexUI.elementToName(index, element);
if (methodName != null) {
IBinding methodBinding= index.findBinding(methodName);
if (methodBinding instanceof ICPPMethod) {
ICElement[] defs= CHQueries.findOverriders(index, (ICPPMethod) methodBinding);
if (defs != null && defs.length > 0) {
return new Object[] { new CHMultiDefNode(null, tu, 0, defs, methodBinding.getLinkage().getLinkageID()) };
}
}
}
}
return new Object[] { new CHNode(null, tu, 0, element, -1) };
}
finally {
@ -177,8 +192,7 @@ public class CHContentProvider extends AsyncTreeContentProvider {
CHNode[] createNodes(CHNode node, CalledByResult result) throws CoreException {
ArrayList<CHNode> nodes= new ArrayList<CHNode>();
ICElement[] elements= result.getElements();
for (int i = 0; i < elements.length; i++) {
ICElement element = elements[i];
for (ICElement element : elements) {
if (element != null) {
if (fFilter == null || fFilter.isPartOfWorkingSet(element)) {
IIndexName[] refs= result.getReferences(element);
@ -201,8 +215,7 @@ public class CHContentProvider extends AsyncTreeContentProvider {
}
boolean readAccess= false;
boolean writeAccess= false;
for (int i = 0; i < refs.length; i++) {
IIndexName reference = refs[i];
for (IIndexName reference : refs) {
node.addReference(new CHReferenceInfo(reference.getNodeOffset(), reference.getNodeLength()));
readAccess= (readAccess || reference.isReadAccess());
writeAccess= (writeAccess || reference.isWriteAccess());
@ -216,8 +229,8 @@ public class CHContentProvider extends AsyncTreeContentProvider {
ITranslationUnit tu= CModelUtil.getTranslationUnit(node.getRepresentedDeclaration());
ArrayList<CHNode> result= new ArrayList<CHNode>();
CElementSet[] elementSets= callsTo.getElementSets();
for (int i = 0; i < elementSets.length; i++) {
CElementSet set = elementSets[i];
for (CElementSet elementSet : elementSets) {
CElementSet set = elementSet;
if (!set.isEmpty()) {
IIndexName[] refs= callsTo.getReferences(set);
ICElement[] elements= set.getElements(fFilter);
@ -246,8 +259,7 @@ public class CHContentProvider extends AsyncTreeContentProvider {
boolean readAccess= false;
boolean writeAccess= false;
for (int i = 0; i < references.length; i++) {
IIndexName reference = references[i];
for (IIndexName reference : references) {
node.addReference(new CHReferenceInfo(reference.getNodeOffset(), reference.getNodeLength()));
readAccess= (readAccess || reference.isReadAccess());
writeAccess= (writeAccess || reference.isWriteAccess());

View file

@ -120,19 +120,7 @@ public class CHQueries {
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
ICElement[] defs= null;
if (binding instanceof ICPPMethod) {
try {
IBinding[] virtualOverriders= ClassTypeHelper.findOverriders(index, (ICPPMethod) binding);
if (virtualOverriders.length > 0) {
ArrayList<ICElementHandle> list= new ArrayList<ICElementHandle>();
list.addAll(Arrays.asList(IndexUI.findRepresentative(index, binding)));
for (IBinding overrider : virtualOverriders) {
list.addAll(Arrays.asList(IndexUI.findRepresentative(index, overrider)));
}
defs= list.toArray(new ICElement[list.size()]);
}
} catch (DOMException e) {
// index bindings don't throw DOMExceptions
}
defs = findOverriders(index, (ICPPMethod) binding);
}
if (defs == null) {
defs= IndexUI.findRepresentative(index, binding);
@ -145,4 +133,24 @@ public class CHQueries {
}
return cp.createNodes(node, result);
}
/**
* Searches for overriders of method and converts them to ICElement, returns null, if there are none.
*/
static ICElement[] findOverriders(IIndex index, ICPPMethod binding) throws CoreException {
try {
IBinding[] virtualOverriders= ClassTypeHelper.findOverriders(index, binding);
if (virtualOverriders.length > 0) {
ArrayList<ICElementHandle> list= new ArrayList<ICElementHandle>();
list.addAll(Arrays.asList(IndexUI.findRepresentative(index, binding)));
for (IBinding overrider : virtualOverriders) {
list.addAll(Arrays.asList(IndexUI.findRepresentative(index, overrider)));
}
return list.toArray(new ICElement[list.size()]);
}
} catch (DOMException e) {
// index bindings don't throw DOMExceptions
}
return null;
}
}