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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
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) {
|
if (fragCount > 1) {
|
||||||
HashSet keys= new HashSet();
|
HashMap fileMap= new HashMap();
|
||||||
for (Iterator iterator = result.iterator(); iterator.hasNext();) {
|
for (Iterator iterator = result.iterator(); iterator.hasNext();) {
|
||||||
final IIndexFragmentName name = (IIndexFragmentName) iterator.next();
|
final IIndexFragmentName name = (IIndexFragmentName) iterator.next();
|
||||||
final String key= name.getFile().getLocation().getURI().toString() + name.getNodeOffset();
|
final IIndexFile file= name.getFile();
|
||||||
if (!keys.add(key)) {
|
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();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,11 @@ public interface IWritableIndex extends IIndex {
|
||||||
*/
|
*/
|
||||||
boolean isWritableFile(IIndexFragmentFile file);
|
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.
|
* Clears the given file in the index.
|
||||||
* @param file a file to clear.
|
* @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
|
* Returns the primary writable fragment, or <code>null</code> if there is
|
||||||
* no writable fragment.
|
* no writable fragment.
|
||||||
*/
|
*/
|
||||||
IWritableIndexFragment getPrimaryWritableFragment();
|
IWritableIndexFragment getWritableFragment();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes all caches to the disk.
|
* Flushes all caches to the disk.
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory
|
||||||
private ICodeReaderFactory fFallBackFactory;
|
private ICodeReaderFactory fFallBackFactory;
|
||||||
private CallbackHandler fCallbackHandler;
|
private CallbackHandler fCallbackHandler;
|
||||||
private final ICProject cproject;
|
private final ICProject cproject;
|
||||||
|
private final String fProjectPathPrefix;
|
||||||
|
|
||||||
public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index) {
|
public IndexBasedCodeReaderFactory(ICProject cproject, IIndex index) {
|
||||||
this(cproject, index, new HashMap/*<String,IIndexFileLocation>*/());
|
this(cproject, index, new HashMap/*<String,IIndexFileLocation>*/());
|
||||||
|
@ -112,6 +113,7 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory
|
||||||
this.fileInfoCache = new HashMap/*<IIndexFileLocation,FileInfo>*/();
|
this.fileInfoCache = new HashMap/*<IIndexFileLocation,FileInfo>*/();
|
||||||
this.iflCache = iflCache;
|
this.iflCache = iflCache;
|
||||||
this.fFallBackFactory= fallbackFactory;
|
this.fFallBackFactory= fallbackFactory;
|
||||||
|
this.fProjectPathPrefix= cproject == null ? null : '/' + cproject.getElementName() + '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected Map getIFLCache() {
|
final protected Map getIFLCache() {
|
||||||
|
@ -230,7 +232,21 @@ public class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory
|
||||||
IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(location);
|
IndexFileInfo info= (IndexFileInfo) fileInfoCache.get(location);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
info= new IndexFileInfo();
|
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);
|
fileInfoCache.put(location, info);
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
|
|
|
@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.core.index;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -100,19 +99,15 @@ public class IndexFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWritableIndex getWritableIndex(ICProject project) throws CoreException {
|
public IWritableIndex getWritableIndex(ICProject project) throws CoreException {
|
||||||
Collection selectedProjects= Collections.singleton(project);
|
|
||||||
Map readOnlyFrag= new LinkedHashMap();
|
Map readOnlyFrag= new LinkedHashMap();
|
||||||
Map fragments= new LinkedHashMap();
|
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(project);
|
||||||
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
|
if (pdom == null) {
|
||||||
ICProject cproject = (ICProject) iter.next();
|
throw new CoreException(CCorePlugin.createStatus(
|
||||||
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
|
MessageFormat.format(Messages.IndexFactory_errorNoSuchPDOM0, new Object[]{project.getElementName()})));
|
||||||
if (pdom != null) {
|
|
||||||
safeAddFragment(fragments, pdom);
|
|
||||||
safeAddProvidedFragments(cproject, readOnlyFrag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
safeAddProvidedFragments(project, readOnlyFrag);
|
||||||
selectedProjects= getProjects(new ICProject[] {project}, true, false, new HashMap(), new Integer(1));
|
|
||||||
|
Collection selectedProjects= getProjects(new ICProject[] {project}, true, false, new HashMap(), new Integer(1));
|
||||||
selectedProjects.remove(project);
|
selectedProjects.remove(project);
|
||||||
|
|
||||||
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
|
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
|
||||||
|
@ -120,15 +115,8 @@ public class IndexFactory {
|
||||||
safeAddFragment(readOnlyFrag, fPDOMManager.getPDOM(cproject));
|
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();
|
Collection roPdoms= readOnlyFrag.values();
|
||||||
return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]),
|
return new WritableCIndex(pdom, (IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) );
|
||||||
(IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection getProjects(ICProject[] projects, boolean addDependencies, boolean addDependent, HashMap map, Integer markWith) {
|
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 {
|
public class WritableCIndex extends CIndex implements IWritableIndex {
|
||||||
|
|
||||||
final private IWritableIndexFragment[] fWritableFragments;
|
final private IWritableIndexFragment fWritableFragment;
|
||||||
private boolean fIsWriteLocked= false;
|
private boolean fIsWriteLocked= false;
|
||||||
|
|
||||||
public WritableCIndex(IWritableIndexFragment[] writable, IIndexFragment[] readonly) {
|
public WritableCIndex(IWritableIndexFragment writable, IIndexFragment[] readonly) {
|
||||||
super (concat(writable, readonly));
|
super (concat(writable, readonly));
|
||||||
fWritableFragments= writable;
|
fWritableFragment= writable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IIndexFragment[] concat(IIndexFragment[] writable, IIndexFragment[] readonly) {
|
private static IIndexFragment[] concat(IIndexFragment writable, IIndexFragment[] readonly) {
|
||||||
IIndexFragment[] result= new IIndexFragment[writable.length + readonly.length];
|
IIndexFragment[] result= new IIndexFragment[1 + readonly.length];
|
||||||
System.arraycopy(writable, 0, result, 0, writable.length);
|
result[0]= writable;
|
||||||
System.arraycopy(readonly, 0, result, writable.length, readonly.length);
|
System.arraycopy(readonly, 0, result, 1, readonly.length);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException {
|
public IWritableIndexFragment getWritableFragment() {
|
||||||
IWritableIndexFragment frag= selectFragment(fileLocation);
|
return fWritableFragment;
|
||||||
return frag.addFile(fileLocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IWritableIndexFragment selectFragment(IIndexFileLocation fileLocation) {
|
public IIndexFragmentFile getWritableFile(IIndexFileLocation location) throws CoreException {
|
||||||
// todo handling of multiple writable indices
|
return fWritableFragment.getFile(location);
|
||||||
assert fWritableFragments.length == 1;
|
}
|
||||||
return fWritableFragments[0];
|
|
||||||
|
public IIndexFragmentFile addFile(IIndexFileLocation fileLocation) throws CoreException {
|
||||||
|
return fWritableFragment.addFile(fileLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWritableFragment(IIndexFragment frag) {
|
private boolean isWritableFragment(IIndexFragment frag) {
|
||||||
for (int i = 0; i < fWritableFragments.length; i++) {
|
return frag == fWritableFragment;
|
||||||
if (fWritableFragments[i] == frag) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFileContent(IIndexFragmentFile file,
|
public void setFileContent(IIndexFragmentFile file,
|
||||||
|
@ -76,10 +72,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() throws CoreException {
|
public void clear() throws CoreException {
|
||||||
for (int i = 0; i < fWritableFragments.length; i++) {
|
fWritableFragment.clear();
|
||||||
IWritableIndexFragment frag = fWritableFragments[i];
|
|
||||||
frag.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isWritableFile(IIndexFragmentFile file) {
|
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 !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$
|
||||||
assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
fWritableFragment.acquireWriteLock(giveupReadlockCount);
|
||||||
fIsWriteLocked= true;
|
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) {
|
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$
|
assert establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
||||||
|
|
||||||
fIsWriteLocked= false;
|
fIsWriteLocked= false;
|
||||||
for (int i = 0; i < fWritableFragments.length; i++) {
|
fWritableFragment.releaseWriteLock(establishReadlockCount, flush);
|
||||||
fWritableFragments[i].releaseWriteLock(establishReadlockCount, flush);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWritableIndexFragment getPrimaryWritableFragment() {
|
|
||||||
return fWritableFragments.length > 0 ? fWritableFragments[0] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void flush() throws CoreException {
|
public void flush() throws CoreException {
|
||||||
assert !fIsWriteLocked;
|
assert !fIsWriteLocked;
|
||||||
int i= 0;
|
fWritableFragment.flush();
|
||||||
for (i = 0; i < fWritableFragments.length; i++) {
|
|
||||||
fWritableFragments[i].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.IParserLogService;
|
||||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
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.index.WritableCIndex;
|
||||||
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
@ -55,7 +54,7 @@ public class StandaloneFastIndexer extends StandaloneIndexer{
|
||||||
IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log) throws CoreException {
|
IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log) throws CoreException {
|
||||||
WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings);
|
WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings);
|
||||||
fIndex = new WritableCIndex(
|
fIndex = new WritableCIndex(
|
||||||
new IWritableIndexFragment[] { pdom },
|
pdom,
|
||||||
new IIndexFragment[0]);
|
new IIndexFragment[0]);
|
||||||
fIndexAllFiles = false;
|
fIndexAllFiles = false;
|
||||||
fScanner = scanner;
|
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.IParserLogService;
|
||||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
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.index.WritableCIndex;
|
||||||
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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 {
|
IScannerInfo scanner, ILanguageMapper mapper, IParserLogService log, ICodeReaderFactory codeReaderFactory) throws CoreException {
|
||||||
WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings);
|
WritablePDOM pdom = new WritablePDOM(writableIndexFile, converter, linkageFactoryMappings);
|
||||||
fIndex = new WritableCIndex(
|
fIndex = new WritableCIndex(
|
||||||
new IWritableIndexFragment[] { pdom },
|
pdom,
|
||||||
new IIndexFragment[0]);
|
new IIndexFragment[0]);
|
||||||
fIndexAllFiles = false;
|
fIndexAllFiles = false;
|
||||||
fScanner = scanner;
|
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 {
|
private IIndexFragmentFile addToIndex(IWritableIndex index, IIndexFileLocation location, Map symbolMap, int configHash, Set contextIncludes) throws CoreException {
|
||||||
Set clearedContexts= Collections.EMPTY_SET;
|
Set clearedContexts= Collections.EMPTY_SET;
|
||||||
IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(location);
|
IIndexFragmentFile file= index.getWritableFile(location);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
clearedContexts= new HashSet();
|
clearedContexts= new HashSet();
|
||||||
index.clearFile(file, clearedContexts);
|
index.clearFile(file, clearedContexts);
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
|
||||||
index.acquireWriteLock(0);
|
index.acquireWriteLock(0);
|
||||||
try {
|
try {
|
||||||
index.clear();
|
index.clear();
|
||||||
IWritableIndexFragment wf= index.getPrimaryWritableFragment();
|
IWritableIndexFragment wf= index.getWritableFragment();
|
||||||
if (wf instanceof WritablePDOM) {
|
if (wf instanceof WritablePDOM) {
|
||||||
PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject());
|
PDOMManager.writeProjectPDOMProperties((WritablePDOM) wf, project.getProject());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue