From 9ca7ade7ee969db29932c171da09ee162eb300fc Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 29 Oct 2008 10:17:24 +0000 Subject: [PATCH] Consider static functions in fall-back navigation, bug 252549. --- .../cdt/core/dom/ast/ASTNameCollector.java | 68 +++++++++++++++++++ .../selection/CPPSelectionTestsNoIndexer.java | 18 +++++ .../actions/OpenDeclarationsAction.java | 35 +++++++++- 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTNameCollector.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTNameCollector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTNameCollector.java new file mode 100644 index 00000000000..851db518964 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTNameCollector.java @@ -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 fFound= new ArrayList(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(); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java index 03627e33148..265a426b421 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java @@ -1032,4 +1032,22 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { 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()); + } + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java index 91319d6e075..714f89407e9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java @@ -14,8 +14,10 @@ package org.eclipse.cdt.internal.ui.search.actions; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.eclipse.core.runtime.CoreException; 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.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.IASTFileLocation; 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 char[] name = fSelectedText.toCharArray(); List elems= new ArrayList(); + + // bug 252549, search for names in the AST first + Set bindings= new HashSet(); + Set ignoreIndexBindings= new HashSet(); + 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 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); for (IIndexMacro macro : macros) { ICElement elem= IndexUI.getCElementForMacro(project, fIndex, macro); @@ -230,7 +262,8 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR elems.add(elem); } } - IIndexBinding[] bindings = fIndex.findBindings(name, false, filter, fMonitor); + + // convert bindings to CElements for (IBinding binding : bindings) { final IName[] names = findNames(fIndex, ast, KIND_OTHER, binding); convertToCElements(project, fIndex, names, elems);