From 120cac7e4541e338179a0430d8e79e7ea9ac88fd Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Tue, 9 Oct 2007 11:52:01 +0000 Subject: [PATCH] Fix for 205555, NPE when SDK overlaps with project. --- .../cdt/internal/core/index/CIndex.java | 14 +++- .../internal/core/index/IWritableIndex.java | 7 +- .../index/IndexBasedCodeReaderFactory.java | 18 ++++- .../cdt/internal/core/index/IndexFactory.java | 28 ++----- .../internal/core/index/WritableCIndex.java | 73 ++++++------------- .../core/indexer/StandaloneFastIndexer.java | 3 +- .../core/indexer/StandaloneFullIndexer.java | 3 +- .../cdt/internal/core/pdom/PDOMWriter.java | 2 +- .../core/pdom/indexer/PDOMRebuildTask.java | 2 +- 9 files changed, 66 insertions(+), 84 deletions(-) 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 5f8e2754ddd..37880f0dc44 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 @@ -17,6 +17,7 @@ package org.eclipse.cdt.internal.core.index; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -128,13 +129,18 @@ public class CIndex implements IIndex { } } } - // bug 192352, files can reside in multipe fragments, remove duplicates + // bug 192352, files can reside in multiple fragments, remove duplicates if (fragCount > 1) { - HashSet keys= new HashSet(); + HashMap fileMap= new HashMap(); for (Iterator iterator = result.iterator(); iterator.hasNext();) { final IIndexFragmentName name = (IIndexFragmentName) iterator.next(); - final String key= name.getFile().getLocation().getURI().toString() + name.getNodeOffset(); - if (!keys.add(key)) { + final IIndexFile file= name.getFile(); + final String fileKey= name.getFile().getLocation().getURI().toString(); + final IIndexFile otherFile= (IIndexFile) fileMap.get(fileKey); + if (otherFile == null) { + fileMap.put(fileKey, file); + } + else if (!otherFile.equals(file)) { // same file in another fragment iterator.remove(); } } 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 ff9b62acaa3..adcd7f76c82 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 @@ -40,6 +40,11 @@ public interface IWritableIndex extends IIndex { */ boolean isWritableFile(IIndexFragmentFile file); + /** + * Returns a writable file for the given location, or null. + */ + IIndexFragmentFile getWritableFile(IIndexFileLocation location) throws CoreException; + /** * Clears the given file in the index. * @param file a file to clear. @@ -102,7 +107,7 @@ public interface IWritableIndex extends IIndex { * Returns the primary writable fragment, or null if there is * no writable fragment. */ - IWritableIndexFragment getPrimaryWritableFragment(); + IWritableIndexFragment getWritableFragment(); /** * Flushes all caches to the disk. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java index b9a7a77c40d..5abd73481e4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexBasedCodeReaderFactory.java @@ -87,6 +87,7 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory private ICodeReaderFactory fFallBackFactory; private CallbackHandler fCallbackHandler; private final ICProject cproject; + private final String fProjectPathPrefix; public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index) { this(cproject, index, new HashMap/**/()); @@ -112,6 +113,7 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory this.fileInfoCache = new HashMap/**/(); this.iflCache = iflCache; this.fFallBackFactory= fallbackFactory; + this.fProjectPathPrefix= cproject == null ? null : '/' + cproject.getElementName() + '/'; } final protected Map getIFLCache() { @@ -230,7 +232,21 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(location); if (info == null) { info= new IndexFileInfo(); - info.fFile= file == null ? index.getFile(location) : file; + if (file != null) { + info.fFile= file; + } + else { + // bug 205555, in case a file of the project is also part of a read-only pdom, + // we prefer the writable pdom. + final String path= location.getFullPath(); + if (path != null && fProjectPathPrefix != null && + path.startsWith(fProjectPathPrefix) && index instanceof IWritableIndex) { + info.fFile= ((IWritableIndex) index).getWritableFile(location); + } + else { + info.fFile= index.getFile(location); + } + } fileInfoCache.put(location, info); } return info; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java index df53c36441d..c5f053fc7af 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java @@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.core.index; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -100,19 +99,15 @@ public class IndexFactory { } public IWritableIndex getWritableIndex(ICProject project) throws CoreException { - Collection selectedProjects= Collections.singleton(project); Map readOnlyFrag= new LinkedHashMap(); - Map fragments= new LinkedHashMap(); - for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { - ICProject cproject = (ICProject) iter.next(); - IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); - if (pdom != null) { - safeAddFragment(fragments, pdom); - safeAddProvidedFragments(cproject, readOnlyFrag); - } + IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(project); + if (pdom == null) { + throw new CoreException(CCorePlugin.createStatus( + MessageFormat.format(Messages.IndexFactory_errorNoSuchPDOM0, new Object[]{project.getElementName()}))); } - - selectedProjects= getProjects(new ICProject[] {project}, true, false, new HashMap(), new Integer(1)); + safeAddProvidedFragments(project, readOnlyFrag); + + Collection selectedProjects= getProjects(new ICProject[] {project}, true, false, new HashMap(), new Integer(1)); selectedProjects.remove(project); for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { @@ -120,15 +115,8 @@ public class IndexFactory { safeAddFragment(readOnlyFrag, fPDOMManager.getPDOM(cproject)); } - if (fragments.isEmpty()) { - throw new CoreException(CCorePlugin.createStatus( - MessageFormat.format(Messages.IndexFactory_errorNoSuchPDOM0, new Object[]{project.getElementName()}))); - } - - Collection pdoms= fragments.values(); Collection roPdoms= readOnlyFrag.values(); - return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]), - (IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) ); + return new WritableCIndex(pdom, (IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) ); } private Collection getProjects(ICProject[] projects, boolean addDependencies, boolean addDependent, HashMap map, Integer markWith) { 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 19bfe117578..7961948b1ef 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 @@ -21,39 +21,35 @@ import org.eclipse.core.runtime.CoreException; public class WritableCIndex extends CIndex implements IWritableIndex { - final private IWritableIndexFragment[] fWritableFragments; + final private IWritableIndexFragment fWritableFragment; private boolean fIsWriteLocked= false; - public WritableCIndex(IWritableIndexFragment[] writable, IIndexFragment[] readonly) { + public WritableCIndex(IWritableIndexFragment writable, IIndexFragment[] readonly) { super (concat(writable, readonly)); - fWritableFragments= writable; + fWritableFragment= writable; } - private static IIndexFragment[] concat(IIndexFragment[] writable, IIndexFragment[] readonly) { - IIndexFragment[] result= new IIndexFragment[writable.length + readonly.length]; - System.arraycopy(writable, 0, result, 0, writable.length); - System.arraycopy(readonly, 0, result, writable.length, readonly.length); + private static IIndexFragment[] concat(IIndexFragment writable, IIndexFragment[] readonly) { + IIndexFragment[] result= new IIndexFragment[1 + readonly.length]; + result[0]= writable; + System.arraycopy(readonly, 0, result, 1, readonly.length); return result; } - public IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException { - IWritableIndexFragment frag= selectFragment(fileLocation); - return frag.addFile(fileLocation); + public IWritableIndexFragment getWritableFragment() { + return fWritableFragment; } - - private IWritableIndexFragment selectFragment(IIndexFileLocation fileLocation) { - // todo handling of multiple writable indices - assert fWritableFragments.length == 1; - return fWritableFragments[0]; + + public IIndexFragmentFile getWritableFile(IIndexFileLocation location) throws CoreException { + return fWritableFragment.getFile(location); + } + + public IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException { + return fWritableFragment.addFile(fileLocation); } private boolean isWritableFragment(IIndexFragment frag) { - for (int i = 0; i < fWritableFragments.length; i++) { - if (fWritableFragments[i] == frag) { - return true; - } - } - return false; + return frag == fWritableFragment; } public void setFileContent(IIndexFragmentFile file, @@ -76,10 +72,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex { } public void clear() throws CoreException { - for (int i = 0; i < fWritableFragments.length; i++) { - IWritableIndexFragment frag = fWritableFragments[i]; - frag.clear(); - } + fWritableFragment.clear(); } public boolean isWritableFile(IIndexFragmentFile file) { @@ -111,22 +104,8 @@ public class WritableCIndex extends CIndex implements IWritableIndex { assert !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$ assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$ + fWritableFragment.acquireWriteLock(giveupReadlockCount); fIsWriteLocked= true; - int i= 0; - try { - for (i = 0; i < fWritableFragments.length; i++) { - fWritableFragments[i].acquireWriteLock(giveupReadlockCount); - } - } - finally { - if (i < fWritableFragments.length) { - // rollback - fIsWriteLocked= false; - while (--i >= 0) { - fWritableFragments[i].releaseWriteLock(giveupReadlockCount, false); - } - } - } } public synchronized void releaseWriteLock(int establishReadlockCount) { @@ -138,22 +117,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex { assert establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$ fIsWriteLocked= false; - for (int i = 0; i < fWritableFragments.length; i++) { - fWritableFragments[i].releaseWriteLock(establishReadlockCount, flush); - } + fWritableFragment.releaseWriteLock(establishReadlockCount, flush); } - public IWritableIndexFragment getPrimaryWritableFragment() { - return fWritableFragments.length > 0 ? fWritableFragments[0] : null; - } public void flush() throws CoreException { assert !fIsWriteLocked; - int i= 0; - for (i = 0; i < fWritableFragments.length; i++) { - fWritableFragments[i].flush(); - } + fWritableFragment.flush(); } - - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexer.java index ea19e4c5b04..a824a26c17a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFastIndexer.java @@ -21,7 +21,6 @@ import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.internal.core.index.IIndexFragment; -import org.eclipse.cdt.internal.core.index.IWritableIndexFragment; import org.eclipse.cdt.internal.core.index.WritableCIndex; import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.core.runtime.CoreException; @@ -55,7 +54,7 @@ public class StandaloneFastIndexer extends StandaloneIndexer{ IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log) throws CoreException { WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings); fIndex = new WritableCIndex( - new IWritableIndexFragment[] { pdom }, + pdom, new IIndexFragment[0]); fIndexAllFiles = false; fScanner = scanner; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java index e00de8a06a1..b8b730e497c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/indexer/StandaloneFullIndexer.java @@ -22,7 +22,6 @@ import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.internal.core.index.IIndexFragment; -import org.eclipse.cdt.internal.core.index.IWritableIndexFragment; import org.eclipse.cdt.internal.core.index.WritableCIndex; import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.core.runtime.CoreException; @@ -60,7 +59,7 @@ public class StandaloneFullIndexer extends StandaloneIndexer{ IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException { WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings); fIndex = new WritableCIndex( - new IWritableIndexFragment[] { pdom }, + pdom, new IIndexFragment[0]); fIndexAllFiles = false; fScanner = scanner; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java index 3a4ffd178ca..18268e6e9ac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java @@ -438,7 +438,7 @@ abstract public class PDOMWriter { private IIndexFragmentFile addToIndex(IWritableIndex index, IIndexFileLocation location, Map symbolMap, int configHash, Set contextIncludes) throws CoreException { Set clearedContexts= Collections.EMPTY_SET; - IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(location); + IIndexFragmentFile file= index.getWritableFile(location); if (file != null) { clearedContexts= new HashSet(); index.clearFile(file, clearedContexts); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java index 89d2fa70856..ddbb9c4b681 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMRebuildTask.java @@ -82,7 +82,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask { index.acquireWriteLock(0); try { index.clear(); - IWritableIndexFragment wf= index.getPrimaryWritableFragment(); + IWritableIndexFragment wf= index.getWritableFragment(); if (wf instanceof WritablePDOM) { PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject()); }