1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 405678 - fix "show references" not showing all references of a

strucuture field in mixed C and C++ code

Change-Id: Ie5c5f96e18d9b949c69fcf8f330e31fe8a9002da
Signed-off-by: Wei Li <wei.r.li@ericsson.com>
This commit is contained in:
Wei Li 2015-06-16 20:13:27 +00:00 committed by Gerrit Code Review @ Eclipse.org
parent 4646b8854f
commit 654c2999e1
5 changed files with 169 additions and 3 deletions

View file

@ -47,6 +47,7 @@ import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
@ -1553,6 +1554,20 @@ public class PDOM extends PlatformObject implements IPDOM {
result = FindBinding.findBinding(c.getIndex(), c,
func.getNameCharArray(), new int[] { IIndexCBindingConstants.CFUNCTION }, 0);
}
} else if (binding instanceof ICPPField) {
ICPPField field = (ICPPField) binding;
IBinding parent = field.getCompositeTypeOwner();
PDOMBinding[] cOwners = getCBindingForCPP(parent);
List<PDOMBinding> results = new ArrayList<>();
for (PDOMBinding cOwner : cOwners) {
result = FindBinding.findBinding(cOwner, c,
field.getNameCharArray(), new int[] { IIndexCBindingConstants.CFIELD }, 0);
if (result != null) {
results.add(result);
}
}
return results.isEmpty() ? PDOMBinding.EMPTY_PDOMBINDING_ARRAY : results.toArray(new PDOMBinding[results.size()]);
} else if (binding instanceof ICPPVariable) {
ICPPVariable var = (ICPPVariable) binding;
if (var.isExternC()) {
@ -1586,6 +1601,7 @@ public class PDOM extends PlatformObject implements IPDOM {
if (cpp == null) {
return PDOMBinding.EMPTY_PDOMBINDING_ARRAY;
}
PDOMBinding[] cppOwners = null;
IndexFilter filter= null;
if (binding instanceof IFunction) {
filter= new IndexFilter() {
@ -1597,6 +1613,12 @@ public class PDOM extends PlatformObject implements IPDOM {
return false;
}
};
} else if (binding instanceof IField) {
IBinding compOwner = ((IField) binding).getCompositeTypeOwner();
cppOwners = getCPPBindingForC(compOwner);
if (cppOwners.length > 0) {
filter = IndexFilter.ALL;
}
} else if (binding instanceof IVariable) {
if (!(binding instanceof IField) && !(binding instanceof IParameter)) {
filter= new IndexFilter() {
@ -1645,7 +1667,13 @@ public class PDOM extends PlatformObject implements IPDOM {
if (filter != null) {
BindingCollector collector=
new BindingCollector(cpp, binding.getNameCharArray(), filter, false, false, true);
cpp.accept(collector);
if (cppOwners != null) {
for (PDOMBinding owner : cppOwners) {
owner.accept(collector);
}
} else {
cpp.accept(collector);
}
return collector.getBindings();
}
return PDOMBinding.EMPTY_PDOMBINDING_ARRAY;

View file

@ -0,0 +1,135 @@
/*******************************************************************************
* Copyright (c) 2015 Wei Li
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wei Li - initial implementation
*******************************************************************************/
package org.eclipse.cdt.ui.tests.search;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager;
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.ui.CUIPlugin;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.search.CSearchResult;
import org.eclipse.cdt.internal.ui.search.CSearchTextSelectionQuery;
import junit.framework.TestSuite;
public class SearchReferencesAcrossLanguagesTest extends BaseUITestCase {
protected ICProject fCProject;
protected IIndex fIndex;
public SearchReferencesAcrossLanguagesTest(String name) {
super(name);
}
public static TestSuite suite() {
return suite(SearchReferencesAcrossLanguagesTest.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
fCProject = CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_FAST_INDEXER);
waitForIndexer(fCProject);
fIndex= CCorePlugin.getIndexManager().getIndex(fCProject);
}
@Override
protected void tearDown() throws Exception {
closeAllEditors();
if (fCProject != null) {
CProjectHelper.delete(fCProject);
}
super.tearDown();
}
protected IProject getProject() {
return fCProject.getProject();
}
// typedef struct foo_s{
// int m1;
// } foo_t;
// #include "405678.h"
// void bar_c() {
// foo_t foo;
// foo.m1 = 2;
// }
// #include "405678.h"
// void bar_cpp() {
// foo_t foo;
// foo.m1 = 1;
// }
public void testSearchReferencesAcrossLangs_405678() throws Exception {
final StringBuilder[] contents = getContentsForTest(3);
final String hcontent = contents[0].toString();
final String ccontent = contents[1].toString();
final String cppcontent = contents[2].toString();
IFile f_h= createFile(getProject(), "405678.h", hcontent);
IFile f_c= createFile(getProject(), "405678.c", ccontent);
IFile f_cpp= createFile(getProject(), "405678.cpp", cppcontent);
IIndexManager indexManager = CCorePlugin.getIndexManager();
indexManager.update(new ICElement[] {fCProject}, IIndexManager.UPDATE_ALL);
waitForIndexer(fCProject);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
assertNotNull(page);
IEditorPart editor = IDE.openEditor(page, f_h, CUIPlugin.EDITOR_ID);
assertNotNull(editor);
CEditor ceditor = (CEditor) editor.getAdapter(CEditor.class);
assertNotNull(ceditor);
ceditor.selectAndReveal(hcontent.indexOf("m1"), 2);
ISelection sel = ceditor.getSelectionProvider().getSelection();
// Now a query is created and executed.
CSearchTextSelectionQuery query = new CSearchTextSelectionQuery(null, ceditor.getInputCElement(), (ITextSelection) sel, IIndex.FIND_REFERENCES);
IStatus status = null;
long end_ms = System.currentTimeMillis() + 1000;
do {
status = query.run(npm());
if (status == Status.CANCEL_STATUS) {
Thread.sleep(100);
}
} while(!status.isOK() && System.currentTimeMillis() < end_ms);
assertTrue("query failed: " + status.getMessage(), status.isOK());
ISearchResult result = query.getSearchResult();
assertNotNull(result);
assertTrue(result instanceof CSearchResult);
// The query should have found two references, one in the c source file and another
// in the cpp source file
CSearchResult searchResult = (CSearchResult) result;
assertEquals(2, searchResult.getMatchCount());
}
}

View file

@ -21,5 +21,6 @@ public class SearchTestSuite extends TestSuite {
super(SearchTestSuite.class.getName());
addTest(BasicSearchTest.suite());
addTest(LinkedNamesFinderTest.suite());
addTest(SearchReferencesAcrossLanguagesTest.suite());
}
}

View file

@ -65,7 +65,7 @@ public class CHQueries {
return EMPTY_NODES;
final String ct = tu.getContentTypeId();
if (ct.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER)) {
if (ct.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) || ct.equals(CCorePlugin.CONTENT_TYPE_CHEADER)) {
// Bug 260262: in a header file we need to consider C and C++.
findCalledBy(callee, ILinkage.C_LINKAGE_ID, index, result);
findCalledBy(callee, ILinkage.CPP_LINKAGE_ID, index, result);

View file

@ -14,8 +14,10 @@ package org.eclipse.cdt.internal.ui.viewsupport;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
@ -289,7 +291,7 @@ public class IndexUI {
if (binding != null) {
IIndexName[] defs= index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
ArrayList<ICElementHandle> result= new ArrayList<>();
Set<ICElementHandle> result = new LinkedHashSet<>();
for (IIndexName in : defs) {
ICElementHandle definition= getCElementForName((ICProject) null, index, in);
if (definition != null) {