From 208e4f68ef9c2723bdfe0264fe490bbfbdc58a14 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Tue, 24 Jul 2007 09:16:15 +0000 Subject: [PATCH] Fix and Testcase for 197311, Full Indexer with dependent project corrupts index. --- .../internal/index/tests/IndexBugsTests.java | 62 ++++++++++++++++++- .../internal/core/index/IWritableIndex.java | 21 ++++--- .../internal/core/index/WritableCIndex.java | 32 ++++++---- .../indexer/full/PDOMFullIndexerTask.java | 6 ++ 4 files changed, 101 insertions(+), 20 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 d73aca2e09d..731dcc7a4ce 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 @@ -750,7 +750,6 @@ public class IndexBugsTests extends BaseTestCase { // StructA_T gvar2; public void testFileInMultipleFragments_bug192352() throws Exception { StringBuffer[] contents= getContentsForTest(3); - ICProject p2 = CProjectHelper.createCCProject("__bugsTest_2_", "bin", IPDOMManager.ID_FAST_INDEXER); try { @@ -833,4 +832,65 @@ public class IndexBugsTests extends BaseTestCase { index.releaseReadLock(); } } + + // int globalVar; + + // #include "../__bugsTest__/common.h" + // void func() { + // globalVar++; + // } + public void testDependentProjectsWithFullIndexer_Bug197311() throws Exception { + StringBuffer[] contents= getContentsForTest(2); + final IIndexManager indexManager = CCorePlugin.getIndexManager(); + indexManager.setIndexerId(fCProject, IPDOMManager.ID_FULL_INDEXER); + ICProject p2 = CProjectHelper.createCCProject("bug197311", "bin", IPDOMManager.ID_FULL_INDEXER); + IProject[] refs = new IProject[] {fCProject.getProject()}; + IProjectDescription pd = p2.getProject().getDescription(); + pd.setReferencedProjects(refs); + p2.getProject().setDescription(pd, new NullProgressMonitor()); + try { + IFile f1= TestSourceReader.createFile(fCProject.getProject(), "common.h", contents[0].toString()); + IFile f2= TestSourceReader.createFile(fCProject.getProject(), "src.cpp", contents[1].toString()); + IFile f3= TestSourceReader.createFile(p2.getProject(), "src.cpp", contents[1].toString()); + waitForIndexer(); + + IIndex index= indexManager.getIndex(p2, IIndexManager.ADD_DEPENDENCIES); + index.acquireReadLock(); + try { + IIndexBinding[] bindings= index.findBindings("globalVar".toCharArray(), IndexFilter.ALL, NPM); + assertEquals(1, bindings.length); + IIndexBinding binding= bindings[0]; + IIndexName[] names= index.findReferences(binding); + assertEquals(2, names.length); + names= index.findDeclarations(binding); + assertEquals(1, names.length); + } + finally { + index.releaseReadLock(); + } + + indexManager.reindex(p2); + waitForIndexer(); + + index= indexManager.getIndex(p2, IIndexManager.ADD_DEPENDENCIES); + index.acquireReadLock(); + try { + IIndexBinding[] bindings= index.findBindings("globalVar".toCharArray(), IndexFilter.ALL, NPM); + assertEquals(1, bindings.length); + IIndexBinding binding= bindings[0]; + IIndexName[] names= index.findReferences(binding); + assertEquals(2, names.length); + names= index.findDeclarations(binding); + assertEquals(1, names.length); + } + finally { + index.releaseReadLock(); + } + } + finally { + CProjectHelper.delete(p2); + } + + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java index ab99788e608..ff9b62acaa3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndex.java @@ -34,6 +34,19 @@ public interface IWritableIndex extends IIndex { public IIndexFragmentFile fTargetFile; public boolean fIsContext= false; } + + /** + * Checks whether the given file can be written to in this index. + */ + boolean isWritableFile(IIndexFragmentFile file); + + /** + * Clears the given file in the index. + * @param file a file to clear. + * @param a collection that receives IndexFileLocation objects for files that + * had the cleared file as a context. May be null. + */ + void clearFile(IIndexFragmentFile file, Collection clearedContexts) throws CoreException; /** * Creates a file object for the given location or returns an existing one. @@ -52,14 +65,6 @@ public interface IWritableIndex extends IIndex { */ void clear() throws CoreException; - /** - * Clears the given file in the index. - * @param file a file to clear. - * @param a collection that receives IndexFileLocation objects for files that - * had the cleared file as a context. May be null. - */ - void clearFile(IIndexFragmentFile file, Collection clearedContexts) throws CoreException; - /** * Acquires a write lock, while giving up a certain amount of read locks. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java index 8e5cc2abc4e..19bfe117578 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/WritableCIndex.java @@ -61,15 +61,18 @@ public class WritableCIndex extends CIndex implements IWritableIndex { IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException { IIndexFragment indexFragment = file.getIndexFragment(); - assert isWritableFragment(indexFragment); - - for (int i = 0; i < includes.length; i++) { - IncludeInformation ii= includes[i]; - if (ii.fLocation != null) { - ii.fTargetFile= addFile(ii.fLocation); - } + if (!isWritableFragment(indexFragment)) { + assert false : "Attempt to update file of read-only fragment"; //$NON-NLS-1$ + } + else { + for (int i = 0; i < includes.length; i++) { + IncludeInformation ii= includes[i]; + if (ii.fLocation != null) { + ii.fTargetFile= addFile(ii.fLocation); + } + } + ((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names); } - ((IWritableIndexFragment) indexFragment).addFileContent(file, includes, macros, names); } public void clear() throws CoreException { @@ -79,11 +82,18 @@ public class WritableCIndex extends CIndex implements IWritableIndex { } } + public boolean isWritableFile(IIndexFragmentFile file) { + return isWritableFragment(file.getIndexFragment()); + } + public void clearFile(IIndexFragmentFile file, Collection clearedContexts) throws CoreException { IIndexFragment indexFragment = file.getIndexFragment(); - assert isWritableFragment(indexFragment); - - ((IWritableIndexFragment) indexFragment).clearFile(file, clearedContexts); + if (!isWritableFragment(indexFragment)) { + assert false : "Attempt to clear file of read-only fragment"; //$NON-NLS-1$ + } + else { + ((IWritableIndexFragment) indexFragment).clearFile(file, clearedContexts); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java index 682f3eb225d..04a4482638b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullIndexerTask.java @@ -33,6 +33,7 @@ import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; +import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndex; import org.eclipse.cdt.internal.core.index.IWritableIndexManager; import org.eclipse.cdt.internal.core.pdom.indexer.PDOMIndexerTask; @@ -173,6 +174,11 @@ class PDOMFullIndexerTask extends PDOMIndexerTask { Object required= filePathsToParse.get(location); if (required == null) { required= MISSING; + // bug 197311, don't attempt to update files in fragments of other projects. + IIndexFragmentFile file= (IIndexFragmentFile) fIndex.getFile(location); + if (file != null && !fIndex.isWritableFile(file)) { + required= SKIP; + } filePathsToParse.put(location, required); } else if (confighash != 0 && required == REQUIRED_IF_CONFIG_CHANGED) {