/// Replace the document in the snapshot. /// /// \returns true if successful, false if the new document is out-dated. bool CppModelManager::replaceDocument(Document::Ptr newDoc) { QMutexLocker locker(&d->m_snapshotMutex); Document::Ptr previous = d->m_snapshot.document(newDoc->fileName()); if (previous && (newDoc->revision() != 0 && newDoc->revision() < previous->revision())) // the new document is outdated return false; d->m_snapshot.insert(newDoc); return true; }
/*! * \brief createSourceProcessor Create a new source processor, which will signal the * model manager when a document has been processed. * * Indexed file is truncated version of fully parsed document: copy of source * code and full AST will be dropped when indexing is done. * * \return a new source processor object, which the caller needs to delete when finished. */ CppSourceProcessor *CppModelManager::createSourceProcessor() { CppModelManager *that = instance(); return new CppSourceProcessor(that->snapshot(), [that](const Document::Ptr &doc) { const Document::Ptr previousDocument = that->document(doc->fileName()); const unsigned newRevision = previousDocument.isNull() ? 1U : previousDocument->revision() + 1; doc->setRevision(newRevision); that->emitDocumentUpdated(doc); doc->releaseSourceAndAST(); }); }
void BuiltinEditorDocumentParser::updateHelper(const WorkingCopy &theWorkingCopy) { if (filePath().isEmpty()) return; const Configuration baseConfig = configuration(); const bool releaseSourceAndAST_ = releaseSourceAndAST(); State baseState = state(); ExtraState state = extraState(); WorkingCopy workingCopy = theWorkingCopy; bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged_ = false; CppModelManager *modelManager = CppModelManager::instance(); QByteArray configFile = modelManager->codeModelConfiguration(); ProjectPartHeaderPaths headerPaths; QStringList precompiledHeaders; QString projectConfigFile; LanguageFeatures features = LanguageFeatures::defaultFeatures(); baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState); if (state.forceSnapshotInvalidation) { invalidateSnapshot = true; state.forceSnapshotInvalidation = false; } if (const ProjectPart::Ptr part = baseState.projectPart) { configFile += part->toolchainDefines; configFile += overwrittenToolchainDefines(*part.data()); configFile += part->projectDefines; headerPaths = part->headerPaths; projectConfigFile = part->projectConfigFile; if (baseConfig.usePrecompiledHeaders) precompiledHeaders = part->precompiledHeaders; features = part->languageFeatures; } if (configFile != state.configFile) { state.configFile = configFile; invalidateSnapshot = true; invalidateConfig = true; } if (baseConfig.editorDefines != baseState.editorDefines) { baseState.editorDefines = baseConfig.editorDefines; invalidateSnapshot = true; editorDefinesChanged_ = true; } if (headerPaths != state.headerPaths) { state.headerPaths = headerPaths; invalidateSnapshot = true; } if (projectConfigFile != state.projectConfigFile) { state.projectConfigFile = projectConfigFile; invalidateSnapshot = true; } if (precompiledHeaders != state.precompiledHeaders) { state.precompiledHeaders = precompiledHeaders; invalidateSnapshot = true; } unsigned rev = 0; if (Document::Ptr doc = state.snapshot.document(filePath())) rev = doc->revision(); else invalidateSnapshot = true; Snapshot globalSnapshot = modelManager->snapshot(); if (invalidateSnapshot) { state.snapshot = Snapshot(); } else { // Remove changed files from the snapshot QSet<Utils::FileName> toRemove; foreach (const Document::Ptr &doc, state.snapshot) { const Utils::FileName fileName = Utils::FileName::fromString(doc->fileName()); if (workingCopy.contains(fileName)) { if (workingCopy.get(fileName).second != doc->editorRevision()) addFileAndDependencies(&state.snapshot, &toRemove, fileName); continue; } Document::Ptr otherDoc = globalSnapshot.document(fileName); if (!otherDoc.isNull() && otherDoc->revision() != doc->revision()) addFileAndDependencies(&state.snapshot, &toRemove, fileName); } if (!toRemove.isEmpty()) { invalidateSnapshot = true; foreach (const Utils::FileName &fileName, toRemove) state.snapshot.remove(fileName); } }
void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy) { QMutexLocker locker(&m_mutex); if (m_fileInEditor.isEmpty()) return; bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged = false; CppModelManager *modelManager = dynamic_cast<CppModelManager *>(CppModelManagerInterface::instance()); QByteArray configFile = modelManager->codeModelConfiguration(); QStringList includePaths; QStringList frameworkPaths; QStringList precompiledHeaders; updateProjectPart(); if (m_forceSnapshotInvalidation) { invalidateSnapshot = true; m_forceSnapshotInvalidation = false; } if (m_projectPart) { configFile += m_projectPart->toolchainDefines; configFile += m_projectPart->projectDefines; includePaths = m_projectPart->includePaths; frameworkPaths = m_projectPart->frameworkPaths; if (m_usePrecompiledHeaders) precompiledHeaders = m_projectPart->precompiledHeaders; } if (configFile != m_configFile) { m_configFile = configFile; invalidateSnapshot = true; invalidateConfig = true; } if (m_editorDefinesChangedSinceLastUpdate) { invalidateSnapshot = true; editorDefinesChanged = true; m_editorDefinesChangedSinceLastUpdate = false; } if (includePaths != m_includePaths) { m_includePaths = includePaths; invalidateSnapshot = true; } if (frameworkPaths != m_frameworkPaths) { m_frameworkPaths = frameworkPaths; invalidateSnapshot = true; } if (precompiledHeaders != m_precompiledHeaders) { m_precompiledHeaders = precompiledHeaders; invalidateSnapshot = true; } unsigned rev = 0; if (Document::Ptr doc = document()) rev = doc->revision(); else invalidateSnapshot = true; Snapshot globalSnapshot = modelManager->snapshot(); if (invalidateSnapshot) { m_snapshot = Snapshot(); } else { // Remove changed files from the snapshot QSet<QString> toRemove; foreach (const Document::Ptr &doc, m_snapshot) { QString fileName = doc->fileName(); if (workingCopy.contains(fileName)) { if (workingCopy.get(fileName).second != doc->editorRevision()) addFileAndDependencies(&toRemove, fileName); continue; } Document::Ptr otherDoc = globalSnapshot.document(fileName); if (!otherDoc.isNull() && otherDoc->revision() != doc->revision()) addFileAndDependencies(&toRemove, fileName); } if (!toRemove.isEmpty()) { invalidateSnapshot = true; foreach (const QString &fileName, toRemove) m_snapshot.remove(fileName); }