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 b320516e23b..d635772fd12 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 963a1017f3b..559caaccd50 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 @@ -15,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; @@ -35,8 +34,25 @@ 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 makeSearchQuery(IFile file, TextSelection selection) { @@ -51,7 +67,7 @@ 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, selection, CSearchQuery.FIND_REFERENCES); + return new CSearchTextSelectionQuery(fStrategy.getScope(), tu, selection, CSearchQuery.FIND_REFERENCES); } private TextSelection selectSection(String section, String context, String code) { @@ -137,4 +153,19 @@ public class FindReferencesTest extends SearchTestBase { CSearchQuery query = makeSearchQuery(fSourceFile, selectSection("findMe", "findMe(b)", fSourceContents)); 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 20792fdbf61..5b2c3bfb382 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; @@ -31,31 +37,117 @@ public abstract class SearchTestBase extends BaseUITestCase { protected IFile fHeaderFile; protected String fSourceContents; protected IFile fSourceFile; - protected CharSequence[] testData; + 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); - - fSourceContents = testData[1].toString(); - fSourceFile = TestSourceReader.createFile(fCProject.getProject(), new Path("references.cpp"), fSourceContents); - 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);