mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Bug 509734 - Cross-project references to template instances
Change-Id: I14ed61d2f709f615ba74501e70ac4ddc0db3d05a
This commit is contained in:
parent
f810db333f
commit
1a627cc928
8 changed files with 205 additions and 39 deletions
|
@ -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$
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -67,9 +68,8 @@ public class CompositeInstanceCache {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void populate(ICompositesFactory cf, IIndexFragmentBinding fb) {
|
||||
if (fb instanceof ICPPInstanceCache) {
|
||||
ICPPTemplateInstance[] insts= ((ICPPInstanceCache) fb).getAllInstances();
|
||||
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);
|
||||
|
@ -78,6 +78,24 @@ public class CompositeInstanceCache {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void populate(ICompositesFactory cf, IIndexFragmentBinding fb) {
|
||||
if (fb instanceof ICPPInstanceCache) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public ICPPTemplateInstance[] getAllInstances() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -55,6 +55,10 @@ public class BasicSearchTest extends SearchTestBase {
|
|||
return suite(BasicSearchTest.class);
|
||||
}
|
||||
|
||||
public BasicSearchTest() {
|
||||
setStrategy(new SingleProjectStrategy());
|
||||
}
|
||||
|
||||
// // empty
|
||||
|
||||
// #include "extHead.h"
|
||||
|
|
|
@ -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); }
|
||||
}
|
||||
|
||||
private CSearchQuery makeProjectQuery(int offset, int length) {
|
||||
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) {
|
||||
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 <typename T>
|
||||
// class Waldo {
|
||||
// void find();
|
||||
// };
|
||||
|
||||
// #include "header.h"
|
||||
// void foo() {
|
||||
// Waldo<int> waldo;
|
||||
// waldo.find();
|
||||
// }
|
||||
public void testMethodOfClassTemplate_509734() throws Exception {
|
||||
CSearchQuery query = makeSearchQuery(fHeaderFile, selectSection("find", "void find()", fHeaderContents));
|
||||
assertOccurrences(query, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
public void setUp() throws Exception {
|
||||
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);
|
||||
fTestData = TestSourceReader.getContentsForTest(b, "ui", SearchTestBase.this.getClass(), getName(), 2);
|
||||
assertEquals("Incomplete test data", 2, fTestData.length);
|
||||
|
||||
fHeaderContents = testData[0].toString();
|
||||
fHeaderContents = fTestData[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());
|
||||
fSourceContents = fTestData[1].toString();
|
||||
fSourceFile = TestSourceReader.createFile(fCProject.getProject(), new Path("references.cpp"), fSourceContents);
|
||||
waitForIndexer(fCProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
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();
|
||||
fStrategy.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
fStrategy.tearDown();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,6 @@ public class SearchTestSuite extends TestSuite {
|
|||
addTest(BasicSearchTest.suite());
|
||||
addTest(LinkedNamesFinderTest.suite());
|
||||
addTest(SearchReferencesAcrossLanguagesTest.suite());
|
||||
addTest(FindReferencesTest.suite());
|
||||
FindReferencesTest.addTests(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue