1
0
Fork 0
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:
Markus Schorn 2007-10-09 11:52:01 +00:00
parent 6d456f9e7e
commit 120cac7e45
9 changed files with 66 additions and 84 deletions

View file

@ -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();
}
}

View file

@ -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.

View file

@ -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;

View file

@ -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) {

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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());
}