From 4e149fbde7841935336ee794a5df78d0f3422dc0 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 2 Mar 2009 15:50:43 +0000 Subject: [PATCH] API to check whether a declaration is from a file actually included by a translation unit, bug 254844. --- .../internal/index/tests/IndexBugsTests.java | 40 +++++++++++++++++++ .../cdt/core/dom/ast/IASTTranslationUnit.java | 28 ++++++++----- .../eclipse/cdt/core/index/IIndexFileSet.java | 11 ++++- .../core/index/IIndexFragmentFileSet.java | 5 +++ .../cdt/internal/core/index/IndexFileSet.java | 12 ++++++ .../cdt/internal/core/pdom/PDOMFileSet.java | 7 ++++ 6 files changed, 92 insertions(+), 11 deletions(-) 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 daea1485b70..864f2c532d4 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 @@ -50,6 +50,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; 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.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexManager; @@ -1675,4 +1676,43 @@ public class IndexBugsTests extends BaseTestCase { fIndex.releaseReadLock(); } } + + // int a; + + // #include "a.h" + // void test() {a=0;} + public void testDeclarationForBinding_Bug254844() throws Exception { + String[] contents= getContentsForTest(2); + final IIndexManager indexManager = CCorePlugin.getIndexManager(); + IFile a= TestSourceReader.createFile(fCProject.getProject(), "a.h", contents[0]); + IFile b= TestSourceReader.createFile(fCProject.getProject(), "b.h", contents[0]); + IFile source= TestSourceReader.createFile(fCProject.getProject(), "source.cpp", contents[1]); + indexManager.reindex(fCProject); + waitForIndexer(); + ITranslationUnit tu= (ITranslationUnit) CoreModel.getDefault().create(source); + fIndex.acquireReadLock(); + try { + IASTTranslationUnit ast= tu.getAST(fIndex, ITranslationUnit.AST_SKIP_INDEXED_HEADERS); + IIndexFileSet fileset= ast.getIndexFileSet(); + IBinding var= getBindingFromASTName(ast, contents[1], "a=", 1, IBinding.class); + IName[] decls= ast.getDeclarations(var); + assertEquals(2, decls.length); + int check= 0; + for (int i = 0; i < decls.length; i++) { + IName name = decls[i]; + assert name instanceof IIndexName; + IIndexName iName= (IIndexName) name; + if (iName.getFileLocation().getFileName().endsWith("a.h")) { + check |= 1; + assertTrue(fileset.contains(iName.getFile())); + } else { + check |= 2; + assertFalse(fileset.contains(iName.getFile())); + } + } + assertEquals(3, check); + } finally { + fIndex.releaseReadLock(); + } + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index 52b3621f251..bd76544f166 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.core.dom.ast; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.core.runtime.IAdaptable; @@ -244,11 +245,13 @@ public interface IASTTranslationUnit extends IASTNode, IASTDeclarationListOwner, public IIndex getIndex(); /** - * Set the Index to be used for this translation unit. - * - * @param index + * Return the set of files that have been skipped because they have been part of the index + * prior to creating this AST, or null if not available. + * Applies only, if AST was created with an index and the option to skip headers found in the + * index. + * @since 5.1 */ - public void setIndex(IIndex index); + IIndexFileSet getIndexFileSet(); /** * In case the ast was created in a way that supports comment parsing, @@ -271,11 +274,6 @@ public interface IASTTranslationUnit extends IASTNode, IASTDeclarationListOwner, */ public boolean isHeaderUnit(); - /** - * Sets whether this ast represents a header file. - */ - public void setIsHeaderUnit(boolean headerUnit); - /** * Returns the node factory that was used to build the AST. * @@ -283,6 +281,18 @@ public interface IASTTranslationUnit extends IASTNode, IASTDeclarationListOwner, * @since 5.1 */ public INodeFactory getASTNodeFactory(); + + /** + * Set the Index to be used for this translation unit. + * @noreference This method is not intended to be referenced by clients. + */ + public void setIndex(IIndex index); + + /** + * Sets whether this ast represents a header file. + * @noreference This method is not intended to be referenced by clients. + */ + public void setIsHeaderUnit(boolean headerUnit); /** * Causes this node and all the nodes rooted at this node to become immutable. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFileSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFileSet.java index 0ded38106af..aa82e44da17 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFileSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexFileSet.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.core.index; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.internal.core.index.IndexFileSet; +import org.eclipse.core.runtime.CoreException; /** * File set for index files. Can be used to filter file-local bindings. @@ -22,15 +23,21 @@ import org.eclipse.cdt.internal.core.index.IndexFileSet; public interface IIndexFileSet { IIndexFileSet EMPTY = new IndexFileSet(); + /** + * Returns whether the given file is part of this file set. + * @since 5.1 + */ + boolean contains(IIndexFile file) throws CoreException; + /** * Returns an array of bindings where all local bindings that are not part of this file-set * have been removed. */ - IBinding[] filterFileLocalBindings(IBinding[] bindings); + IBinding[] filterFileLocalBindings(IBinding[] bindings); /** * Adds a file to this set. - * @param indexFile + * @noreference This method is not intended to be referenced by clients. */ void add(IIndexFile indexFile); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFileSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFileSet.java index 95da81bee1d..30d0b3347ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFileSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragmentFileSet.java @@ -24,4 +24,9 @@ public interface IIndexFragmentFileSet { * Adds the fragment file to the file-set. */ void add(IIndexFragmentFile fragFile); + + /** + * Returns whether the file set contains the given file. + */ + boolean contains(IIndexFragmentFile file) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java index 9240373c0e4..78220069169 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFileSet.java @@ -79,4 +79,16 @@ public class IndexFileSet implements IIndexFileSet { } return result; } + + public boolean contains(IIndexFile file) throws CoreException { + if (!(file instanceof IIndexFragmentFile)) + return false; + + IIndexFragmentFile ifile= (IIndexFragmentFile) file; + IIndexFragmentFileSet subSet= fSubSets.get(ifile.getIndexFragment()); + if (subSet != null) { + return subSet.contains(ifile); + } + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMFileSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMFileSet.java index defa010f95f..66e1a214146 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMFileSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMFileSet.java @@ -32,4 +32,11 @@ public class PDOMFileSet implements IIndexFragmentFileSet { PDOMBinding pdomBinding= (PDOMBinding) fb; return fFileIDs.contains(pdomBinding.getLocalToFileRec()); } + + public boolean contains(IIndexFragmentFile file) throws CoreException { + if (file instanceof PDOMFile) { + return fFileIDs.contains(((PDOMFile) file).getRecord()); + } + return false; + } }