diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 4a22cfe736e..0d20dab3130 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -644,9 +644,11 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { } else if (binding instanceof ICPPAliasTemplate) { return new CompositeCPPAliasTemplate(this, (ICPPBinding) binding); } else if (binding instanceof ICPPFieldTemplate) { - return new CompositeCPPFieldTemplate(this, (ICPPField) binding); + ICPPField def = (ICPPField) findOneBinding(binding); + return new CompositeCPPFieldTemplate(this, def); } else if (binding instanceof ICPPVariableTemplate) { - return new CompositeCPPVariableTemplate(this, (ICPPVariable) binding); + ICPPVariable def = (ICPPVariable) findOneBinding(binding); + return new CompositeCPPVariableTemplate(this, def); } else { throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java index 55dd9cf6963..9aed16a7c63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; +import org.eclipse.cdt.internal.core.index.CIndex; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil; @@ -66,17 +67,34 @@ public class CompositeInstanceCache { } return null; } + + private void addInstancesFrom(ICompositesFactory cf, ICPPInstanceCache cache) { + ICPPTemplateInstance[] insts= cache.getAllInstances(); + for (ICPPTemplateInstance ti : insts) { + if (ti instanceof IIndexFragmentBinding) { + ICPPTemplateInstance comp= (ICPPTemplateInstance) cf.getCompositeBinding((IIndexFragmentBinding) ti); + ICPPTemplateArgument[] args= comp.getTemplateArguments(); + addInstance(args, comp); + } + } + } private void populate(ICompositesFactory cf, IIndexFragmentBinding fb) { if (fb instanceof ICPPInstanceCache) { - ICPPTemplateInstance[] insts= ((ICPPInstanceCache) fb).getAllInstances(); - for (ICPPTemplateInstance ti : insts) { - if (ti instanceof IIndexFragmentBinding) { - ICPPTemplateInstance comp= (ICPPTemplateInstance) cf.getCompositeBinding((IIndexFragmentBinding) ti); - ICPPTemplateArgument[] args= comp.getTemplateArguments(); - addInstance(args, comp); + addInstancesFrom(cf, (ICPPInstanceCache) fb); + } + + // Also add instanced cached in other fragments. + CIndex index = (CIndex) ((CPPCompositesFactory) cf).getContext(); + try { + IIndexFragmentBinding[] fragmentBindings = index.findEquivalentBindings(fb); + for (IIndexFragmentBinding fragmentBinding : fragmentBindings) { + if (fragmentBinding instanceof ICPPInstanceCache) { + addInstancesFrom(cf, (ICPPInstanceCache) fragmentBinding); } } + } catch (CoreException e) { + CCorePlugin.log(e); } } diff --git a/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF index 40b7355ba16..032741b8d06 100644 --- a/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui.tests/META-INF/MANIFEST.MF @@ -37,7 +37,8 @@ Require-Bundle: org.eclipse.jface.text, com.ibm.icu, org.eclipse.ltk.core.refactoring;bundle-version="3.4.0", org.eclipse.core.filesystem;bundle-version="1.2.0", - org.eclipse.ltk.ui.refactoring + org.eclipse.ltk.ui.refactoring, + org.eclipse.osgi Bundle-ActivationPolicy: lazy Bundle-Vendor: Eclipse CDT Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/BasicSearchTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/BasicSearchTest.java index c99a0039a06..424a7240fa8 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/BasicSearchTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/BasicSearchTest.java @@ -55,6 +55,10 @@ public class BasicSearchTest extends SearchTestBase { return suite(BasicSearchTest.class); } + public BasicSearchTest() { + setStrategy(new SingleProjectStrategy()); + } + // // empty // #include "extHead.h" diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java index b2b61ce9aed..df003c02109 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java @@ -7,6 +7,7 @@ *******************************************************************************/ package org.eclipse.cdt.ui.tests.search; +import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.TextSelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; @@ -14,7 +15,6 @@ import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.FileEditorInput; -import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.ui.testplugin.EditorTestHelper; @@ -31,15 +31,32 @@ import junit.framework.TestSuite; * CSearchTextSelectionQuery directly. */ public class FindReferencesTest extends SearchTestBase { - public static TestSuite suite() { - return suite(FindReferencesTest.class); + public static class SingleProject extends FindReferencesTest { + public SingleProject() { setStrategy(new SingleProjectStrategy()); } + public static TestSuite suite() { return suite(SingleProject.class); } + } + + public static class ReferencedProject extends FindReferencesTest { + public ReferencedProject() { setStrategy(new ReferencedProjectStrategy()); } + public static TestSuite suite() { return suite(ReferencedProject.class); } + } + + public static void addTests(TestSuite suite) { + suite.addTest(SingleProject.suite()); + suite.addTest(ReferencedProject.suite()); + } + + public FindReferencesTest() { + // For convenience, to be able to run tests via right click -> Run As -> JUnit Plugin Test. + // Will use the SingleProjectStrategy when run this way. + setStrategy(new SingleProjectStrategy()); } - private CSearchQuery makeProjectQuery(int offset, int length) { + private CSearchQuery makeSearchQuery(IFile file, TextSelection selection) { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IEditorPart part = null; try { - part = page.openEditor(new FileEditorInput(fHeaderFile), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ + part = page.openEditor(new FileEditorInput(file), "org.eclipse.cdt.ui.editor.CEditor"); //$NON-NLS-1$ } catch (PartInitException e) { assertFalse(true); } @@ -47,8 +64,23 @@ public class FindReferencesTest extends SearchTestBase { CEditor editor = (CEditor) part; EditorTestHelper.joinReconciler(EditorTestHelper.getSourceViewer(editor), 100, 5000, 10); ITranslationUnit tu = editor.getInputCElement(); - return new CSearchTextSelectionQuery(new ICElement[] { fCProject }, tu, new TextSelection(offset, length), - CSearchQuery.FIND_REFERENCES); + return new CSearchTextSelectionQuery(fStrategy.getScope(), tu, selection, CSearchQuery.FIND_REFERENCES); + } + + private TextSelection selectSection(String section, String context, String code) { + int contextOffset; + if (context == null) { + context = code; + contextOffset = 0; + } else { + contextOffset = code.indexOf(context); + if (contextOffset < 0) + fail("Didn't find \"" + context + "\" in \"" + code + "\""); + } + int offset = context.indexOf(section); + if (offset < 0) + fail("Didn't find \"" + section + "\" in \"" + context + "\""); + return new TextSelection(contextOffset + offset, section.length()); } // struct A { @@ -66,8 +98,22 @@ public class FindReferencesTest extends SearchTestBase { // // empty file public void testOnlyPolymorphicMatches_bug491343() throws Exception { - int offset = fHeaderContents.indexOf("waldo() override"); - CSearchQuery query = makeProjectQuery(offset, 5); + CSearchQuery query = makeSearchQuery(fHeaderFile, selectSection("waldo", "waldo() override", fHeaderContents)); + assertOccurrences(query, 1); + } + + // template + // class Waldo { + // void find(); + // }; + + // #include "header.h" + // void foo() { + // Waldo waldo; + // waldo.find(); + // } + public void testMethodOfClassTemplate_509734() throws Exception { + CSearchQuery query = makeSearchQuery(fHeaderFile, selectSection("find", "void find()", fHeaderContents)); assertOccurrences(query, 1); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestBase.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestBase.java index 272706458a3..ad143ce060e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestBase.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestBase.java @@ -8,13 +8,19 @@ package org.eclipse.cdt.ui.tests.search; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.osgi.framework.Bundle; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.TestScannerProvider; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.ui.testplugin.CTestPlugin; import org.eclipse.cdt.ui.tests.BaseUITestCase; @@ -26,33 +32,122 @@ import org.eclipse.cdt.internal.ui.search.CSearchResult; * Base class for tests that test functionality based on CSearchQuery. */ public abstract class SearchTestBase extends BaseUITestCase { - ICProject fCProject; - String fHeaderContents; - IFile fHeaderFile; - CharSequence[] testData; + protected ICProject fCProject; + protected String fHeaderContents; + protected IFile fHeaderFile; + protected String fSourceContents; + protected IFile fSourceFile; + protected CharSequence[] fTestData; + + protected ITestStrategy fStrategy; + public void setStrategy(ITestStrategy strategy) { + fStrategy = strategy; + } + + protected interface ITestStrategy { + void setUp() throws Exception; + void tearDown() throws Exception; + + // The scope for searches. + ICElement[] getScope(); + } + + protected class SingleProjectStrategy implements ITestStrategy { + @Override + public void setUp() throws Exception { + fCProject = CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER); + Bundle b = CTestPlugin.getDefault().getBundle(); + fTestData = TestSourceReader.getContentsForTest(b, "ui", SearchTestBase.this.getClass(), getName(), 2); + assertEquals("Incomplete test data", 2, fTestData.length); + + fHeaderContents = fTestData[0].toString(); + fHeaderFile = TestSourceReader.createFile(fCProject.getProject(), new Path("header.h"), fHeaderContents); + CCorePlugin.getIndexManager().setIndexerId(fCProject, IPDOMManager.ID_FAST_INDEXER); + waitForIndexer(fCProject); + + fSourceContents = fTestData[1].toString(); + fSourceFile = TestSourceReader.createFile(fCProject.getProject(), new Path("references.cpp"), fSourceContents); + waitForIndexer(fCProject); + } + + @Override + public void tearDown() throws Exception { + if (fCProject != null) { + fCProject.getProject().delete(true, npm()); + } + } + + @Override + public ICElement[] getScope() { + return new ICElement[] { fCProject }; + } + } + + protected class ReferencedProjectStrategy implements ITestStrategy { + private ICProject fReferencedCProject; + + @Override + public void setUp() throws Exception { + fCProject = CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", + IPDOMManager.ID_NO_INDEXER); + Bundle b = CTestPlugin.getDefault().getBundle(); + fTestData = TestSourceReader.getContentsForTest(b, "ui", SearchTestBase.this.getClass(), getName(), 2); + assertEquals("Incomplete test data", 2, fTestData.length); + + fReferencedCProject = CProjectHelper.createCCProject("ReferencedContent" + getName() + System.currentTimeMillis(), + "bin", IPDOMManager.ID_NO_INDEXER); + + fHeaderContents = fTestData[0].toString(); + fHeaderFile = TestSourceReader.createFile(fReferencedCProject.getProject(), new Path("header.h"), + fHeaderContents); + + CCorePlugin.getIndexManager().setIndexerId(fReferencedCProject, IPDOMManager.ID_FAST_INDEXER); + CCorePlugin.getIndexManager().reindex(fReferencedCProject); + waitForIndexer(fReferencedCProject); + + TestScannerProvider.sIncludes = new String[] { fReferencedCProject.getProject().getLocation().toOSString() }; + + fSourceContents = fTestData[1].toString(); + fSourceFile = TestSourceReader.createFile(fCProject.getProject(), new Path("refs.cpp"), fSourceContents); + + IProject[] refs = new IProject[] { fReferencedCProject.getProject() }; + IProjectDescription desc = fCProject.getProject().getDescription(); + desc.setReferencedProjects(refs); + fCProject.getProject().setDescription(desc, new NullProgressMonitor()); + + CCorePlugin.getIndexManager().setIndexerId(fCProject, IPDOMManager.ID_FAST_INDEXER); + CCorePlugin.getIndexManager().reindex(fCProject); + waitForIndexer(fCProject); + } + + @Override + public void tearDown() throws Exception { + if (fCProject != null) { + fCProject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, + new NullProgressMonitor()); + } + if (fReferencedCProject != null) { + fReferencedCProject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, + new NullProgressMonitor()); + } + } + + @Override + public ICElement[] getScope() { + return new ICElement[] { fReferencedCProject, fCProject }; + } + } + @Override protected void setUp() throws Exception { super.setUp(); - fCProject = CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER); - Bundle b = CTestPlugin.getDefault().getBundle(); - testData = TestSourceReader.getContentsForTest(b, "ui", this.getClass(), getName(), 2); - assertEquals("Incomplete test data", 2, testData.length); - - fHeaderContents = testData[0].toString(); - fHeaderFile = TestSourceReader.createFile(fCProject.getProject(), new Path("header.h"), fHeaderContents); - CCorePlugin.getIndexManager().setIndexerId(fCProject, IPDOMManager.ID_FAST_INDEXER); - waitForIndexer(fCProject); - - IFile cppfile= TestSourceReader.createFile(fCProject.getProject(), new Path("references.cpp"), testData[1].toString()); - waitForIndexer(fCProject); + fStrategy.setUp(); } @Override protected void tearDown() throws Exception { - if (fCProject != null) { - fCProject.getProject().delete(true, npm()); - } + fStrategy.tearDown(); super.tearDown(); } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestSuite.java index d9687469a7b..3ae856c7a5d 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/SearchTestSuite.java @@ -22,6 +22,6 @@ public class SearchTestSuite extends TestSuite { addTest(BasicSearchTest.suite()); addTest(LinkedNamesFinderTest.suite()); addTest(SearchReferencesAcrossLanguagesTest.suite()); - addTest(FindReferencesTest.suite()); + FindReferencesTest.addTests(this); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchTextSelectionQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchTextSelectionQuery.java index 0ac7b25fec8..55d1738d695 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchTextSelectionQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchTextSelectionQuery.java @@ -73,7 +73,7 @@ public class CSearchTextSelectionQuery extends CSearchQuery { return Status.OK_STATUS; } } - binding = ast.getIndex().findBinding(searchName); + binding = index.findBinding(searchName); binding= CPPTemplates.findDeclarationForSpecialization(binding); if (binding != null) { label= labelForBinding(index, binding, label);