1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Consider static functions in fall-back navigation, bug 252549.

This commit is contained in:
Markus Schorn 2008-10-29 10:17:24 +00:00
parent 72dc668810
commit 9ca7ade7ee
3 changed files with 120 additions and 1 deletions

View file

@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.core.runtime.Assert;
/**
* A convenience visitor that collects names.
* @since 5.1
*/
public final class ASTNameCollector extends ASTVisitor {
private char[] fName;
private ArrayList<IASTName> fFound= new ArrayList<IASTName>(4);
/**
* Construct a name collector for the given name.
*/
public ASTNameCollector(char[] name) {
Assert.isNotNull(name);
fName= name;
shouldVisitNames = true;
}
/**
* Construct a name collector for the given name.
*/
public ASTNameCollector(String name) {
this(name.toCharArray());
}
@Override
public int visit(IASTName name) {
if (name != null && !(name instanceof ICPPASTQualifiedName) && !(name instanceof ICPPASTTemplateId)) {
if (CharArrayUtils.equals(fName, name.toCharArray())) {
fFound.add(name);
}
}
return PROCESS_CONTINUE;
}
/**
* Return the array of matching names.
*/
public IASTName[] getNames() {
return fFound.toArray(new IASTName[fFound.size()]);
}
/**
* Clear the names found, such that the collector can be reused.
*/
public void clear() {
fFound.clear();
}
}

View file

@ -1032,4 +1032,22 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
assertEquals(((ASTNode)decl).getOffset(), od1); assertEquals(((ASTNode)decl).getOffset(), od1);
} }
} }
// static int myFunc(int) {}
// #define USE_FUNC(x) (myFunc(x) == 0)
public void testFallBackForStaticFuncs_Bug252549() throws Exception {
String code= getContentsForTest(1)[0].toString();
String[] filenames= {"testBug252549.c", "testBug252549.cpp"};
for (int i=0; i<2; i++) {
OpenDeclarationsAction.sAllowFallback= true;
IFile file = importFile(filenames[i], code);
int offset= code.indexOf("myFunc(x)");
IASTNode decl= testF3(file, offset);
assertTrue(decl instanceof IASTName);
final IASTName name = (IASTName) decl;
assertTrue(name.isDefinition());
assertEquals("myFunc", name.toString());
}
}
} }

View file

@ -14,8 +14,10 @@ package org.eclipse.cdt.internal.ui.search.actions;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -34,6 +36,7 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTNameCollector;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
@ -222,7 +225,36 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
final ICProject project = fWorkingCopy.getCProject(); final ICProject project = fWorkingCopy.getCProject();
final char[] name = fSelectedText.toCharArray(); final char[] name = fSelectedText.toCharArray();
List<ICElement> elems= new ArrayList<ICElement>(); List<ICElement> elems= new ArrayList<ICElement>();
// bug 252549, search for names in the AST first
Set<IBinding> bindings= new HashSet<IBinding>();
Set<IBinding> ignoreIndexBindings= new HashSet<IBinding>();
ASTNameCollector nc= new ASTNameCollector(fSelectedText);
ast.accept(nc);
IASTName[] candidates= nc.getNames();
for (IASTName astName : candidates) {
try {
IBinding b= astName.resolveBinding();
if (b!=null && !(b instanceof IProblemBinding)) {
if (bindings.add(b)) {
ignoreIndexBindings.add(fIndex.adaptBinding(b));
}
}
} catch (RuntimeException e) {
CCorePlugin.log(e);
}
}
// search the index, also
final IndexFilter filter = IndexFilter.getDeclaredBindingFilter(ast.getLinkage().getLinkageID(), false); final IndexFilter filter = IndexFilter.getDeclaredBindingFilter(ast.getLinkage().getLinkageID(), false);
final IIndexBinding[] idxBindings = fIndex.findBindings(name, false, filter, fMonitor);
for (IIndexBinding idxBinding : idxBindings) {
if (!ignoreIndexBindings.contains(idxBinding)) {
bindings.add(idxBinding);
}
}
// search for a macro in the index
IIndexMacro[] macros= fIndex.findMacros(name, filter, fMonitor); IIndexMacro[] macros= fIndex.findMacros(name, filter, fMonitor);
for (IIndexMacro macro : macros) { for (IIndexMacro macro : macros) {
ICElement elem= IndexUI.getCElementForMacro(project, fIndex, macro); ICElement elem= IndexUI.getCElementForMacro(project, fIndex, macro);
@ -230,7 +262,8 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
elems.add(elem); elems.add(elem);
} }
} }
IIndexBinding[] bindings = fIndex.findBindings(name, false, filter, fMonitor);
// convert bindings to CElements
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
final IName[] names = findNames(fIndex, ast, KIND_OTHER, binding); final IName[] names = findNames(fIndex, ast, KIND_OTHER, binding);
convertToCElements(project, fIndex, names, elems); convertToCElements(project, fIndex, names, elems);