From ecfdcab4abb0a82f2a30e697b3823f0b3219cab6 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 2 Nov 2011 15:03:13 +0100 Subject: [PATCH] Bug 361999: Call Hierarchy for instance of template-specialization. --- .../callhierarchy/CallHierarchyBaseTest.java | 25 ++++----- .../callhierarchy/CallHierarchyBugs.java | 26 ++++++++++ .../text/contentassist2/CompletionTests.java | 4 +- .../CompletionTests_PlainC.java | 4 +- .../internal/ui/callhierarchy/CHQueries.java | 2 +- .../ui/callhierarchy/CallHierarchyUI.java | 6 +++ .../internal/ui/search/PDOMSearchQuery.java | 7 ++- .../cdt/internal/ui/viewsupport/IndexUI.java | 52 ++++++++++++------- 8 files changed, 86 insertions(+), 40 deletions(-) diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBaseTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBaseTest.java index e726a09a18f..7e8fc911de7 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBaseTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBaseTest.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.ui.tests.callhierarchy; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWTException; @@ -81,24 +82,21 @@ public class CallHierarchyBaseTest extends BaseUITestCase { return editor; } - protected void openCallHierarchy(CEditor editor) { + protected void openCallHierarchy(CEditor editor) throws InterruptedException { CallHierarchyUI.open(editor, (ITextSelection) editor.getSelectionProvider().getSelection()); + for (Job job : Job.getJobManager().find(CallHierarchyUI.class)) { + job.join(); + } + runEventQueue(0); } - protected void openCallHierarchy(CEditor editor, boolean showReferencedBy) { - CallHierarchyUI.setIsJUnitTest(true); - CallHierarchyUI.open(editor, (ITextSelection) editor.getSelectionProvider().getSelection()); - runEventQueue(0); - CHViewPart ch= null; + protected void openCallHierarchy(CEditor editor, boolean showReferencedBy) throws InterruptedException { + openCallHierarchy(editor); IWorkbenchPage page = editor.getSite().getPage(); - for (int i = 0; i < 400; i++) { - ch= (CHViewPart)page.findView(CUIPlugin.ID_CALL_HIERARCHY); - if (ch != null) - break; - runEventQueue(10); - } + CHViewPart ch= (CHViewPart)page.findView(CUIPlugin.ID_CALL_HIERARCHY); assertNotNull(ch); ch.onSetShowReferencedBy(showReferencedBy); + runEventQueue(0); } protected TreeViewer getCHTreeViewer() { @@ -111,8 +109,7 @@ public class CallHierarchyBaseTest extends BaseUITestCase { break; runEventQueue(10); } - assertNotNull(ch); - return ch.getTreeViewer(); + return ch.getTreeViewer(); } protected TreeItem checkTreeNode(TreeItem root, int i1, String label) { diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java index 9e760ff2735..448259b6cd3 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CallHierarchyBugs.java @@ -479,4 +479,30 @@ public class CallHierarchyBugs extends CallHierarchyBaseTest { checkTreeNode(chTree, 0, 1, "Derived::dosomething() : void"); checkTreeNode(chTree, 0, 2, null); } + + // template struct Array { + // template void erase(TIterator it) {} + // }; + // + // int main() { + // Array test; + // test.erase(1); + // } + public void testCallsToInstanceofSpecializedTemplate_361999() throws Exception { + final String content = getAboveComment(); + IFile f2= createFile(getProject(), "testCallsToInstanceofSpecializedTemplate_361999.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("erase(TIterator it)"); + editor.selectAndReveal(idx, 0); + openCallHierarchy(editor, true); + + Tree chTree= checkTreeNode(ch, 0, "Array::erase(TIterator) : void").getParent(); + TreeItem ti= checkTreeNode(chTree, 0, 0, "main() : int"); + checkTreeNode(chTree, 0, 1, null); + } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 628e01e7331..f0f95fad96b 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -29,7 +29,6 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.testplugin.TestScannerProvider; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; -import org.eclipse.cdt.core.testplugin.util.TestSourceReader; /** * A collection of code completion tests. @@ -959,8 +958,7 @@ public class CompletionTests extends AbstractContentAssistTest { createFile(fProject, "header191315.h", content[0].toString()); createFile(fProject, "source191315.c", content[1].toString()); createFile(fProject, "source191315.cpp", content[1].toString()); - IFile dfile= createFile(fProject, "header191315.h", content[0].toString()); - TestSourceReader.waitUntilFileIsIndexed(CCorePlugin.getIndexManager().getIndex(fCProject), dfile, 8000); + waitForIndexer(fCProject); final String[] expected= { "c_linkage()" }; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java index a5b676b433c..44823cfe330 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java @@ -22,7 +22,6 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; -import org.eclipse.cdt.core.testplugin.util.TestSourceReader; /** * Completion tests for plain C. @@ -313,8 +312,7 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { createFile(fProject, "header191315.h", content[0].toString()); createFile(fProject, "source191315.c", content[1].toString()); createFile(fProject, "source191315.cpp", content[1].toString()); - IFile dfile= createFile(fProject, "header191315.h", content[0].toString()); - TestSourceReader.waitUntilFileIsIndexed(CCorePlugin.getIndexManager().getIndex(fCProject), dfile, 8000); + waitForIndexer(fCProject); final String[] expected= { "c_linkage(void)" }; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java index 07cf22d12aa..c72ba3b6a43 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHQueries.java @@ -93,7 +93,7 @@ public class CHQueries { private static void findCalledBy1(IIndex index, IBinding callee, boolean includeOrdinaryCalls, ICProject project, CalledByResult result) throws CoreException { findCalledBy2(index, callee, includeOrdinaryCalls, project, result); - List specializations = IndexUI.findSpecializations(callee); + List specializations = IndexUI.findSpecializations(index, callee); for (IBinding spec : specializations) { findCalledBy2(index, spec, includeOrdinaryCalls, project, result); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java index d520b11a21f..3aba5d15132 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java @@ -71,6 +71,7 @@ public class CallHierarchyUI { final ICElement[] elems= findDefinitions(input); if (elems != null && elems.length > 0) { display.asyncExec(new Runnable() { + @Override public void run() { internalOpen(window, elems); }}); @@ -134,6 +135,7 @@ public class CallHierarchyUI { final ICElement[] elems= findDefinitions(project, editorInput, sel); if (elems.length > 0) { display.asyncExec(new Runnable() { + @Override public void run() { internalOpen(editor.getSite().getWorkbenchWindow(), elems); }}); @@ -146,6 +148,10 @@ public class CallHierarchyUI { return e.getStatus(); } } + @Override + public boolean belongsTo(Object family) { + return family == CallHierarchyUI.class; + } }; job.setUser(true); job.schedule(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java index 67b81215a74..8d43fe87f67 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java @@ -147,6 +147,7 @@ public abstract class PDOMSearchQuery implements ISearchQuery { return defaultLabel; } + @Override public String getLabel() { String type; if ((flags & FIND_REFERENCES) != 0) { @@ -197,14 +198,17 @@ public abstract class PDOMSearchQuery implements ISearchQuery { return label + " " + countLabel; //$NON-NLS-1$ } + @Override public boolean canRerun() { return true; } + @Override public boolean canRunInBackground() { return true; } + @Override public ISearchResult getSearchResult() { return result; } @@ -344,7 +348,7 @@ public abstract class PDOMSearchQuery implements ISearchQuery { if ((flags & FIND_REFERENCES) != 0) { for (IBinding binding : bindings) { if (binding != null) { - List specializations = IndexUI.findSpecializations(binding); + List specializations = IndexUI.findSpecializations(index, binding); for (IBinding spec : specializations) { if (spec != null && handled.add(spec)) { createMatches1(index, spec, names); @@ -481,6 +485,7 @@ public abstract class PDOMSearchQuery implements ISearchQuery { return preferred; } + @Override public final IStatus run(IProgressMonitor monitor) throws OperationCanceledException { PDOMSearchResult result= (PDOMSearchResult) getSearchResult(); result.removeAll(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java index c11a424b741..1b055ed0631 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java @@ -409,6 +409,7 @@ public class IndexUI { final IASTName[] result= {null}; ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_ACTIVE_ONLY, null, new ASTRunnable() { + @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) { if (ast != null) { final IASTNodeSelector nodeSelector = ast.getNodeSelector(null); @@ -490,36 +491,51 @@ public class IndexUI { /** * Searches for all specializations that depend on the definition of the given binding. */ - public static List findSpecializations(IBinding binding) throws CoreException { + public static List findSpecializations(IIndex index, IBinding binding) throws CoreException { List result= null; - IBinding owner = binding.getOwner(); - if (owner != null) { - List specializedOwners= findSpecializations(owner); - if (!specializedOwners.isEmpty()) { - result= new ArrayList(specializedOwners.size()); - - for (IBinding specOwner : specializedOwners) { - if (specOwner instanceof ICPPClassSpecialization) { - result.add(((ICPPClassSpecialization) specOwner).specializeMember(binding)); - } - } - } - } - + // Check for instances of the given binding if (binding instanceof ICPPInstanceCache) { final List instances= Arrays.asList(((ICPPInstanceCache) binding).getAllInstances()); if (!instances.isEmpty()) { - if (result == null) - result= new ArrayList(instances.size()); - for (ICPPTemplateInstance inst : instances) { if (!ASTInternal.hasDeclaration(inst)) { + if (result == null) + result= new ArrayList(instances.size()); result.add(inst); } } } } + + // Check for specializations of the owner + IBinding owner = binding.getOwner(); + if (owner != null) { + for (IBinding specOwner : findSpecializations(index, owner)) { + if (specOwner instanceof ICPPClassSpecialization) { + // Add the specialized member + IBinding specializedMember = ((ICPPClassSpecialization) specOwner).specializeMember(binding); + specializedMember= index.adaptBinding(specializedMember); + if (specializedMember != null) { + if (result == null) + result= new ArrayList(findSpecializations(index, owner).size()); + result.add(specializedMember); + // Also add instances of the specialized member + if (specializedMember instanceof ICPPInstanceCache) { + final List instances= Arrays.asList(((ICPPInstanceCache) specializedMember).getAllInstances()); + if (!instances.isEmpty()) { + for (ICPPTemplateInstance inst : instances) { + if (!ASTInternal.hasDeclaration(inst)) { + result.add(inst); + } + } + } + } + } + } + } + } + if (result != null) { return result;