private IIndexFragmentFile findContextFile( int linkageID, LinkageTask map, final FileVersionTask versionTask, LinkedHashSet<IIndexFile> safeGuard, IProgressMonitor monitor) throws CoreException, InterruptedException { IIndexFragmentFile ctxFile = versionTask.fIndexFile; while (true) { IIndexInclude ctxInclude = ctxFile.getParsedInContext(); if (ctxInclude == null) return ctxFile; IIndexFragmentFile nextCtx = (IIndexFragmentFile) ctxInclude.getIncludedBy(); if (nextCtx == null) return nextCtx; // Found a recursion. if (!safeGuard.add(nextCtx)) return null; final IIndexFileLocation ctxIfl = nextCtx.getLocation(); LocationTask ctxTask = map.find(ctxIfl); if (ctxTask != null) { FileVersionTask ctxVersionTask = ctxTask.findVersion(nextCtx); if (ctxVersionTask != null && ctxVersionTask.fOutdated) { // 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. return null; // The file is no longer a context, look for a different one. nextCtx = ctxFile; } } ctxFile = nextCtx; } }
private void extractFiles( HashMap<Integer, List<IIndexFileLocation>> files, List<IIndexFragmentFile> iFilesToRemove, IProgressMonitor monitor) throws CoreException { 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 forceUnresolvedIncludes = (fUpdateFlags & IIndexManager.UPDATE_UNRESOLVED_INCLUDES) != 0; final boolean both = fIndexHeadersWithoutContext == UnusedHeaderStrategy.useBoth; int count = 0; int forceFirst = fForceNumberFiles; BitSet linkages = new BitSet(); for (final Object tu : fFilesToUpdate) { if (monitor.isCanceled()) return; final boolean force = forceAll || --forceFirst >= 0; final IIndexFileLocation ifl = fResolver.resolveFile(tu); if (ifl == null) continue; final IIndexFragmentFile[] indexFiles = fIndex.getWritableFiles(ifl); final boolean isSourceUnit = fResolver.isSourceUnit(tu); linkages.clear(); 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 : 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 || (forceUnresolvedIncludes && ifile.hasUnresolvedInclude()) || 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++; } } } } // Handle other files present in index. for (IIndexFragmentFile ifile : indexFiles) { if (ifile != null) { IIndexInclude ctx = ifile.getParsedInContext(); if (ctx == null && !indexedUnconditionally && ifile.hasContent()) { iFilesToRemove.add(ifile); count++; } else { boolean update = force || (forceUnresolvedIncludes && ifile.hasUnresolvedInclude()) || isModified(checkTimestamps, checkFileContentsHash, ifl, tu, ifile); final int linkageID = ifile.getLinkageID(); if (update && requestUpdate(linkageID, ifl, ifile, tu, UpdateKind.OTHER_HEADER)) { count++; linkages.set(linkageID); } } } } for (int lid = linkages.nextSetBit(0); lid >= 0; lid = linkages.nextSetBit(lid + 1)) { addPerLinkage(lid, ifl, files); } } synchronized (this) { incrementRequestedFilesCount(count - fFilesToUpdate.length); fFilesToUpdate = null; } }