mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 14:15:23 +02:00
Improved cancellability of indexer.
Change-Id: I194e5b135f1f58501fb3345ca373feef23832c97
This commit is contained in:
parent
d4a911baa8
commit
260b6dadac
9 changed files with 204 additions and 105 deletions
|
@ -0,0 +1,33 @@
|
|||
package org.eclipse.cdt.internal.core.util;
|
||||
|
||||
/**
|
||||
* A thread-safe implementation of {@link ICanceler} interface.
|
||||
*/
|
||||
public class Canceler implements ICanceler {
|
||||
private ICancelable fCancelable;
|
||||
private boolean canceled;
|
||||
|
||||
@Override
|
||||
public synchronized void setCancelable(ICancelable cancelable) {
|
||||
fCancelable= cancelable;
|
||||
checkCanceled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setCanceled(boolean canceled) {
|
||||
this.canceled = canceled;
|
||||
checkCanceled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isCanceled() {
|
||||
return canceled;
|
||||
}
|
||||
|
||||
private synchronized void checkCanceled() {
|
||||
if (fCancelable != null && canceled) {
|
||||
fCancelable.cancel();
|
||||
fCancelable= null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,12 +16,24 @@ package org.eclipse.cdt.internal.core.util;
|
|||
* @since 5.0
|
||||
*/
|
||||
public interface ICanceler {
|
||||
|
||||
/**
|
||||
* Set the cancelable object.
|
||||
* Sets the cancelable object.
|
||||
*
|
||||
* @param cancelable the cancelable object
|
||||
*/
|
||||
void setCancelable(ICancelable cancelable);
|
||||
|
||||
public void setCancelable(ICancelable cancelable);
|
||||
|
||||
/**
|
||||
* Sets the cancel state to the given value. The state will be propagated to the cancelable object
|
||||
* if it was set.
|
||||
*
|
||||
* @param value {@code true} indicates that cancellation has been requested,
|
||||
* {@code false} clears this flag
|
||||
*/
|
||||
public void setCanceled(boolean value);
|
||||
|
||||
/**
|
||||
* Checks if cancellation has been requested.
|
||||
*/
|
||||
public boolean isCanceled();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,14 @@ public interface IPDOMIndexerTask {
|
|||
*/
|
||||
public void run(IProgressMonitor monitor) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Notifies the task that it should stop executing at its earliest convenience.
|
||||
* It's up to the task whether to react to this method or not.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @nooverride This default method is not intended to be re-implemented or extended by clients.
|
||||
*/
|
||||
public default void cancel() {}
|
||||
|
||||
/**
|
||||
* Returns the indexer the task belongs to.
|
||||
*/
|
||||
|
|
|
@ -62,7 +62,6 @@ import org.eclipse.cdt.core.parser.IScannerInfo;
|
|||
import org.eclipse.cdt.core.parser.ISignificantMacros;
|
||||
import org.eclipse.cdt.core.parser.IncludeExportPatterns;
|
||||
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
|
||||
import org.eclipse.cdt.internal.core.index.FileContentKey;
|
||||
|
@ -70,7 +69,9 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
|||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||
import org.eclipse.cdt.internal.core.index.IndexBasedFileContentProvider;
|
||||
import org.eclipse.cdt.internal.core.model.DebugLogConstants;
|
||||
import org.eclipse.cdt.internal.core.parser.IMacroDictionary;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserLogService;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserSettings2;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider.DependsOnOutdatedFileException;
|
||||
|
@ -80,8 +81,10 @@ import org.eclipse.core.runtime.CoreException;
|
|||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
|
@ -333,7 +336,6 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
private final Deque<AbstractIndexerTask> fUrgentTasks;
|
||||
boolean fTaskCompleted;
|
||||
private IndexerProgress fInfo= new IndexerProgress();
|
||||
private IProgressMonitor fProgressMonitor;
|
||||
|
||||
public AbstractIndexerTask(Object[] filesToUpdate, Object[] filesToRemove,
|
||||
IndexerInputAdapter resolver, boolean fastIndexer) {
|
||||
|
@ -448,7 +450,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
protected IParserLogService getLogService() {
|
||||
return ParserUtil.getParserLogService();
|
||||
return new ParserLogService(DebugLogConstants.PARSER, fCancelState);
|
||||
}
|
||||
|
||||
protected void logError(IStatus s) {
|
||||
|
@ -514,7 +516,6 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
public final void runTask(IProgressMonitor monitor) throws InterruptedException {
|
||||
fProgressMonitor = monitor;
|
||||
try {
|
||||
if (!fIndexFilesWithoutConfiguration) {
|
||||
fIndexHeadersWithoutContext= UnusedHeaderStrategy.skip;
|
||||
|
@ -538,22 +539,25 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
try {
|
||||
try {
|
||||
SubMonitor progress = SubMonitor.convert(monitor, 20);
|
||||
// Split into sources and headers, remove excluded sources.
|
||||
HashMap<Integer, List<IIndexFileLocation>> files= new HashMap<>();
|
||||
final ArrayList<IIndexFragmentFile> indexFilesToRemove= new ArrayList<>();
|
||||
extractFiles(files, indexFilesToRemove, monitor);
|
||||
extractFiles(files, indexFilesToRemove, progress.split(1));
|
||||
|
||||
setResume(true);
|
||||
setResume(true, progress.split(1));
|
||||
|
||||
// Remove files from index
|
||||
removeFilesInIndex(fFilesToRemove, indexFilesToRemove, monitor);
|
||||
removeFilesInIndex(fFilesToRemove, indexFilesToRemove, progress.split(1));
|
||||
|
||||
HashMap<Integer, List<IIndexFileLocation>> moreFiles= null;
|
||||
while (true) {
|
||||
for (int linkageID : getLinkagesToParse()) {
|
||||
int[] linkageIDs = getLinkagesToParse();
|
||||
progress.setWorkRemaining((linkageIDs.length + 2) * 2);
|
||||
for (int linkageID : linkageIDs) {
|
||||
final List<IIndexFileLocation> filesForLinkage = files.get(linkageID);
|
||||
if (filesForLinkage != null) {
|
||||
parseLinkage(linkageID, filesForLinkage, monitor);
|
||||
parseLinkage(linkageID, filesForLinkage, progress.split(1));
|
||||
for (Iterator<LocationTask> it = fOneLinkageTasks.values().iterator(); it.hasNext();) {
|
||||
LocationTask task = it.next();
|
||||
if (task.isCompleted())
|
||||
|
@ -598,13 +602,11 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
fForceNumberFiles = urgentTask.fForceNumberFiles;
|
||||
fFilesToRemove = urgentTask.fFilesToRemove;
|
||||
incrementRequestedFilesCount(fFilesToUpdate.length + fFilesToRemove.size());
|
||||
extractFiles(files, indexFilesToRemove, monitor);
|
||||
removeFilesInIndex(fFilesToRemove, indexFilesToRemove, monitor);
|
||||
extractFiles(files, indexFilesToRemove, progress.split(1));
|
||||
removeFilesInIndex(fFilesToRemove, indexFilesToRemove, progress.split(1));
|
||||
}
|
||||
}
|
||||
if (!monitor.isCanceled()) {
|
||||
setResume(false);
|
||||
}
|
||||
setResume(false, progress.split(1));
|
||||
} finally {
|
||||
fIndex.flush();
|
||||
}
|
||||
|
@ -617,12 +619,11 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
synchronized (this) {
|
||||
fTaskCompleted = true;
|
||||
}
|
||||
fProgressMonitor = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setResume(boolean value) throws InterruptedException, CoreException {
|
||||
fIndex.acquireWriteLock(fProgressMonitor);
|
||||
private void setResume(boolean value, IProgressMonitor monitor) throws InterruptedException, CoreException {
|
||||
fIndex.acquireWriteLock(monitor);
|
||||
try {
|
||||
fIndex.getWritableFragment().setProperty(IIndexFragment.PROPERTY_RESUME_INDEXER, String.valueOf(value));
|
||||
} finally {
|
||||
|
@ -640,10 +641,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
int count= 0;
|
||||
int forceFirst= fForceNumberFiles;
|
||||
BitSet linkages= new BitSet();
|
||||
SubMonitor progress = SubMonitor.convert(monitor, fFilesToUpdate.length);
|
||||
for (final Object tu : fFilesToUpdate) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
|
||||
progress.split(1);
|
||||
final boolean force= forceAll || --forceFirst >= 0;
|
||||
final IIndexFileLocation ifl= fResolver.resolveFile(tu);
|
||||
if (ifl == null)
|
||||
|
@ -828,12 +828,12 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
private void removeFilesInIndex(List<Object> filesToRemove, List<IIndexFragmentFile> indexFilesToRemove,
|
||||
IProgressMonitor monitor) throws InterruptedException, CoreException {
|
||||
if (!filesToRemove.isEmpty() || !indexFilesToRemove.isEmpty()) {
|
||||
fIndex.acquireWriteLock(fProgressMonitor);
|
||||
SubMonitor progress =
|
||||
SubMonitor.convert(monitor, 1 + filesToRemove.size() + indexFilesToRemove.size());
|
||||
fIndex.acquireWriteLock(progress.split(1));
|
||||
try {
|
||||
for (Object tu : filesToRemove) {
|
||||
if (monitor.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
progress.split(1);
|
||||
IIndexFileLocation ifl= fResolver.resolveFile(tu);
|
||||
if (ifl == null)
|
||||
continue;
|
||||
|
@ -844,9 +844,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
incrementRequestedFilesCount(-1);
|
||||
}
|
||||
for (IIndexFragmentFile ifile : indexFilesToRemove) {
|
||||
if (monitor.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
progress.split(1);
|
||||
fIndex.clearFile(ifile);
|
||||
incrementRequestedFilesCount(-1);
|
||||
}
|
||||
|
@ -863,6 +861,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (map == null || files == null || files.isEmpty())
|
||||
return;
|
||||
|
||||
SubMonitor progress = SubMonitor.convert(monitor, files.size() + 1);
|
||||
int maxPriority = Integer.MIN_VALUE;
|
||||
int minPriority = Integer.MAX_VALUE;
|
||||
Map<Integer, List<IIndexFileLocation>> filesByPriority = new HashMap<>();
|
||||
|
@ -893,11 +892,11 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (locTask == null || locTask.isCompleted()) {
|
||||
it.remove();
|
||||
} else if (locTask.fKind == UpdateKind.REQUIRED_SOURCE) {
|
||||
if (monitor.isCanceled() || hasUrgentTasks())
|
||||
if (hasUrgentTasks())
|
||||
return;
|
||||
final Object tu = locTask.fTu;
|
||||
final IScannerInfo scannerInfo = getScannerInfo(linkageID, tu);
|
||||
parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor);
|
||||
parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, progress.split(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -910,10 +909,10 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
} else {
|
||||
for (FileVersionTask versionTask : locTask.fVersionTasks) {
|
||||
if (versionTask.fOutdated) {
|
||||
if (monitor.isCanceled() || hasUrgentTasks())
|
||||
if (hasUrgentTasks())
|
||||
return;
|
||||
parseVersionInContext(linkageID, map, ifl, versionTask, locTask.fTu,
|
||||
new LinkedHashSet<IIndexFile>(), monitor);
|
||||
new LinkedHashSet<IIndexFile>(), progress.split(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -927,11 +926,11 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
it.remove();
|
||||
} else {
|
||||
if (locTask.needsVersion()) {
|
||||
if (monitor.isCanceled() || hasUrgentTasks())
|
||||
if (hasUrgentTasks())
|
||||
return;
|
||||
final Object tu = locTask.fTu;
|
||||
final IScannerInfo scannerInfo= getScannerInfo(linkageID, tu);
|
||||
parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor);
|
||||
parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, progress.split(1));
|
||||
if (locTask.isCompleted())
|
||||
it.remove();
|
||||
|
||||
|
@ -940,13 +939,14 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
// Delete remaining files.
|
||||
fIndex.acquireWriteLock(fProgressMonitor);
|
||||
fIndex.acquireWriteLock(progress.split(1));
|
||||
try {
|
||||
for (IIndexFileLocation ifl : filesAtPriority) {
|
||||
LocationTask locTask = map.find(ifl);
|
||||
if (locTask != null && !locTask.isCompleted()) {
|
||||
if (!locTask.needsVersion()) {
|
||||
if (monitor.isCanceled() || hasUrgentTasks())
|
||||
progress.split(1);
|
||||
if (hasUrgentTasks())
|
||||
return;
|
||||
Iterator<FileVersionTask> it= locTask.fVersionTasks.iterator();
|
||||
while (it.hasNext()) {
|
||||
|
@ -973,10 +973,12 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
IProgressMonitor monitor) throws CoreException, InterruptedException {
|
||||
final IIndexFragmentFile headerFile = versionTask.fIndexFile;
|
||||
|
||||
SubMonitor progress = SubMonitor.convert(monitor, 10);
|
||||
final int safeguardSize= safeGuard.size();
|
||||
while (true) {
|
||||
progress.setWorkRemaining(10);
|
||||
// Look for a context and parse the file.
|
||||
IIndexFragmentFile ctxFile = findContextFile(linkageID, map, versionTask, safeGuard, monitor);
|
||||
IIndexFragmentFile ctxFile = findContextFile(linkageID, map, versionTask, safeGuard, progress.split(1));
|
||||
if (ctxFile == null || ctxFile == headerFile)
|
||||
return;
|
||||
|
||||
|
@ -990,23 +992,25 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
Set<IIndexFile> dependencies= null;
|
||||
boolean done= false;
|
||||
while (!done) {
|
||||
progress.setWorkRemaining(9);
|
||||
done= true;
|
||||
DependsOnOutdatedFileException d= parseFile(tu, language, ifl, scannerInfo, ctx, monitor);
|
||||
DependsOnOutdatedFileException d= parseFile(tu, language, ifl, scannerInfo, ctx, progress.split(1));
|
||||
if (d != null) {
|
||||
// File was not parsed, because there is a dependency that needs to be
|
||||
// handled before.
|
||||
// File was not parsed, because there is a dependency that needs to be handled before.
|
||||
if (dependencies == null)
|
||||
dependencies= new HashSet<>();
|
||||
if (dependencies.add(d.fIndexFile)) {
|
||||
if (parseFile(d.fTu, language, d.fIndexFile.getLocation(), scannerInfo, new FileContext(ctxFile, d.fIndexFile), monitor) == null)
|
||||
if (parseFile(d.fTu, language, d.fIndexFile.getLocation(), scannerInfo,
|
||||
new FileContext(ctxFile, d.fIndexFile), progress.split(1)) == null) {
|
||||
done= false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ctx.fLostPragmaOnceSemantics)
|
||||
return;
|
||||
|
||||
// Try the next context
|
||||
// Try the next context.
|
||||
restoreSet(safeGuard, safeguardSize);
|
||||
}
|
||||
}
|
||||
|
@ -1057,9 +1061,10 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
// Handle the context first.
|
||||
parseVersionInContext(linkageID, map, ctxIfl, ctxVersionTask, ctxTask.fTu,
|
||||
safeGuard, monitor);
|
||||
if (ctxVersionTask.fOutdated // This is unexpected.
|
||||
|| !versionTask.fOutdated) // Our file was parsed.
|
||||
if (ctxVersionTask.fOutdated // This is unexpected.
|
||||
|| !versionTask.fOutdated) { // Our file was parsed.
|
||||
return null;
|
||||
}
|
||||
|
||||
// The file is no longer a context, look for a different one.
|
||||
nextCtx= ctxFile;
|
||||
|
@ -1070,8 +1075,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
private DependsOnOutdatedFileException parseFile(Object tu, AbstractLanguage lang,
|
||||
IIndexFileLocation ifl, IScannerInfo scanInfo, FileContext ctx, IProgressMonitor pm)
|
||||
IIndexFileLocation ifl, IScannerInfo scanInfo, FileContext ctx, IProgressMonitor monitor)
|
||||
throws CoreException, InterruptedException {
|
||||
SubMonitor progress = SubMonitor.convert(monitor, 21);
|
||||
boolean resultCacheCleared = false;
|
||||
IPath path= getLabel(ifl);
|
||||
Throwable th= null;
|
||||
|
@ -1079,14 +1085,15 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (fShowActivity) {
|
||||
trace("Indexer: parsing " + path.toOSString()); //$NON-NLS-1$
|
||||
}
|
||||
pm.subTask(getMessage(MessageKind.parsingFileTask,
|
||||
progress.subTask(getMessage(MessageKind.parsingFileTask,
|
||||
path.lastSegment(), path.removeLastSegments(1).toString()));
|
||||
FileContent codeReader= fResolver.getCodeReader(tu);
|
||||
final boolean isSource = fResolver.isSourceUnit(tu);
|
||||
|
||||
long start= System.currentTimeMillis();
|
||||
ASTTypeUtil.startTranslationUnit();
|
||||
IASTTranslationUnit ast= createAST(lang, codeReader, scanInfo, isSource, fASTOptions, ctx, pm);
|
||||
IASTTranslationUnit ast=
|
||||
createAST(lang, codeReader, scanInfo, isSource, fASTOptions, ctx, progress.split(10));
|
||||
fStatistics.fParsingTime += System.currentTimeMillis() - start;
|
||||
if (ast == null) {
|
||||
++fStatistics.fTooManyTokensCount;
|
||||
|
@ -1094,9 +1101,10 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
// Give the new AST a chance to recognize its translation unit before it is written
|
||||
// to the index.
|
||||
((ASTTranslationUnit) ast).setOriginatingTranslationUnit((ITranslationUnit) tu);
|
||||
writeToIndex(lang.getLinkageID(), ast, codeReader, ctx, pm);
|
||||
writeToIndex(lang.getLinkageID(), ast, codeReader, ctx, progress.split(10));
|
||||
resultCacheCleared = true; // The cache was cleared while writing to the index.
|
||||
}
|
||||
} catch (OperationCanceledException e) {
|
||||
} catch (RuntimeException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause instanceof DependsOnOutdatedFileException)
|
||||
|
@ -1118,7 +1126,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
if (!resultCacheCleared) {
|
||||
// If the result cache has not been cleared, clear it under a write lock to reduce
|
||||
// interference with index readers.
|
||||
fIndex.acquireWriteLock(fProgressMonitor);
|
||||
fIndex.acquireWriteLock(progress.split(1));
|
||||
try {
|
||||
fIndex.clearResultCache();
|
||||
} finally {
|
||||
|
@ -1197,7 +1205,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
private final IASTTranslationUnit createAST(AbstractLanguage language, FileContent codeReader,
|
||||
IScannerInfo scanInfo, boolean isSource, int options,
|
||||
FileContext ctx, IProgressMonitor pm) throws CoreException {
|
||||
FileContext ctx, IProgressMonitor monitor) throws CoreException {
|
||||
if (codeReader == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1233,8 +1241,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
|
||||
IASTTranslationUnit ast= language.getASTTranslationUnit(codeReader, scanInfo, fCodeReaderFactory,
|
||||
fIndex, options, getLogService());
|
||||
if (pm.isCanceled()) {
|
||||
return null;
|
||||
if (monitor.isCanceled()) {
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
@ -1248,7 +1256,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
private void writeToIndex(final int linkageID, IASTTranslationUnit ast, FileContent codeReader,
|
||||
FileContext ctx, IProgressMonitor pm) throws CoreException, InterruptedException {
|
||||
FileContext ctx, IProgressMonitor monitor) throws CoreException, InterruptedException {
|
||||
SubMonitor progress = SubMonitor.convert(monitor, 3);
|
||||
HashSet<FileContentKey> enteredFiles= new HashSet<>();
|
||||
ArrayList<FileInAST> orderedFileKeys= new ArrayList<>();
|
||||
|
||||
|
@ -1279,9 +1288,9 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
int storageLinkageID = process(ast, data);
|
||||
if (storageLinkageID != ILinkage.NO_LINKAGE_ID) {
|
||||
IASTComment[] comments = ast.getComments();
|
||||
data.fReplacementHeaders = extractReplacementHeaders(comments, pm);
|
||||
data.fReplacementHeaders = extractReplacementHeaders(comments, progress.split(1));
|
||||
|
||||
addSymbols(data, storageLinkageID, ctx, pm);
|
||||
addSymbols(data, storageLinkageID, ctx, progress.split(1));
|
||||
|
||||
// Update task markers.
|
||||
if (fTodoTaskUpdater != null) {
|
||||
|
@ -1294,11 +1303,13 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
// Contributed processors now have an opportunity to examine the AST.
|
||||
for (IPDOMASTProcessor processor : PDOMASTProcessorManager.getProcessors(ast)) {
|
||||
List<IPDOMASTProcessor> processors = PDOMASTProcessorManager.getProcessors(ast);
|
||||
progress.setWorkRemaining(processors.size());
|
||||
for (IPDOMASTProcessor processor : processors) {
|
||||
data = new PDOMWriter.Data(ast, fileKeys, fIndex);
|
||||
storageLinkageID = processor.process(ast, data);
|
||||
if (storageLinkageID != ILinkage.NO_LINKAGE_ID)
|
||||
addSymbols(data, storageLinkageID, ctx, pm);
|
||||
addSymbols(data, storageLinkageID, ctx, progress.split(1));
|
||||
}
|
||||
} catch (CoreException | RuntimeException | Error e) {
|
||||
// Avoid parsing files again, that caused an exception to be thrown.
|
||||
|
@ -1308,7 +1319,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
}
|
||||
|
||||
private void collectOrderedFileKeys(final int linkageID, IASTInclusionNode inclusion,
|
||||
HashSet<FileContentKey> enteredFiles, ArrayList<FileInAST> orderedFileKeys) throws CoreException {
|
||||
Set<FileContentKey> enteredFiles, List<FileInAST> orderedFileKeys) throws CoreException {
|
||||
final IASTPreprocessorIncludeStatement include= inclusion.getIncludeDirective();
|
||||
if (include.createsAST()) {
|
||||
final IIndexFileLocation ifl= fResolver.resolveASTPath(include.getPath());
|
||||
|
@ -1352,7 +1363,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
*
|
||||
* @return replacement headers keyed by file paths
|
||||
*/
|
||||
private Map<String, String> extractReplacementHeaders(IASTComment[] comments, IProgressMonitor pm) {
|
||||
private Map<String, String> extractReplacementHeaders(IASTComment[] comments, IProgressMonitor monitor) {
|
||||
Map<String, String> replacementHeaders = new HashMap<>();
|
||||
StringBuilder text = new StringBuilder();
|
||||
IASTFileLocation carryoverLocation = null;
|
||||
|
@ -1405,8 +1416,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
// include "header"
|
||||
if (text.charAt(matcher.end()) == ',' &&
|
||||
isWhitespace(text, matcher.end() + 1, text.length())) {
|
||||
// Defer processing until the next comment, which will be appended to this
|
||||
// one.
|
||||
// Defer processing until the next comment, which will be appended to this one.
|
||||
carryoverLocation = location;
|
||||
}
|
||||
}
|
||||
|
@ -1442,7 +1452,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
|||
return fc;
|
||||
}
|
||||
|
||||
IIndexFragmentFile selectIndexFile(int linkageID, IIndexFileLocation ifl, ISignificantMacros sigMacros) throws CoreException {
|
||||
IIndexFragmentFile selectIndexFile(int linkageID, IIndexFileLocation ifl, ISignificantMacros sigMacros)
|
||||
throws CoreException {
|
||||
LinkageTask map = findRequestMap(linkageID);
|
||||
if (map != null) {
|
||||
LocationTask locTask= map.find(ifl);
|
||||
|
|
|
@ -58,10 +58,14 @@ public class PDOMIndexerJob extends Job {
|
|||
@Override
|
||||
protected void canceling() {
|
||||
// Speed up cancellation by notifying the waiting thread.
|
||||
synchronized(this) {
|
||||
synchronized (this) {
|
||||
fCancelled= true;
|
||||
notify();
|
||||
}
|
||||
synchronized (taskMutex) {
|
||||
if (currentTask != null)
|
||||
currentTask.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,15 +163,7 @@ public class PDOMIndexerJob extends Job {
|
|||
}
|
||||
} while (currentTask != null);
|
||||
return Status.OK_STATUS;
|
||||
} catch (RuntimeException e) {
|
||||
CCorePlugin.log(e);
|
||||
pdomManager.cancelledIndexerJob(true);
|
||||
synchronized (taskMutex) {
|
||||
currentTask= null;
|
||||
taskMutex.notifyAll();
|
||||
}
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
} catch (RuntimeException | Error e) {
|
||||
CCorePlugin.log(e);
|
||||
pdomManager.cancelledIndexerJob(true);
|
||||
synchronized (taskMutex) {
|
||||
|
|
|
@ -67,11 +67,15 @@ import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
|
|||
import org.eclipse.cdt.internal.core.parser.scanner.LocationMap;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerASTVisitor;
|
||||
import org.eclipse.cdt.internal.core.util.Canceler;
|
||||
import org.eclipse.cdt.internal.core.util.ICanceler;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.MultiStatus;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
|
@ -203,6 +207,7 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
protected boolean fShowActivity;
|
||||
protected final IndexerStatistics fStatistics;
|
||||
protected final IndexerInputAdapter fResolver;
|
||||
protected final ICanceler fCancelState = new Canceler();
|
||||
|
||||
private int fSkipReferences= SKIP_NO_REFERENCES;
|
||||
|
||||
|
@ -256,7 +261,7 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
* the index after your last write operation.
|
||||
*/
|
||||
final protected void addSymbols(Data data, int storageLinkageID, FileContext ctx,
|
||||
IProgressMonitor pm) throws InterruptedException, CoreException {
|
||||
IProgressMonitor monitor) throws InterruptedException, CoreException {
|
||||
if (data.isEmpty() || storageLinkageID == ILinkage.NO_LINKAGE_ID)
|
||||
return;
|
||||
|
||||
|
@ -266,11 +271,12 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
fShowSyntaxProblems= true;
|
||||
}
|
||||
|
||||
SubMonitor progress = SubMonitor.convert(monitor, 2);
|
||||
// Name resolution.
|
||||
resolveNames(data, pm);
|
||||
resolveNames(data, progress.split(1));
|
||||
|
||||
// Index update.
|
||||
storeSymbolsInIndex(data, storageLinkageID, ctx, pm);
|
||||
storeSymbolsInIndex(data, storageLinkageID, ctx, progress.split(1));
|
||||
|
||||
if (!data.fStatuses.isEmpty()) {
|
||||
List<IStatus> statuses = data.fStatuses;
|
||||
|
@ -294,26 +300,24 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private void storeSymbolsInIndex(final Data data, int storageLinkageID, FileContext ctx, IProgressMonitor pm)
|
||||
throws InterruptedException, CoreException {
|
||||
private void storeSymbolsInIndex(final Data data, int storageLinkageID, FileContext ctx,
|
||||
IProgressMonitor monitor) throws InterruptedException, CoreException {
|
||||
final IIndexFragmentFile newFile= ctx == null ? null : ctx.fNewFile;
|
||||
SubMonitor progress = SubMonitor.convert(monitor, data.fSelectedFiles.length * 10);
|
||||
for (int i= 0; i < data.fSelectedFiles.length; i++) {
|
||||
if (pm.isCanceled())
|
||||
return;
|
||||
|
||||
final FileInAST fileInAST= data.fSelectedFiles[i];
|
||||
if (fileInAST != null) {
|
||||
if (fShowActivity) {
|
||||
trace("Indexer: adding " + fileInAST.fileContentKey.getLocation().getURI()); //$NON-NLS-1$
|
||||
}
|
||||
Throwable th= null;
|
||||
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, false, pm);
|
||||
YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, false, progress.split(1));
|
||||
lock.acquire();
|
||||
try {
|
||||
final boolean isReplacement= ctx != null && fileInAST.includeStatement == null;
|
||||
IIndexFragmentFile ifile= null;
|
||||
if (!isReplacement || newFile == null) {
|
||||
ifile= storeFileInIndex(data, fileInAST, storageLinkageID, lock);
|
||||
ifile= storeFileInIndex(data, fileInAST, storageLinkageID, lock, progress.split(9));
|
||||
reportFileWrittenToIndex(fileInAST, ifile);
|
||||
}
|
||||
|
||||
|
@ -321,8 +325,7 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
if (ifile == null)
|
||||
ifile= newFile;
|
||||
if (ctx != null && !ctx.fOldFile.equals(ifile) && ifile != null) {
|
||||
if (ctx.fOldFile.hasPragmaOnceSemantics() &&
|
||||
!ifile.hasPragmaOnceSemantics()) {
|
||||
if (ctx.fOldFile.hasPragmaOnceSemantics() && !ifile.hasPragmaOnceSemantics()) {
|
||||
data.fIndex.transferContext(ctx.fOldFile, ifile);
|
||||
ctx.fLostPragmaOnceSemantics= true;
|
||||
} else {
|
||||
|
@ -330,16 +333,11 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
th= e;
|
||||
} catch (StackOverflowError e) {
|
||||
th= e;
|
||||
} catch (AssertionError e) {
|
||||
} catch (RuntimeException | StackOverflowError | AssertionError e) {
|
||||
th= e;
|
||||
} finally {
|
||||
// Because the caller holds a read-lock, the result cache of the index is never
|
||||
// cleared. Before releasing the lock for the last time in this AST, we clear
|
||||
// the result cache.
|
||||
// Because the caller holds a read-lock, the result cache of the index is never cleared.
|
||||
// Before releasing the lock for the last time in this AST, we clear the result cache.
|
||||
if (i == data.fSelectedFiles.length - 1) {
|
||||
data.fIndex.clearResultCache();
|
||||
}
|
||||
|
@ -354,19 +352,19 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
private void resolveNames(Data data, IProgressMonitor pm) {
|
||||
private void resolveNames(Data data, IProgressMonitor monitor) {
|
||||
long start= System.currentTimeMillis();
|
||||
SubMonitor progress = SubMonitor.convert(monitor, data.fSelectedFiles.length);
|
||||
for (FileInAST file : data.fSelectedFiles) {
|
||||
if (pm.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
Symbols symbols= data.fSymbolMap.get(file.includeStatement);
|
||||
|
||||
final ArrayList<IASTName[]> names= symbols.fNames;
|
||||
SubMonitor progress2 = SubMonitor.convert(progress, names.size());
|
||||
boolean reported= false;
|
||||
for (Iterator<IASTName[]> j = names.iterator(); j.hasNext();) {
|
||||
final IASTName[] na= j.next();
|
||||
final IASTName name = na[0];
|
||||
progress2.split(1);
|
||||
if (name != null) { // should not be null, just be defensive.
|
||||
Throwable th= null;
|
||||
try {
|
||||
|
@ -467,8 +465,12 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
|
||||
// Names.
|
||||
final IndexerASTVisitor visitor = new IndexerASTVisitor((fSkipReferences & SKIP_IMPLICIT_REFERENCES) == 0) {
|
||||
private int cancelationCheckThrottler;
|
||||
|
||||
@Override
|
||||
public void visit(IASTName name, IASTName caller) {
|
||||
checkForCancellation();
|
||||
|
||||
if (fSkipReferences == SKIP_ALL_REFERENCES) {
|
||||
if (name.isReference()) {
|
||||
if (!isRequiredReference(name)) {
|
||||
|
@ -487,6 +489,16 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForCancellation() {
|
||||
if (cancelationCheckThrottler <= 0) {
|
||||
if (fCancelState.isCanceled())
|
||||
throw new OperationCanceledException();
|
||||
cancelationCheckThrottler = 1000;
|
||||
} else {
|
||||
cancelationCheckThrottler--;
|
||||
}
|
||||
}
|
||||
};
|
||||
ast.accept(visitor);
|
||||
|
||||
|
@ -558,7 +570,7 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
}
|
||||
|
||||
private IIndexFragmentFile storeFileInIndex(Data data, FileInAST astFile, int storageLinkageID,
|
||||
YieldableIndexLock lock) throws CoreException, InterruptedException {
|
||||
YieldableIndexLock lock, IProgressMonitor monitor) throws CoreException, InterruptedException {
|
||||
final IWritableIndex index = data.fIndex;
|
||||
IIndexFragmentFile file;
|
||||
// We create a temporary PDOMFile with zero timestamp, add names to it, then replace
|
||||
|
@ -686,4 +698,8 @@ public abstract class PDOMWriter implements IPDOMASTProcessor {
|
|||
protected IStatus createStatus(String msg, Throwable e) {
|
||||
return CCorePlugin.createStatus(msg, e);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
fCancelState.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,4 +137,10 @@ public class PDOMRebuildTask implements IPDOMIndexerTask {
|
|||
public synchronized boolean acceptUrgentTask(IPDOMIndexerTask task) {
|
||||
return fDelegate != null && fDelegate.acceptUrgentTask(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (fDelegate != null)
|
||||
fDelegate.cancel();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,6 +281,12 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
|
|||
}
|
||||
|
||||
public void setTranslationUnitSelection(List<? extends ICElement> filesAndFolders) {
|
||||
fFilesAndFolders= new ArrayList<ICElement>(filesAndFolders);
|
||||
fFilesAndFolders= new ArrayList<>(filesAndFolders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
if (fDelegate != null)
|
||||
fDelegate.cancel();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.eclipse.cdt.core.ICLogConstants;
|
|||
import org.eclipse.cdt.core.parser.AbstractParserLogService;
|
||||
import org.eclipse.cdt.internal.core.model.DebugLogConstants;
|
||||
import org.eclipse.cdt.internal.core.model.Util;
|
||||
import org.eclipse.cdt.internal.core.util.Canceler;
|
||||
import org.eclipse.cdt.internal.core.util.ICancelable;
|
||||
import org.eclipse.cdt.internal.core.util.ICanceler;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
@ -31,10 +32,12 @@ public class ParserLogService extends AbstractParserLogService implements ICance
|
|||
private final ICanceler fCanceler;
|
||||
|
||||
public ParserLogService(DebugLogConstants constant) {
|
||||
this(constant, null);
|
||||
this(constant, new Canceler());
|
||||
}
|
||||
|
||||
public ParserLogService(DebugLogConstants constant, ICanceler canceler) {
|
||||
if (canceler == null)
|
||||
throw new NullPointerException();
|
||||
topic = constant;
|
||||
if (CCorePlugin.getDefault() == null) {
|
||||
fIsTracingExceptions= false;
|
||||
|
@ -79,8 +82,16 @@ public class ParserLogService extends AbstractParserLogService implements ICance
|
|||
|
||||
@Override
|
||||
public void setCancelable(ICancelable cancelable) {
|
||||
if (fCanceler != null) {
|
||||
fCanceler.setCancelable(cancelable);
|
||||
}
|
||||
fCanceler.setCancelable(cancelable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCanceled(boolean value) {
|
||||
fCanceler.setCanceled(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCanceled() {
|
||||
return fCanceler.isCanceled();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue