diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 9988f47fdfc..e4d889b39de 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; @@ -538,4 +539,69 @@ public class IndexBugsTests extends BaseTestCase { fIndex.releaseReadLock(); } } + + // class a {}; + // class A {}; + // namespace aa { + // class a { + // class e { + // class AA {class A{};}; + // }; + // }; + // }; + public void testFindBindingsWithPrefix() throws Exception { + waitForIndexer(); + String content= getContentsForTest(1)[0].toString(); + + IFile file= TestSourceReader.createFile(fCProject.getProject(), "testFBWP.cpp", content); + TestSourceReader.waitUntilFileIsIndexed(fIndex, file, INDEX_WAIT_TIME); + + fIndex.acquireReadLock(); + try { + final IndexFilter NON_FUNCTIONS = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return !(binding instanceof IFunction); + } + }; + + IBinding[] bindings= fIndex.findBindingsForPrefix(new char[] {'a'}, true, NON_FUNCTIONS); + assertEquals(3,bindings.length); + + bindings= fIndex.findBindingsForPrefix(new char[] {'a'}, false, NON_FUNCTIONS); + assertEquals(6,bindings.length); + + bindings= fIndex.findBindingsForPrefix(new char[] {'a','A'}, true, NON_FUNCTIONS); + assertEquals(1,bindings.length); + + bindings= fIndex.findBindingsForPrefix(new char[] {'a','A'}, false, NON_FUNCTIONS); + assertEquals(2, bindings.length); + } + finally { + fIndex.releaseReadLock(); + } + } + + // class a { class b { class c { void f(); }; }; }; + public void testFilterFindBindingsFQCharArray() throws Exception { + waitForIndexer(); + String content= getContentsForTest(1)[0].toString(); + + IFile file= TestSourceReader.createFile(fCProject.getProject(), "testFilterFindBindingsFQCharArray.cpp", content); + TestSourceReader.waitUntilFileIsIndexed(fIndex, file, INDEX_WAIT_TIME); + + fIndex.acquireReadLock(); + try { + final IndexFilter NON_CLASS = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return !(binding instanceof ICPPClassType); + } + }; + + IBinding[] bindings= fIndex.findBindings(new char[][]{{'a'},{'b'},{'c'},{'f'}}, NON_CLASS, NPM); + assertEquals(1,bindings.length); + } + finally { + fIndex.releaseReadLock(); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java index 6592ff40251..f65c6d01c74 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java @@ -254,11 +254,12 @@ public interface IIndex { /** * Searches for all bindings with names that start with the given prefix. * @param prefix the prefix with which all returned bindings must start + * @param filescope if true, only bindings at file scope are returned * @param filter a filter that allows for skipping parts of the index * @return an array of bindings with the prefix * @throws CoreException */ - public IIndexBinding[] findBindingsForPrefix(char[] prefix, IndexFilter filter, boolean caseSensitive) throws CoreException; + public IIndexBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter) throws CoreException; /** * Searches for all names that resolve to the given binding. You can limit the result to references, declarations diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index 06547624ab3..8768b76f324 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -1323,7 +1323,7 @@ public class CVisitor { IndexFilter filter = IndexFilter .getFilter(ILinkage.C_LINKAGE_ID); IBinding[] bindings = prefix ? index.findBindingsForPrefix( - name.toCharArray(), filter, false) : index.findBindings( + name.toCharArray(), true, filter) : index.findBindings( name.toCharArray(), filter, new NullProgressMonitor()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index f88932e2888..56042825b1d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -1046,7 +1046,7 @@ public class CPPSemantics { try { IndexFilter filter = IndexFilter.getFilter(ILinkage.CPP_LINKAGE_ID); IBinding[] bindings = data.prefixLookup ? - index.findBindingsForPrefix(data.astName.toCharArray(), filter, false) : + index.findBindingsForPrefix(data.astName.toCharArray(), true, filter) : index.findBindings(data.astName.toCharArray(), filter, new NullProgressMonitor()); mergeResults(data, bindings, true); useASTResults = false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java index 6b2cca1a420..256325a04be 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java @@ -430,9 +430,9 @@ public class CIndex implements IIndex { }; } - public IIndexBinding[] findBindingsForPrefix(char[] prefix, IndexFilter filter, boolean caseSensitive) throws CoreException { + public IIndexBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter) throws CoreException { if(SPECIALCASE_SINGLES && fFragments.length==1) { - return fFragments[0].findBindingsForPrefix(prefix, filter, caseSensitive); + return fFragments[0].findBindingsForPrefix(prefix, filescope, filter); } else { List result = new ArrayList(); ILinkage[] linkages = Linkage.getAllLinkages(); @@ -441,7 +441,7 @@ public class CIndex implements IIndex { IIndexFragmentBinding[][] fragmentBindings = new IIndexFragmentBinding[fPrimaryFragmentCount][]; for (int i = 0; i < fPrimaryFragmentCount; i++) { try { - IBinding[] part = fFragments[i].findBindingsForPrefix(prefix, retargetFilter(linkages[j], filter), caseSensitive); + IBinding[] part = fFragments[i].findBindingsForPrefix(prefix, filescope, retargetFilter(linkages[j], filter)); fragmentBindings[i] = new IIndexFragmentBinding[part.length]; System.arraycopy(part, 0, fragmentBindings[i], 0, part.length); } catch (CoreException e) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java index 5a13d8a15d4..713a8320d4b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java @@ -99,7 +99,7 @@ final public class EmptyCIndex implements IIndex { return null; } - public IIndexBinding[] findBindingsForPrefix(char[] prefix, IndexFilter filter, boolean caseSensitive) { + public IIndexBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter) { return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java index 3701b46c229..e2608bc0658 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java @@ -150,7 +150,7 @@ public interface IIndexFragment { /** * Returns all bindings with the given prefix, accepted by the given filter */ - IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, IndexFilter filter, boolean caseSensitive) throws CoreException; + IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter) throws CoreException; /** * Returns the linkages that are contained in this fragment diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index d0ced5db635..7968524e6db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -49,6 +49,7 @@ import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory; +import org.eclipse.cdt.internal.core.pdom.dom.ApplyVisitor; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; import org.eclipse.cdt.internal.core.pdom.dom.PDOMInclude; @@ -352,7 +353,8 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { bindings.add(linkage); for (int i=0; i < names.length; i++) { char[] name= names[i]; - BindingCollector collector= new BindingCollector(linkage, name, filter, false, true); + IndexFilter levelFilter= i==names.length-1 ? filter : IndexFilter.ALL; + BindingCollector collector= new BindingCollector(linkage, name, levelFilter, false, true); for (Iterator in = bindings.iterator(); in.hasNext();) { PDOMNode node= (PDOMNode) in.next(); node.accept(collector); @@ -608,12 +610,22 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { return fPath; } - public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, IndexFilter filter, boolean caseSensitive) throws CoreException { - ArrayList result = new ArrayList(); - for (Iterator iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { - PDOMLinkage linkage = (PDOMLinkage) iter.next(); + public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter) throws CoreException { + ArrayList result= new ArrayList(); + for (Iterator iter= fLinkageIDCache.values().iterator(); iter.hasNext();) { + PDOMLinkage linkage= (PDOMLinkage) iter.next(); if (filter.acceptLinkage(linkage)) { - IBinding[] bindings = linkage.findBindingsForPrefix(prefix, filter, caseSensitive); + IBinding[] bindings; + if(filescope) { + BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false); + linkage.accept(visitor); + bindings= visitor.getBindings(); + } else { + BindingCollector visitor = new BindingCollector(linkage, prefix, filter, true, false); + linkage.accept(visitor); + linkage.accept(new ApplyVisitor(linkage, visitor)); + bindings= visitor.getBindings(); + } for (int j = 0; j < bindings.length; j++) { result.add(bindings[j]); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/ApplyVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/ApplyVisitor.java new file mode 100644 index 00000000000..631ce68ceb0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/ApplyVisitor.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Systems 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: + * Andrew Ferguson (Symbian) - Initial implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom; + +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; +import org.eclipse.core.runtime.CoreException; + +/** + * Applies the specified visitor to the node being visited, and recursively to + * any nodes which act as containers + */ +public class ApplyVisitor implements IBTreeVisitor, IPDOMVisitor { + protected PDOMLinkage linkage; + protected IPDOMVisitor visitor; + + public ApplyVisitor(PDOMLinkage linkage, IPDOMVisitor visitor) { + this.linkage= linkage; + this.visitor= visitor; + } + + public int compare(int record) throws CoreException { + return 0; // visit all nodes in a b-tree + } + + public boolean visit(IPDOMNode node) throws CoreException { + if(node instanceof PDOMBinding) { + ((PDOMBinding)node).accept(visitor); + ((PDOMBinding)node).accept(this); + } + return false; // don't visit children of the node + } + + public boolean visit(int record) throws CoreException { + if (record == 0) + return true; + PDOMNode node= linkage.getNode(record); + if(node instanceof PDOMBinding) { + ((PDOMBinding)node).accept(visitor); + ((PDOMBinding)node).accept(this); + } + return true; + } + + public void leave(IPDOMNode node) throws CoreException { + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 6e38097372f..b1f5f3417c1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -32,7 +32,6 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexLinkage; -import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.index.IIndexScope; @@ -252,13 +251,6 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage protected abstract boolean isFileLocalBinding(IBinding binding) throws DOMException; public abstract int getBindingType(IBinding binding); - public IBinding[] findBindingsForPrefix(char[] prefix, IndexFilter filter, boolean caseSensitive) throws CoreException { - BindingCollector visitor = new BindingCollector(this, prefix, filter, true, caseSensitive); - getIndex().accept(visitor); - - return visitor.getBindings(); - } - /** * Callback informing the linkage that a name has been added. This is * used to do addtional processing, like establishing inheritance relationships. diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java index 403f105f25d..f6ef53ea053 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java @@ -78,7 +78,7 @@ public class OpenTypeDialog extends TypeSelectionDialog { IIndex index = CCorePlugin.getIndexManager().getIndex(CoreModel.getDefault().getCModel().getCProjects()); try { index.acquireReadLock(); - IBinding[] bindings= index.findBindingsForPrefix(prefix, IndexFilter.ALL, false); + IBinding[] bindings= index.findBindingsForPrefix(prefix, false, IndexFilter.ALL); for(int i=0; i