private void parseVersionInContext( int linkageID, LinkageTask map, IIndexFileLocation ifl, final FileVersionTask versionTask, Object tu, LinkedHashSet<IIndexFile> safeGuard, IProgressMonitor monitor) throws CoreException, InterruptedException { final IIndexFragmentFile headerFile = versionTask.fIndexFile; final int safeguardSize = safeGuard.size(); while (true) { // Look for a context and parse the file. IIndexFragmentFile ctxFile = findContextFile(linkageID, map, versionTask, safeGuard, monitor); if (ctxFile == null || ctxFile == headerFile) return; Object contextTu = fResolver.getInputFile(ctxFile.getLocation()); if (contextTu == null) return; final IScannerInfo scannerInfo = getScannerInfo(linkageID, contextTu); final AbstractLanguage language = getLanguage(contextTu, linkageID); final FileContext ctx = new FileContext(ctxFile, headerFile); Set<IIndexFile> dependencies = null; boolean done = false; while (!done) { done = true; DependsOnOutdatedFileException d = parseFile(tu, language, ifl, scannerInfo, ctx, monitor); if (d != null) { // File was not parsed, because there is a dependency that needs to be // handled before. if (dependencies == null) dependencies = new HashSet<IIndexFile>(); if (dependencies.add(d.fIndexFile)) { if (parseFile( d.fTu, language, d.fIndexFile.getLocation(), scannerInfo, new FileContext(ctxFile, d.fIndexFile), monitor) == null) done = false; } } } if (!ctx.fLostPragmaOnceSemantics) return; // Try the next context restoreSet(safeGuard, safeguardSize); } }
@Override public void clearFile(IIndexFragmentFile file) throws CoreException { assert file.getIndexFragment() == this; IIndexFileLocation location = file.getLocation(); PDOMFile pdomFile = (PDOMFile) file; pdomFile.clear(); IIndexInclude include = pdomFile.getParsedInContext(); if (include != null) { PDOMFile includedBy = (PDOMFile) include.getIncludedBy(); if (includedBy.getTimestamp() > 0) getIndexOfFilesWithUnresolvedIncludes().insert(includedBy.getRecord()); } fEvent.fClearedFiles.add(location); }
@Override public void addFileContent( IIndexFragmentFile sourceFile, IncludeInformation[] includes, IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver pathResolver, YieldableIndexLock lock) throws CoreException, InterruptedException { assert sourceFile.getIndexFragment() == this; PDOMFile pdomFile = (PDOMFile) sourceFile; pdomFile.addMacros(macros); final ASTFilePathResolver origResolver = fPathResolver; fPathResolver = pathResolver; try { pdomFile.addNames(names, lock); } finally { fPathResolver = origResolver; } // Includes expose the temporary file in the index, we must not yield the lock beyond this // point. pdomFile.addIncludesTo(includes); final IIndexFileLocation location = pdomFile.getLocation(); if (location != null) { fEvent.fClearedFiles.remove(location); fEvent.fFilesWritten.add(location); } }
private boolean isModified( boolean checkTimestamps, boolean checkFileContentsHash, IIndexFileLocation ifl, Object tu, IIndexFragmentFile file) throws CoreException { if (checkTimestamps) { if (fResolver.getLastModified(ifl) != file.getTimestamp() || computeFileSizeAndEncodingHashcode(ifl) != file.getSizeAndEncodingHashcode()) { if (checkFileContentsHash && computeFileContentsHash(tu) == file.getContentsHash()) { return false; } return true; } } return false; }
IIndexFragmentFile selectIndexFile( int linkageID, IIndexFileLocation ifl, ISignificantMacros sigMacros) throws CoreException { LinkageTask map = findRequestMap(linkageID); if (map != null) { LocationTask locTask = map.find(ifl); if (locTask != null) { FileVersionTask task = locTask.findVersion(sigMacros); if (task != null) { return task.fOutdated ? null : task.fIndexFile; } } } IIndexFragmentFile[] files = getAvailableIndexFiles(linkageID, ifl); for (IIndexFragmentFile file : files) { if (sigMacros.equals(file.getSignificantMacros())) return file; } return null; }
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; } }