mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Fix for 205555, NPE when SDK overlaps with project.
This commit is contained in:
parent
6d456f9e7e
commit
120cac7e45
9 changed files with 66 additions and 84 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <code>null</code> if there is
|
||||
* no writable fragment.
|
||||
*/
|
||||
IWritableIndexFragment getPrimaryWritableFragment();
|
||||
IWritableIndexFragment getWritableFragment();
|
||||
|
||||
/**
|
||||
* Flushes all caches to the disk.
|
||||
|
|
|
@ -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/*<String,IIndexFileLocation>*/());
|
||||
|
@ -112,6 +113,7 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory
|
|||
this.fileInfoCache = new HashMap/*<IIndexFileLocation,FileInfo>*/();
|
||||
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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue