1
0
Fork 0
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:
Nathan Ridge 2017-01-23 01:12:26 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent f810db333f
commit 1a627cc928
8 changed files with 205 additions and 39 deletions

View file

@ -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$
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -55,6 +55,10 @@ public class BasicSearchTest extends SearchTestBase {
return suite(BasicSearchTest.class);
}
public BasicSearchTest() {
setStrategy(new SingleProjectStrategy());
}
// // empty
// #include "extHead.h"

View file

@ -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 <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);
}
}

View file

@ -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();
}

View file

@ -22,6 +22,6 @@ public class SearchTestSuite extends TestSuite {
addTest(BasicSearchTest.suite());
addTest(LinkedNamesFinderTest.suite());
addTest(SearchReferencesAcrossLanguagesTest.suite());
addTest(FindReferencesTest.suite());
FindReferencesTest.addTests(this);
}
}

View file

@ -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);