1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-07 00:05:53 +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); 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.swt.widgets.Display;
import org.eclipse.cdt.core.CCorePlugin; 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.IEnumerator;
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.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.CoreModel;
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.IMethod;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IVariable; import org.eclipse.cdt.core.model.IVariable;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
@ -130,6 +133,18 @@ public class CHContentProvider extends AsyncTreeContentProvider {
}); });
} }
ITranslationUnit tu= CModelUtil.getTranslationUnit(element); 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) }; return new Object[] { new CHNode(null, tu, 0, element, -1) };
} }
finally { finally {
@ -177,8 +192,7 @@ public class CHContentProvider extends AsyncTreeContentProvider {
CHNode[] createNodes(CHNode node, CalledByResult result) throws CoreException { CHNode[] createNodes(CHNode node, CalledByResult result) throws CoreException {
ArrayList<CHNode> nodes= new ArrayList<CHNode>(); ArrayList<CHNode> nodes= new ArrayList<CHNode>();
ICElement[] elements= result.getElements(); ICElement[] elements= result.getElements();
for (int i = 0; i < elements.length; i++) { for (ICElement element : elements) {
ICElement element = elements[i];
if (element != null) { if (element != null) {
if (fFilter == null || fFilter.isPartOfWorkingSet(element)) { if (fFilter == null || fFilter.isPartOfWorkingSet(element)) {
IIndexName[] refs= result.getReferences(element); IIndexName[] refs= result.getReferences(element);
@ -201,8 +215,7 @@ public class CHContentProvider extends AsyncTreeContentProvider {
} }
boolean readAccess= false; boolean readAccess= false;
boolean writeAccess= false; boolean writeAccess= false;
for (int i = 0; i < refs.length; i++) { for (IIndexName reference : refs) {
IIndexName reference = refs[i];
node.addReference(new CHReferenceInfo(reference.getNodeOffset(), reference.getNodeLength())); node.addReference(new CHReferenceInfo(reference.getNodeOffset(), reference.getNodeLength()));
readAccess= (readAccess || reference.isReadAccess()); readAccess= (readAccess || reference.isReadAccess());
writeAccess= (writeAccess || reference.isWriteAccess()); writeAccess= (writeAccess || reference.isWriteAccess());
@ -216,8 +229,8 @@ public class CHContentProvider extends AsyncTreeContentProvider {
ITranslationUnit tu= CModelUtil.getTranslationUnit(node.getRepresentedDeclaration()); ITranslationUnit tu= CModelUtil.getTranslationUnit(node.getRepresentedDeclaration());
ArrayList<CHNode> result= new ArrayList<CHNode>(); ArrayList<CHNode> result= new ArrayList<CHNode>();
CElementSet[] elementSets= callsTo.getElementSets(); CElementSet[] elementSets= callsTo.getElementSets();
for (int i = 0; i < elementSets.length; i++) { for (CElementSet elementSet : elementSets) {
CElementSet set = elementSets[i]; CElementSet set = elementSet;
if (!set.isEmpty()) { if (!set.isEmpty()) {
IIndexName[] refs= callsTo.getReferences(set); IIndexName[] refs= callsTo.getReferences(set);
ICElement[] elements= set.getElements(fFilter); ICElement[] elements= set.getElements(fFilter);
@ -246,8 +259,7 @@ public class CHContentProvider extends AsyncTreeContentProvider {
boolean readAccess= false; boolean readAccess= false;
boolean writeAccess= false; boolean writeAccess= false;
for (int i = 0; i < references.length; i++) { for (IIndexName reference : references) {
IIndexName reference = references[i];
node.addReference(new CHReferenceInfo(reference.getNodeOffset(), reference.getNodeLength())); node.addReference(new CHReferenceInfo(reference.getNodeOffset(), reference.getNodeLength()));
readAccess= (readAccess || reference.isReadAccess()); readAccess= (readAccess || reference.isReadAccess());
writeAccess= (writeAccess || reference.isWriteAccess()); writeAccess= (writeAccess || reference.isWriteAccess());

View file

@ -120,19 +120,7 @@ public class CHQueries {
if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) { if (CallHierarchyUI.isRelevantForCallHierarchy(binding)) {
ICElement[] defs= null; ICElement[] defs= null;
if (binding instanceof ICPPMethod) { if (binding instanceof ICPPMethod) {
try { defs = findOverriders(index, (ICPPMethod) binding);
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
}
} }
if (defs == null) { if (defs == null) {
defs= IndexUI.findRepresentative(index, binding); defs= IndexUI.findRepresentative(index, binding);
@ -145,4 +133,24 @@ public class CHQueries {
} }
return cp.createNodes(node, result); 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;
}
} }