diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java index a2e41c70274..1c0ce140708 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java @@ -7,6 +7,7 @@ * * Contributors: * Andrew Ferguson (Symbian) - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; @@ -16,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexLinkage; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; @@ -63,6 +65,10 @@ public class EmptyIndexFragment implements IIndexFragment { return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; } + public IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, IndexFilter filter, IProgressMonitor monitor) { + return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY; + } + public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws CoreException { return IIndexFragmentInclude.EMPTY_FRAGMENT_INCLUDES_ARRAY; diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java index 2185abf19e8..3564fe548e9 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/IndexTypeInfo.java @@ -16,6 +16,7 @@ package org.eclipse.cdt.core.browser; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; @@ -27,9 +28,12 @@ import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; +import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.internal.core.browser.IndexTypeReference; @@ -50,6 +54,17 @@ import org.eclipse.core.runtime.Path; * */ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { + private static int hashCode(String[] array) { + int prime = 31; + if (array == null) + return 0; + int result = 1; + for (int index = 0; index < array.length; index++) { + result = prime * result + (array[index] == null ? 0 : array[index].hashCode()); + } + return result; + } + private final String[] fqn; private final int elementType; private final IIndex index; @@ -58,7 +73,7 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { private ITypeReference reference; // lazily constructed /** - * Creates a typeinfo suitable for the binding. + * Creates a type info suitable for the binding. * @param index a non-null index in which to locate references * @param binding * @since 4.0.1 @@ -93,6 +108,17 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { return new IndexTypeInfo(fqn, elementType, index); } + /** + * Creates a type info object suitable for a macro. + * @param index a non-null index in which to locate references + * @param binding + * @since 4.0.1 + */ + public static IndexTypeInfo create(IIndex index, IIndexMacro macro) { + final char[] name= macro.getName(); + return new IndexTypeInfo(new String[] {new String(name)}, ICElement.C_MACRO, index); + } + private IndexTypeInfo(String[] fqn, int elementType, IIndex index, String[] params, String returnType, ITypeReference reference) { Assert.isTrue(index != null); this.fqn= fqn; @@ -190,6 +216,9 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { public ITypeReference getResolvedReference() { if(reference==null) { + if (elementType == ICElement.C_MACRO) { + return createMacroReference(); + } try { index.acquireReadLock(); @@ -235,6 +264,29 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { return reference; } + private ITypeReference createMacroReference() { + try { + index.acquireReadLock(); + + IIndexMacro[] macros = index.findMacros(fqn[0].toCharArray(), IndexFilter.ALL_DECLARED, new NullProgressMonitor()); + if(macros.length>0) { + for (int i = 0; i < macros.length; i++) { + reference= createReference(macros[i]); + if (reference != null) { + break; + } + } + } + } catch(CoreException ce) { + CCorePlugin.log(ce); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } finally { + index.releaseReadLock(); + } + return reference; + } + private IndexTypeReference createReference(IIndexBinding binding, IIndexName indexName) throws CoreException { IIndexFileLocation ifl = indexName.getFile().getLocation(); String fullPath = ifl.getFullPath(); @@ -256,7 +308,32 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { return null; } + private IndexTypeReference createReference(IIndexMacro macro) throws CoreException { + IIndexFileLocation ifl = macro.getFile().getLocation(); + String fullPath = ifl.getFullPath(); + if (fullPath != null) { + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fullPath)); + if(file!=null) { + return new IndexTypeReference( + macro, file, file.getProject(), macro.getNodeOffset(), macro.getNodeLength() + ); + } + } else { + IPath path = URIUtil.toPath(ifl.getURI()); + if(path!=null) { + return new IndexTypeReference( + macro, path, null, macro.getNodeOffset(), macro.getNodeLength() + ); + } + } + return null; + } + public ITypeReference[] getReferences() { + if (elementType == ICElement.C_MACRO) { + return getMacroReferences(); + } + List references= new ArrayList(); try { index.acquireReadLock(); @@ -279,16 +356,51 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { return sameType; } }, new NullProgressMonitor()); + // in case a file is represented multiple times in the index then we take references from + // one of those, only. + HashMap iflMap= new HashMap(); for (int i = 0; i < ibs.length; i++) { IIndexBinding binding = ibs[i]; IIndexName[] names; names= index.findNames(binding, IIndex.FIND_DEFINITIONS); if (names.length == 0) { - names= index.findNames(ibs[0], IIndex.FIND_DECLARATIONS); + names= index.findNames(binding, IIndex.FIND_DECLARATIONS); } for (int j = 0; j < names.length; j++) { IIndexName indexName = names[j]; - IndexTypeReference ref= createReference(binding, indexName); + if (checkFile(iflMap, indexName.getFile())) { + IndexTypeReference ref= createReference(binding, indexName); + if (ref != null) { + references.add(ref); + } + } + } + } + } catch(CoreException ce) { + CCorePlugin.log(ce); + } catch (InterruptedException ie) { + CCorePlugin.log(ie); + } finally { + index.releaseReadLock(); + } + return (IndexTypeReference[]) references.toArray(new IndexTypeReference[references.size()]); + } + + + private ITypeReference[] getMacroReferences() { + List references= new ArrayList(); + try { + index.acquireReadLock(); + + char[] cfn= fqn[0].toCharArray(); + IIndexMacro[] ibs = index.findMacros(cfn, IndexFilter.ALL_DECLARED, new NullProgressMonitor()); + // in case a file is represented multiple times in the index then we take references from + // one of those, only. + HashMap iflMap= new HashMap(); + for (int i = 0; i < ibs.length; i++) { + IIndexMacro macro= ibs[i]; + if (checkFile(iflMap, macro.getFile())) { + IndexTypeReference ref= createReference(macro); if (ref != null) { references.add(ref); } @@ -304,6 +416,18 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { return (IndexTypeReference[]) references.toArray(new IndexTypeReference[references.size()]); } + /** + * Makes sure that per file only refs from one IIndexFile object are taken. + */ + private boolean checkFile(HashMap iflMap, IIndexFile file) throws CoreException { + IIndexFileLocation ifl= file.getLocation(); + IIndexFile otherFile= (IIndexFile) iflMap.get(ifl); + if (otherFile == null) { + iflMap.put(ifl, file); + return true; + } + return otherFile.equals(file); + } public ITypeInfo getRootNamespace(boolean includeGlobalNamespace) { throw new PDOMNotImplementedError(); @@ -383,4 +507,32 @@ public class IndexTypeInfo implements ITypeInfo, IFunctionInfo { return returnType; } + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + elementType; + result = prime * result + IndexTypeInfo.hashCode(fqn); + result = prime * result + IndexTypeInfo.hashCode(params); + return result; + } + + /** + * Type info objects are equal if they compute the same references. + */ + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + IndexTypeInfo other = (IndexTypeInfo) obj; + if (elementType != other.elementType) + return false; + if (!Arrays.equals(fqn, other.fqn)) + return false; + if (!Arrays.equals(params, other.params)) + return false; + return true; + } } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java index 6d78125c484..b950740a020 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/IndexTypeReference.java @@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.browser; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.browser.TypeReference; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory; @@ -43,7 +44,17 @@ public class IndexTypeReference extends TypeReference { super(resource, project, offset, length); fCElement= createCElement(binding); } + + public IndexTypeReference(IIndexMacro macro, IPath path, IProject project, int offset, int length) { + super(path, project, offset, length); + fCElement= createCElement(macro); + } + public IndexTypeReference(IIndexMacro macro, IResource resource, IProject project, int offset, int length) { + super(resource, project, offset, length); + fCElement= createCElement(macro); + } + /** * Compute the C element handle for the given binding. * @param binding @@ -62,6 +73,23 @@ public class IndexTypeReference extends TypeReference { return null; } + /** + * Compute the C element handle for the given macro. + */ + private ICElement createCElement(IIndexMacro macro) { + ITranslationUnit tu= getTranslationUnit(); + if (tu != null) { + long timestamp= tu.getResource() != null ? tu.getResource().getLocalTimeStamp() : 0; + IRegion region= new Region(getOffset(), getLength()); + try { + return CElementHandleFactory.create(tu, macro, region, timestamp); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + return null; + } + /* * @see org.eclipse.cdt.core.browser.ITypeReference#getCElements() */ diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java index faed1859837..fb7b880d10f 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/util/IndexModelUtil.java @@ -10,6 +10,7 @@ * IBM Corporation * Andrew Ferguson (Symbian) * Anton Leherbauer (Wind River Systems) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.browser.util; @@ -100,12 +101,16 @@ public class IndexModelUtil { if (binding instanceof ICompositeType) { ICompositeType classType = (ICompositeType) binding; try { - if(classType.getKey() == ICPPClassType.k_class) { + switch(classType.getKey()) { + case ICPPClassType.k_class: elementType = ICElement.C_CLASS; - } else if(classType.getKey() == ICPPClassType.k_struct) { + break; + case ICompositeType.k_struct: elementType = ICElement.C_STRUCT; - } else if(classType.getKey() == ICPPClassType.k_union) { + break; + case ICompositeType.k_union: elementType = ICElement.C_UNION; + break; } } catch(DOMException de) { CCorePlugin.log(de); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java index d54e6d818a9..7794c5e6afe 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.core.runtime.CoreException; @@ -55,7 +56,16 @@ public class CElementHandleFactory { return null; } } - + + public static ICElementHandle create(ITranslationUnit tu, IIndexMacro macro, + IRegion region, long timestamp) throws CoreException { + CElementHandle element= new MacroHandle(tu, macro); + if (element != null && region != null) { + element.setRangeOfID(region, timestamp); + } + return element; + } + public static ICElementHandle internalCreate(ITranslationUnit tu, IBinding binding, boolean definition, IRegion region, long timestamp) throws CoreException, DOMException { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/MacroHandle.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/MacroHandle.java new file mode 100644 index 00000000000..acf1f45f39a --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/MacroHandle.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2007 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.internal.core.model.ext; + +import org.eclipse.cdt.core.index.IIndexMacro; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IMacro; +import org.eclipse.cdt.core.model.ITranslationUnit; + +public class MacroHandle extends CElementHandle implements IMacro { + + public MacroHandle(ITranslationUnit tu, IIndexMacro macro) { + super(tu, ICElement.C_MACRO, new String(macro.getName())); + } + + public String getIdentifierList() { + return ""; //$NON-NLS-1$ + } + + public String getTokenSequence() { + return ""; //$NON-NLS-1$ + } +} 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 67c7d62bcc0..1f41022f51b 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 @@ -59,7 +59,7 @@ public interface IIndex { */ final int FIND_DEFINITIONS = 0x2; /** - * Constant to search for all declarations including definitons. + * Constant to search for all declarations including definitions. */ final int FIND_REFERENCES = 0x4; /** @@ -67,7 +67,7 @@ public interface IIndex { */ final int FIND_DECLARATIONS_DEFINITIONS = FIND_DECLARATIONS | FIND_DEFINITIONS; /** - * Constant to search for all occurrences of a binding. This includes declarations, definitons and references. + * Constant to search for all occurrences of a binding. This includes declarations, definitions and references. */ final int FIND_ALL_OCCURENCES = FIND_DECLARATIONS | FIND_DEFINITIONS | FIND_REFERENCES; @@ -185,6 +185,30 @@ public interface IIndex { */ public IIndexFile resolveInclude(IIndexInclude include) throws CoreException; + /** + * Searches for all macros with a given name. + * + * @param name a name, that has to be matched by the macros. + * @param filter a filter that allows for skipping parts of the index + * @param monitor a monitor to report progress, may be null. + * @return an array of macros matching the name. + * @throws CoreException + * @since 4.0.2 + */ + public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException; + + /** + * Searches for all macros with names that start with the given prefix. + * + * @param prefix the prefix with which all returned macros must start + * @param filter a filter that allows for skipping parts of the index + * @param monitor a monitor for progress reporting and cancellation, may be null + * @return an array of bindings with the prefix + * @throws CoreException + * @since 4.0.2 + */ + public IIndexMacro[] findMacrosForPrefix(char[] prefix, IndexFilter filter, IProgressMonitor monitor) throws CoreException; + /** * Searches for the binding of a name. The name may be originated by * an AST or by a search in an index. May return null. @@ -243,7 +267,7 @@ public interface IIndex { *
 	 * findBindings(new char[][]{name}, filter, monitor);
 	 * 
- * @param names an array of names, which has to be matched by the qualified name of the bindings. + * @param name a name, which has to be matched by the qualified name of the bindings. * @param filter a filter that allows for skipping parts of the index * @param monitor a monitor to report progress, may be null. * @return an array of bindings matching the pattern diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java index bba86032949..d762d594720 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexMacro.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.core.index; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.parser.IMacro; +import org.eclipse.core.runtime.CoreException; /** * Represents a macro stored in the index. @@ -30,11 +31,28 @@ import org.eclipse.cdt.core.parser.IMacro; */ public interface IIndexMacro extends IMacro { + IIndexMacro[] EMPTY_INDEX_MACRO_ARRAY = new IIndexMacro[0]; + /** * If available, return the file location for this macro definition * otherwise return null * @return */ IASTFileLocation getFileLocation(); + + /** + * Returns the file this macro belongs to. + * @throws CoreException + */ + IIndexFile getFile() throws CoreException; + + /** + * Returns the character offset of the location of the name. + */ + public int getNodeOffset(); + /** + * Returns the length of the name. + */ + public int getNodeLength(); } 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 37880f0dc44..33ce7860361 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 @@ -34,6 +34,7 @@ import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexInclude; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.dom.Linkage; @@ -486,7 +487,56 @@ public class CIndex implements IIndex { return flatten(result); } } + + public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException { + return findMacros(name, false, true, filter, monitor); + } + public IIndexMacro[] findMacrosForPrefix(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException { + return findMacros(name, true, false, filter, monitor); + } + + private IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, IndexFilter filter, IProgressMonitor monitor) throws CoreException { + if (SPECIALCASE_SINGLES && fFragments.length==1) { + try { + return fFragments[0].findMacros(name, isPrefix, caseSensitive, filter, monitor); + } catch (CoreException e) { + CCorePlugin.log(e); + return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY; + } + } else { + if (monitor == null) { + monitor= new NullProgressMonitor(); + } + List result = new ArrayList(); + HashSet handledIFLs= new HashSet(); + monitor.beginTask(Messages.CIndex_FindBindingsTask_label, fFragments.length); + for (int i = 0; i < fPrimaryFragmentCount; i++) { + HashSet allowedFiles= new HashSet(); + try { + IIndexMacro[] macros= fFragments[i].findMacros(name, isPrefix, caseSensitive, filter, new SubProgressMonitor(monitor, 1)); + for (int k = 0; k < macros.length; k++) { + IIndexMacro indexMacro = macros[k]; + IIndexFile file= indexMacro.getFile(); + if (!allowedFiles.contains(file)) { + if (handledIFLs.add(file.getLocation())) { + allowedFiles.add(file); + } + else { + continue; + } + } + result.add(indexMacro); + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + monitor.done(); + return (IIndexMacro[]) result.toArray(new IIndexMacro[result.size()]); + } + } + public long getCacheHits() { long result= 0; for (int i = 0; i < fFragments.length; i++) { 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 2e6205aa743..cc4d17df512 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 @@ -22,6 +22,7 @@ import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexInclude; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.core.runtime.CoreException; @@ -112,4 +113,12 @@ final public class EmptyCIndex implements IIndex { IProgressMonitor monitor) { return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; } + + public IIndexMacro[] findMacros(char[] name, IndexFilter filter, IProgressMonitor monitor) { + return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY; + } + + public IIndexMacro[] findMacrosForPrefix(char[] prefix, IndexFilter filter, IProgressMonitor monitor) { + return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY; + } } \ No newline at end of file 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 c79d3bf8407..6270560cfaa 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 @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexLinkage; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -176,6 +177,12 @@ public interface IIndexFragment { */ IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, IndexFilter filter, IProgressMonitor monitor) throws CoreException; + /** + * Returns all macros with the given prefix or name, accepted by the given filter + * @param monitor to report progress, may be null + */ + IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, IndexFilter filter, IProgressMonitor monitor) throws CoreException; + /** * Returns the linkages that are contained in this fragment * @return 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 65df7b909e0..dc90c237ee2 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 @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexLinkage; import org.eclipse.cdt.core.index.IIndexLocationConverter; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.index.IIndexFragment; @@ -51,11 +52,14 @@ import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.cdt.internal.core.pdom.dom.ApplyVisitor; import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector; +import org.eclipse.cdt.internal.core.pdom.dom.FindBinding; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory; +import org.eclipse.cdt.internal.core.pdom.dom.MacroCollector; 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; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMMacro; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -71,17 +75,16 @@ import org.eclipse.core.runtime.Status; * @author Doug Schaefer */ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { - protected Database db; - /** * Identifier for PDOM format * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_ID */ public static final String FRAGMENT_PROPERTY_VALUE_FORMAT_ID= "org.eclipse.cdt.internal.core.pdom.PDOM"; //$NON-NLS-1$ - public static final int CURRENT_VERSION = 37; + public static final int CURRENT_VERSION = 38; public static final int MIN_SUPPORTED_VERSION= 36; public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 4.1 + public static final int MIN_VERSION_TO_WRITE_MACROS_INDEX= 38; // to be removed in 4.1 /* * PDOM internal format history @@ -126,24 +129,33 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { * 35 - add scanner configuration hash-code (62366) * #36#- changed chunk size back to 4K (184892) - <> * #37#- added index for nested bindings (189811), compatible with version 36 - <> + * #38#- added btree for macros (193056), compatible with version 36 and 37 - <> */ public static final int LINKAGES = Database.DATA_AREA; public static final int FILE_INDEX = Database.DATA_AREA + 4; public static final int PROPERTIES = Database.DATA_AREA + 8; public static final int HAS_NESTED_BINDING_BTREES= Database.DATA_AREA + 12; - public static final int END= Database.DATA_AREA + 13; + public static final int HAS_MACRO_BTREES= Database.DATA_AREA + 13; + // 2-bytes of freedom + public static final int MACRO_BTREE= Database.DATA_AREA + 16; + public static final int END= Database.DATA_AREA + 20; static { assert END <= Database.CHUNK_SIZE; } // Local caches + protected Database db; private BTree fileIndex; + private BTree fMacroIndex= null; private Map fLinkageIDCache = new HashMap(); private File fPath; private IIndexLocationConverter locationConverter; private Map fPDOMLinkageFactoryCache; private boolean fHasBTreeForNestedBindings; + private boolean fHasBTreeForMacros; + private HashMap fResultCache= new HashMap(); + public PDOM(File dbPath, IIndexLocationConverter locationConverter, Map linkageFactoryMappings) throws CoreException { this(dbPath, locationConverter, ChunkCache.getSharedInstance(), linkageFactoryMappings); @@ -168,18 +180,28 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { db = new Database(fPath, cache, CURRENT_VERSION, isPermanentlyReadOnly()); fileIndex= null; // holds on to the database, so clear it. - + fMacroIndex= null; // same here + db.setLocked(lockDB); int version= db.getVersion(); if (version >= MIN_SUPPORTED_VERSION) { readLinkages(); fHasBTreeForNestedBindings= db.getByte(HAS_NESTED_BINDING_BTREES) == 1; + fHasBTreeForMacros= db.getByte(HAS_MACRO_BTREES) == 1; // new PDOM with version ready to write nested bindings index - if (version >= MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) { - if (!fHasBTreeForNestedBindings && !isPermanentlyReadOnly()) { - fHasBTreeForNestedBindings= true; - db.putByte(HAS_NESTED_BINDING_BTREES, (byte) 1); + if (!isPermanentlyReadOnly()) { + if (version >= MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) { + if (!fHasBTreeForNestedBindings) { + fHasBTreeForNestedBindings= true; + db.putByte(HAS_NESTED_BINDING_BTREES, (byte) 1); + } + } + if (version >= MIN_VERSION_TO_WRITE_MACROS_INDEX) { + if (!fHasBTreeForMacros) { + fHasBTreeForMacros= true; + db.putByte(HAS_MACRO_BTREES, (byte) 1); + } } } } @@ -281,7 +303,9 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { // Clear out the database, everything is set to zero. db.clear(CURRENT_VERSION); db.putByte(HAS_NESTED_BINDING_BTREES, (byte) 1); + db.putByte(HAS_MACRO_BTREES, (byte) 1); fHasBTreeForNestedBindings= true; + fHasBTreeForMacros= true; clearCaches(); } @@ -550,7 +574,6 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { private long lastWriteAccess= 0; private long lastReadAccess= 0; - private HashMap fResultCache= new HashMap(); public void acquireReadLock() throws InterruptedException { synchronized (mutex) { @@ -772,6 +795,37 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { return (IIndexFragmentBinding[]) result.toArray(new IIndexFragmentBinding[result.size()]); } + public IIndexMacro[] findMacros(char[] prefix, boolean isPrefix, boolean isCaseSensitive, IndexFilter filter, IProgressMonitor monitor) throws CoreException { + if (!fHasBTreeForMacros) { + return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY; + } + ArrayList result= new ArrayList(); + MacroCollector visitor = new MacroCollector(this, prefix, isPrefix, isCaseSensitive); + visitor.setMonitor(monitor); + try { + getMacroIndex().accept(visitor); + result.addAll(visitor.getMacroList()); + } + catch (OperationCanceledException e) { + } + return (IIndexMacro[]) result.toArray(new IIndexMacro[result.size()]); + } + + private BTree getMacroIndex() { + if (fMacroIndex == null) { + fMacroIndex= new BTree(db, MACRO_BTREE, new FindBinding.MacroBTreeComparator(this)); + } + return fMacroIndex; + } + + public void afterAddMacro(PDOMMacro macro) throws CoreException { + getMacroIndex().insert(macro.getRecord()); + } + + public void beforeRemoveMacro(PDOMMacro macro) throws CoreException { + getMacroIndex().delete(macro.getRecord()); + } + public String getProperty(String propertyName) throws CoreException { if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)) { return FRAGMENT_PROPERTY_VALUE_FORMAT_ID; @@ -789,6 +843,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { private void clearCaches() { fileIndex= null; + fMacroIndex= null; fLinkageIDCache.clear(); clearResultCache(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java index 3501b8471b8..1155b5c79ad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexLinkage; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; @@ -47,6 +48,13 @@ public class PDOMProxy implements IPDOM { } } + public IIndexMacro[] findMacros(char[] name, boolean isPrefix, boolean caseSensitive, + IndexFilter filter, IProgressMonitor monitor) throws CoreException { + if (fDelegate != null) + return fDelegate.findMacros(name, isPrefix, caseSensitive, filter, monitor); + return IIndexMacro.EMPTY_INDEX_MACRO_ARRAY; + } + public synchronized IIndexFragmentBinding adaptBinding(IBinding binding) throws CoreException { if (fDelegate != null) return fDelegate.adaptBinding(binding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java index 6abf7ebd893..ce2416b0102 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java @@ -65,7 +65,30 @@ public class FindBinding { return cmp; } } - + + public static class MacroBTreeComparator implements IBTreeComparator { + final private PDOM fPDom; + + public MacroBTreeComparator(PDOM pdom) { + fPDom= pdom; + } + public int compare(int record1, int record2) throws CoreException { + int cmp= compare(PDOMMacro.getNameInDB(fPDom, record1), PDOMMacro.getNameInDB(fPDom, record2)); // compare names + if (cmp==0) { // any order will do. + if (record1 < record2) { + return -1; + } + else if (record1 > record2) { + return 1; + } + } + return cmp; + } + private int compare(IString nameInDB, IString nameInDB2) throws CoreException { + return nameInDB.compareCompatibleWithIgnoreCase(nameInDB2); + } + } + public static PDOMBinding findBinding(BTree btree, final PDOM pdom, final char[]name, final int[] constants) throws CoreException { final PDOMBinding[] result = new PDOMBinding[1]; btree.accept(new IBTreeVisitor() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/MacroCollector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/MacroCollector.java new file mode 100644 index 00000000000..aff691a4972 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/MacroCollector.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2007 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 (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; +import org.eclipse.cdt.internal.core.pdom.db.IString; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; + +/** + * Visitor to find macros in a BTree. + * @since 4.0.2 + */ +public final class MacroCollector implements IBTreeVisitor { + private final PDOM pdom; + private final char[] name; + private final boolean prefixLookup; + private final boolean caseSensitive; + private IProgressMonitor monitor= null; + private int monitorCheckCounter= 0; + + private List macros = new ArrayList(); + + + /** + * Collects all nodes with given name, passing the filter. If prefixLookup is set to + * true a binding is considered if its name starts with the given prefix. + */ + public MacroCollector(PDOM pdom, char[] name, boolean prefixLookup, boolean caseSensitive) { + this.name= name; + this.pdom= pdom; + this.prefixLookup= prefixLookup; + this.caseSensitive= caseSensitive; + } + + /** + * Allows to cancel a visit. If set a visit may throw an OperationCancelledException. + * @since 4.0 + */ + public void setMonitor(IProgressMonitor pm) { + monitor= pm; + } + + final public int compare(int record) throws CoreException { + if (monitor != null) + checkCancelled(); + IString name= PDOMMacro.getNameInDB(pdom, record); + return compare(name); + } + + private int compare(IString rhsName) throws CoreException { + int cmp; + if (prefixLookup) { + cmp= rhsName.comparePrefix(name, false); + if(caseSensitive) { + cmp= cmp==0 ? rhsName.comparePrefix(name, true) : cmp; + } + return cmp; + } else { + if(caseSensitive) { + cmp= rhsName.compareCompatibleWithIgnoreCase(name); + } + else { + cmp= rhsName.compare(name, false); + } + } + return cmp; + } + + final public boolean visit(int record) throws CoreException { + if (monitor != null) + checkCancelled(); + + if (record == 0) + return true; + + macros.add(new PDOMMacro(pdom, record)); + return true; // look for more + } + + final public List getMacroList() { + return macros; + } + + private void checkCancelled() { + if (++monitorCheckCounter % 0x1000 == 0 && monitor.isCanceled()) { + throw new OperationCanceledException(); + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java index 551287fa8a4..9bc83bba622 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java @@ -203,6 +203,7 @@ public class PDOMFile implements IIndexFragmentFile { lastMacro.setNextMacro(pdomMacro); } lastMacro= pdomMacro; + pdom.afterAddMacro(pdomMacro); } } @@ -259,6 +260,7 @@ public class PDOMFile implements IIndexFragmentFile { // Delete all the macros in this file PDOMMacro macro = getFirstMacro(); while (macro != null) { + pdom.beforeRemoveMacro(macro); PDOMMacro nextMacro = macro.getNextMacro(); macro.delete(); macro = nextMacro; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java index e16c070667a..976830b49cb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java @@ -92,7 +92,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { } public void delete() throws CoreException { - getNameInDB().delete(); + getNameInDB(pdom, record).delete(); getExpansionInDB().delete(); PDOMMacroParameter param = getFirstParameter(); if (param != null) @@ -100,7 +100,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { pdom.getDB().free(record); } - public IString getNameInDB() throws CoreException { + public static IString getNameInDB(PDOM pdom, int record) throws CoreException { Database db = pdom.getDB(); int rec = db.getInt(record + NAME); return db.getString(rec); @@ -140,6 +140,15 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { public IASTFileLocation getFileLocation() { return PDOMMacro.this; } + public IIndexFile getFile() throws CoreException { + return PDOMMacro.this.getFile(); + } + public int getNodeOffset() { + return PDOMMacro.this.getNodeOffset(); + } + public int getNodeLength() { + return PDOMMacro.this.getNodeLength(); + } } private class FunctionStylePDOMMacro extends FunctionStyleMacro implements IIndexMacro { @@ -152,6 +161,15 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { public IASTFileLocation getFileLocation() { return PDOMMacro.this; } + public IIndexFile getFile() throws CoreException { + return PDOMMacro.this.getFile(); + } + public int getNodeOffset() { + return PDOMMacro.this.getNodeOffset(); + } + public int getNodeLength() { + return PDOMMacro.this.getNodeLength(); + } } private char[] getMacroExpansion() { @@ -169,7 +187,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { } private void rebuildMacro() throws CoreException { - char[] name = getNameInDB().getChars(); + char[] name = getNameInDB(pdom, record).getChars(); PDOMMacroParameter param = getFirstParameter(); if (param != null) { List paramList = new ArrayList(); @@ -205,12 +223,11 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation { public char[] getName() { try { - rebuildMacro(); + return getNameInDB(pdom, record).getChars(); } catch (CoreException e) { CCorePlugin.log(e); return new char[] { ' ' }; } - return macro.getName(); } public IIndexFile getFile() throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java index a6c8981ba70..df5e2811f87 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/export/GeneratePDOM.java @@ -80,9 +80,10 @@ public class GeneratePDOM implements ISafeRunnable { exportedPDOM.setProperty((String) entry.getKey(), (String) entry.getValue()); } } - // fake version of pdom, such that it works with CDT 4.0.0, also. - if (PDOM.CURRENT_VERSION == PDOM.MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX) { - exportedPDOM.getDB().setVersion(PDOM.CURRENT_VERSION-1); + // fake version of pdom, such that it works with CDT 4.0.0 and CDT 4.0.1, also. + // can be removed in CDT 5.0 + if (PDOM.CURRENT_VERSION == PDOM.MIN_VERSION_TO_WRITE_MACROS_INDEX) { + exportedPDOM.getDB().setVersion(PDOM.CURRENT_VERSION-2); } exportedPDOM.close(); } diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java index 9b673734650..dc2e36b715a 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/ElementSelectionDialog.java @@ -12,9 +12,8 @@ package org.eclipse.cdt.internal.ui.browser.opentype; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; +import java.util.HashSet; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -40,10 +39,13 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.browser.ITypeInfo; import org.eclipse.cdt.core.browser.IndexTypeInfo; import org.eclipse.cdt.core.browser.QualifiedTypeName; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; +import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog; import org.eclipse.cdt.internal.core.browser.util.IndexModelUtil; @@ -232,24 +234,40 @@ public class ElementSelectionDialog extends TypeSelectionDialog { if (monitor.isCanceled()) { return null; } - List types = new ArrayList(); + HashSet types = new HashSet(); if(prefix.length > 0 || fAllowEmptyPrefix) { + final IndexFilter filter= new IndexFilter() { + public boolean acceptBinding(IBinding binding) throws CoreException { + if (isVisibleType(IndexModelUtil.getElementType(binding))) { + if (IndexFilter.ALL_DECLARED.acceptBinding(binding)) { + // until we have correctly modeled file-local variables and functions, don't show them. + return !((IIndexBinding) binding).isFileLocal(); + } + } + return false; + } + }; try { IIndex index = CCorePlugin.getIndexManager().getIndex(CoreModel.getDefault().getCModel().getCProjects()); try { index.acquireReadLock(); - IIndexBinding[] bindings= index.findBindingsForPrefix(prefix, false, IndexFilter.ALL_DECLARED, monitor); + IIndexBinding[] bindings= index.findBindingsForPrefix(prefix, false, filter, monitor); for(int i=0; i