@Override protected void reportFileWrittenToIndex(FileInAST file, IIndexFragmentFile ifile) throws CoreException { final FileContentKey fck = file.fileContentKey; final IIndexFileLocation location = fck.getLocation(); boolean wasCounted = false; UpdateKind kind = UpdateKind.OTHER_HEADER; LinkageTask map = findRequestMap(fck.getLinkageID()); LocationTask locTask = null; if (map != null) { locTask = map.find(location); if (locTask != null) { kind = locTask.fKind; FileVersionTask v = locTask.findVersion(ifile); if (v != null) { wasCounted = v.fOutdated; v.setUpdated(); } else { // We have added a version, the request is fulfilled. wasCounted = locTask.fCountedUnknownVersion; locTask.fCountedUnknownVersion = false; } locTask.fStoredAVersion = true; } } fIndexContentCache.remove(ifile); fIndexFilesCache.remove(file.fileContentKey.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); }
private void parseLinkage(int linkageID, List<IIndexFileLocation> files, IProgressMonitor monitor) throws CoreException, InterruptedException { LinkageTask map = findRequestMap(linkageID); if (map == null || files == null || files.isEmpty()) return; // First parse the required sources for (Iterator<IIndexFileLocation> it = files.iterator(); it.hasNext(); ) { IIndexFileLocation ifl = it.next(); LocationTask locTask = map.find(ifl); if (locTask == null || locTask.isCompleted()) { it.remove(); } else if (locTask.fKind == UpdateKind.REQUIRED_SOURCE) { if (monitor.isCanceled() || hasUrgentTasks()) return; final Object tu = locTask.fTu; final IScannerInfo scannerInfo = getScannerInfo(linkageID, tu); parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor); } } // Files with context for (Iterator<IIndexFileLocation> it = files.iterator(); it.hasNext(); ) { IIndexFileLocation ifl = it.next(); LocationTask locTask = map.find(ifl); if (locTask == null || locTask.isCompleted()) { it.remove(); } else { for (FileVersionTask versionTask : locTask.fVersionTasks) { if (versionTask.fOutdated) { if (monitor.isCanceled() || hasUrgentTasks()) return; parseVersionInContext( linkageID, map, ifl, versionTask, locTask.fTu, new LinkedHashSet<IIndexFile>(), monitor); } } } } // Files without context for (Iterator<IIndexFileLocation> it = files.iterator(); it.hasNext(); ) { IIndexFileLocation ifl = it.next(); LocationTask locTask = map.find(ifl); if (locTask == null || locTask.isCompleted()) { it.remove(); } else { if (locTask.needsVersion()) { if (monitor.isCanceled() || hasUrgentTasks()) return; final Object tu = locTask.fTu; final IScannerInfo scannerInfo = getScannerInfo(linkageID, tu); parseFile(tu, getLanguage(tu, linkageID), ifl, scannerInfo, null, monitor); if (locTask.isCompleted()) it.remove(); } } } // Delete remaining files. fIndex.acquireWriteLock(); try { for (IIndexFileLocation ifl : files) { LocationTask locTask = map.find(ifl); if (locTask != null && !locTask.isCompleted()) { if (!locTask.needsVersion()) { if (monitor.isCanceled() || hasUrgentTasks()) return; Iterator<FileVersionTask> it = locTask.fVersionTasks.iterator(); while (it.hasNext()) { FileVersionTask v = it.next(); if (v.fOutdated) { fIndex.clearFile(v.fIndexFile); reportFile(true, locTask.fKind); locTask.removeVersionTask(it); fIndexContentCache.remove(v.fIndexFile); fIndexFilesCache.remove(ifl); } } } } } } finally { fIndex.releaseWriteLock(); } }
public final void runTask(IProgressMonitor monitor) throws InterruptedException { try { if (!fIndexFilesWithoutConfiguration) { fIndexHeadersWithoutContext = UnusedHeaderStrategy.skip; } fIndex = createIndex(); if (fIndex == null) { return; } fTodoTaskUpdater = createTodoTaskUpdater(); fASTOptions = ILanguage.OPTION_NO_IMAGE_LOCATIONS | ILanguage.OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS; if (getSkipReferences() == SKIP_ALL_REFERENCES) { fASTOptions |= ILanguage.OPTION_SKIP_FUNCTION_BODIES; } fIndex.resetCacheCounters(); fIndex.acquireReadLock(); try { try { // Split into sources and headers, remove excluded sources. HashMap<Integer, List<IIndexFileLocation>> files = new HashMap<Integer, List<IIndexFileLocation>>(); final ArrayList<IIndexFragmentFile> indexFilesToRemove = new ArrayList<IIndexFragmentFile>(); extractFiles(files, indexFilesToRemove, monitor); setResume(true); // Remove files from index removeFilesInIndex(fFilesToRemove, indexFilesToRemove, monitor); HashMap<Integer, List<IIndexFileLocation>> moreFiles = null; while (true) { for (int linkageID : getLinkagesToParse()) { 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(); } if (hasUrgentTasks()) break; } synchronized (this) { if (fUrgentTasks.isEmpty()) { if (moreFiles == null) { // No urgent tasks and no more files to parse. We are done. fTaskCompleted = true; break; } else { files = moreFiles; moreFiles = null; } } } AbstractIndexerTask urgentTask; while ((urgentTask = getUrgentTask()) != null) { // Move the lists of not yet parsed files from 'files' to 'moreFiles'. if (moreFiles == null) { moreFiles = files; } else { for (Map.Entry<Integer, List<IIndexFileLocation>> entry : files.entrySet()) { List<IIndexFileLocation> list = moreFiles.get(entry.getKey()); if (list == null) { moreFiles.put(entry.getKey(), entry.getValue()); } else { list.addAll(0, entry.getValue()); } } } // Extract files from the urgent task. files = new HashMap<Integer, List<IIndexFileLocation>>(); fFilesToUpdate = urgentTask.fFilesToUpdate; fForceNumberFiles = urgentTask.fForceNumberFiles; fFilesToRemove = urgentTask.fFilesToRemove; incrementRequestedFilesCount(fFilesToUpdate.length + fFilesToRemove.size()); extractFiles(files, indexFilesToRemove, monitor); removeFilesInIndex(fFilesToRemove, indexFilesToRemove, monitor); } } if (!monitor.isCanceled()) { setResume(false); } } finally { fIndex.flush(); } } catch (CoreException e) { logException(e); } finally { fIndex.releaseReadLock(); } } finally { synchronized (this) { fTaskCompleted = true; } } }