1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Bug 368045: Choose correct language for indexing files opened in editor.

This commit is contained in:
Markus Schorn 2012-01-11 12:19:38 +01:00
parent c55ca76edc
commit b68ecdc716
6 changed files with 90 additions and 42 deletions

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IndexFileLocation;
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.UnusedHeaderStrategy;
import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
import org.eclipse.cdt.internal.core.pdom.indexer.FileExistsCache;
import org.eclipse.cdt.utils.UNCPathConverter;
@ -178,7 +179,7 @@ public class StandaloneIndexerInputAdapter extends IndexerInputAdapter {
}
@Override
public AbstractLanguage[] getLanguages(Object tu, boolean bothForHeaders) {
public AbstractLanguage[] getLanguages(Object tu, UnusedHeaderStrategy strat) {
ILanguage language = fIndexer.getLanguageMapper().getLanguage(tu.toString());
if (language instanceof AbstractLanguage) {
return new AbstractLanguage[] {(AbstractLanguage) language};

View file

@ -71,12 +71,12 @@ import org.eclipse.osgi.util.NLS;
* @since 5.0
*/
public abstract class AbstractIndexerTask extends PDOMWriter {
protected static enum UnusedHeaderStrategy {
skip, useDefaultLanguage, useAlternateLanguage, useBoth
public static enum UnusedHeaderStrategy {
skip, useC, useCPP, useDefaultLanguage, useBoth
}
private static final int MAX_ERRORS = 500;
private static enum UpdateKind {REQUIRED_SOURCE, REQUIRED_HEADER, OTHER_HEADER}
private static enum UpdateKind {REQUIRED_SOURCE, REQUIRED_HEADER, ONE_LINKAGE_HEADER, OTHER_HEADER}
private static class LinkageTask {
final int fLinkageID;
private final Map<IIndexFileLocation, LocationTask> fLocationTasks;
@ -87,13 +87,19 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
}
boolean requestUpdate(IIndexFileLocation ifl, IIndexFragmentFile ifile, Object tu,
UpdateKind kind) {
UpdateKind kind, Map<IIndexFileLocation, LocationTask> oneLinkageTasks) {
LocationTask locTask= fLocationTasks.get(ifl);
if (locTask == null) {
locTask= new LocationTask();
fLocationTasks.put(ifl, locTask);
}
return locTask.requestUpdate(ifile, tu, kind);
boolean result = locTask.requestUpdate(ifile, tu, kind);
// Store one-linkage tasks.
if (kind == UpdateKind.ONE_LINKAGE_HEADER && locTask.fVersionTasks.isEmpty())
oneLinkageTasks.put(ifl, locTask);
return result;
}
LocationTask find(IIndexFileLocation ifl) {
@ -282,6 +288,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private List<LinkageTask> fRequestsPerLinkage= new ArrayList<LinkageTask>();
private Map<IIndexFile, IndexFileContent> fIndexContentCache= new LRUCache<IIndexFile, IndexFileContent>(500);
private Map<IIndexFileLocation, IIndexFile[]> fIndexFilesCache= new LRUCache<IIndexFileLocation, IIndexFile[]>(5000);
private Map<IIndexFileLocation, LocationTask> fOneLinkageTasks= new HashMap<IIndexFileLocation, AbstractIndexerTask.LocationTask>();
private Object[] fFilesToUpdate;
private List<Object> fFilesToRemove = new ArrayList<Object>();
@ -386,6 +393,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
* @return array of linkage IDs that shall be parsed
*/
protected int[] getLinkagesToParse() {
if (fIndexHeadersWithoutContext == UnusedHeaderStrategy.useCPP)
return PDOMManager.IDS_FOR_LINKAGES_TO_INDEX_C_FIRST;
return PDOMManager.IDS_FOR_LINKAGES_TO_INDEX;
}
@ -494,6 +503,11 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
final List<IIndexFileLocation> filesForLinkage = files.get(linkageID);
if (filesForLinkage != null) {
parseLinkage(linkageID, filesForLinkage, monitor);
for (Iterator<LocationTask> it = fOneLinkageTasks.values().iterator(); it.hasNext();) {
LocationTask task = it.next();
if (task.isCompleted())
it.remove();
}
fIndexContentCache.clear();
fIndexFilesCache.clear();
}
@ -569,7 +583,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
final boolean forceAll= (fUpdateFlags & IIndexManager.UPDATE_ALL) != 0;
final boolean checkTimestamps= (fUpdateFlags & IIndexManager.UPDATE_CHECK_TIMESTAMPS) != 0;
final boolean checkFileContentsHash = (fUpdateFlags & IIndexManager.UPDATE_CHECK_CONTENTS_HASH) != 0;
final boolean both = fIndexHeadersWithoutContext == UnusedHeaderStrategy.useBoth;
int count= 0;
int forceFirst= fForceNumberFiles;
BitSet linkages= new BitSet();
@ -585,28 +599,33 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
final IIndexFragmentFile[] indexFiles= fIndex.getWritableFiles(ifl);
final boolean isSourceUnit= fResolver.isSourceUnit(tu);
linkages.clear();
if (isRequiredInIndex(tu, ifl, isSourceUnit)) {
final boolean regularContent = isRequiredInIndex(tu, ifl, isSourceUnit);
final boolean indexedUnconditionally = fResolver.isIndexedUnconditionally(ifl);
if (regularContent || indexedUnconditionally) {
// Headers or sources required with a specific linkage
final UpdateKind updateKind = isSourceUnit ? UpdateKind.REQUIRED_SOURCE : UpdateKind.REQUIRED_HEADER;
AbstractLanguage[] langs= fResolver.getLanguages(tu, fIndexHeadersWithoutContext == UnusedHeaderStrategy.useBoth);
for (AbstractLanguage lang : langs) {
int linkageID = lang.getLinkageID();
boolean foundInLinkage = false;
for (int i = 0; i < indexFiles.length; i++) {
IIndexFragmentFile ifile = indexFiles[i];
if (ifile != null && ifile.getLinkageID() == linkageID && ifile.hasContent()) {
foundInLinkage = true;
indexFiles[i]= null; // Take the file.
boolean update= force || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
if (update && requestUpdate(linkageID, ifl, ifile, tu, updateKind)) {
count++;
linkages.set(linkageID);
final UpdateKind updateKind = isSourceUnit ? UpdateKind.REQUIRED_SOURCE
: regularContent && both ? UpdateKind.REQUIRED_HEADER : UpdateKind.ONE_LINKAGE_HEADER;
if (regularContent || indexFiles.length == 0) {
AbstractLanguage[] langs= fResolver.getLanguages(tu, fIndexHeadersWithoutContext);
for (AbstractLanguage lang : langs) {
int linkageID = lang.getLinkageID();
boolean foundInLinkage = false;
for (int i = 0; i < indexFiles.length; i++) {
IIndexFragmentFile ifile = indexFiles[i];
if (ifile != null && ifile.getLinkageID() == linkageID && ifile.hasContent()) {
foundInLinkage = true;
indexFiles[i]= null; // Take the file.
boolean update= force || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile);
if (update && requestUpdate(linkageID, ifl, ifile, tu, updateKind)) {
count++;
linkages.set(linkageID);
}
}
}
}
if (!foundInLinkage && requestUpdate(linkageID, ifl, null, tu, updateKind)) {
linkages.set(linkageID);
count++;
if (!foundInLinkage && requestUpdate(linkageID, ifl, null, tu, updateKind)) {
linkages.set(linkageID);
count++;
}
}
}
}
@ -615,7 +634,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
for (IIndexFragmentFile ifile : indexFiles) {
if (ifile != null) {
IIndexInclude ctx= ifile.getParsedInContext();
if (ctx == null && !fResolver.isIndexedUnconditionally(ifile.getLocation())) {
if (ctx == null && !indexedUnconditionally) {
iFilesToRemove.add(ifile);
count++;
} else {
@ -656,10 +675,6 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
if (fIndexHeadersWithoutContext != UnusedHeaderStrategy.skip)
return true;
// File required because it is open in the editor.
if (fResolver.isIndexedUnconditionally(ifl))
return true;
// Source file
if (isSourceUnit) {
if (fIndexFilesWithoutConfiguration || fResolver.isFileBuildConfigured(tu))
@ -689,7 +704,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
private boolean requestUpdate(int linkageID, IIndexFileLocation ifl, IIndexFragmentFile ifile, Object tu, UpdateKind kind) {
LinkageTask fileMap= createRequestMap(linkageID);
return fileMap.requestUpdate(ifl, ifile, tu, kind);
return fileMap.requestUpdate(ifl, ifile, tu, kind, fOneLinkageTasks);
}
private LinkageTask createRequestMap(int linkageID) {
@ -712,11 +727,13 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
@Override
protected void reportFileWrittenToIndex(FileInAST file, IIndexFragmentFile ifile) throws CoreException {
final FileContentKey fck = file.fFileContentKey;
final IIndexFileLocation location = fck.getLocation();
boolean wasCounted= false;
UpdateKind kind= UpdateKind.OTHER_HEADER;
LinkageTask map = findRequestMap(fck.getLinkageID());
LocationTask locTask= null;
if (map != null) {
LocationTask locTask = map.find(fck.getLocation());
locTask = map.find(location);
if (locTask != null) {
kind= locTask.fKind;
FileVersionTask v = locTask.findVersion(ifile);
@ -733,6 +750,21 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
}
fIndexContentCache.remove(ifile);
fIndexFilesCache.remove(file.fFileContentKey.getLocation());
LocationTask task= fOneLinkageTasks.remove(location);
if (task != null && task != locTask) {
if (task.fKind == UpdateKind.ONE_LINKAGE_HEADER && !task.isCompleted()) {
task.fKind= UpdateKind.OTHER_HEADER;
if (task.isCompleted()) {
if (!wasCounted) {
kind= UpdateKind.ONE_LINKAGE_HEADER;
wasCounted= true;
} else {
reportFile(wasCounted, UpdateKind.ONE_LINKAGE_HEADER);
}
}
}
}
reportFile(wasCounted, kind);
}
@ -989,7 +1021,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
}
private AbstractLanguage getLanguage(Object tu, int linkageID) {
for (AbstractLanguage language : fResolver.getLanguages(tu, true)) {
for (AbstractLanguage language : fResolver.getLanguages(tu, UnusedHeaderStrategy.useBoth)) {
if (language.getLinkageID() == linkageID) {
return language;
}

View file

@ -71,7 +71,7 @@ public abstract class IndexerInputAdapter extends ASTFilePathResolver {
/**
* Obtains the languages the input file should be parsed with.
*/
public abstract AbstractLanguage[] getLanguages(Object tu, boolean bothForHeaders);
public abstract AbstractLanguage[] getLanguages(Object tu, AbstractIndexerTask.UnusedHeaderStrategy strat);
/**
* Obtains the scanner configuration for the input file.

View file

@ -136,6 +136,9 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public static final int[] IDS_FOR_LINKAGES_TO_INDEX = {
ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID, ILinkage.FORTRAN_LINKAGE_ID
};
public static final int[] IDS_FOR_LINKAGES_TO_INDEX_C_FIRST = {
ILinkage.C_LINKAGE_ID, ILinkage.CPP_LINKAGE_ID, ILinkage.FORTRAN_LINKAGE_ID
};
private final LinkedList<ICProject> fProjectQueue= new LinkedList<ICProject>();
private final PDOMSetupJob fSetupJob;

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.model.CProject;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
import org.eclipse.cdt.internal.core.pdom.ITodoTaskUpdater;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
@ -80,10 +81,11 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
boolean i1= checkProperty(IndexerPreferences.KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG);
boolean i2= checkProperty(IndexerPreferences.KEY_INDEX_UNUSED_HEADERS_WITH_ALTERNATE_LANG);
UnusedHeaderStrategy strategy;
if (i1) {
strategy= i2 ? UnusedHeaderStrategy.useBoth : UnusedHeaderStrategy.useDefaultLanguage;
if (i1 == i2) {
strategy = i1 ? UnusedHeaderStrategy.useBoth : UnusedHeaderStrategy.skip;
} else {
strategy= i2 ? UnusedHeaderStrategy.useAlternateLanguage: UnusedHeaderStrategy.skip;
strategy = i1 == CProject.hasCCNature(getProject().getProject())
? UnusedHeaderStrategy.useCPP : UnusedHeaderStrategy.useC;
}
setIndexHeadersWithoutContext(strategy);
} else {

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.UnusedHeaderStrategy;
import org.eclipse.cdt.internal.core.pdom.IndexerInputAdapter;
import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy;
import org.eclipse.cdt.utils.UNCPathConverter;
@ -193,7 +194,7 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
}
@Override
public AbstractLanguage[] getLanguages(Object tuo, boolean bothForHeaders) {
public AbstractLanguage[] getLanguages(Object tuo, UnusedHeaderStrategy strategy) {
if (tuo instanceof PotentialTranslationUnit) {
if (fLangC != null) {
if (fLangCpp != null) {
@ -211,14 +212,23 @@ public class ProjectIndexerInputAdapter extends IndexerInputAdapter {
try {
ILanguage lang= tu.getLanguage();
if (lang instanceof AbstractLanguage) {
if (bothForHeaders && tu.isHeaderUnit()) {
final boolean both = strategy == UnusedHeaderStrategy.useBoth;
final boolean useC = strategy == UnusedHeaderStrategy.useC;
final boolean useCpp = strategy == UnusedHeaderStrategy.useCPP;
if ((both || useC || useCpp) && tu.isHeaderUnit()) {
String filename= tu.getElementName();
if (filename.indexOf('.') >= 0) {
final String contentTypeId= tu.getContentTypeId();
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) && fLangC != null) {
return new AbstractLanguage[] {(AbstractLanguage) lang, fLangC};
if (both)
return new AbstractLanguage[] {(AbstractLanguage) lang, fLangC};
if (useC)
return new AbstractLanguage[] {fLangC};
} else if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CHEADER) && fLangCpp != null) {
return new AbstractLanguage[] {(AbstractLanguage) lang, fLangCpp};
if (both)
return new AbstractLanguage[] {(AbstractLanguage) lang, fLangCpp};
if (useCpp)
return new AbstractLanguage[] {fLangCpp};
}
}
}