From a5674be613e5dfa4abf775adb2a3c00703a872af Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 18 Sep 2015 12:19:46 +0200 Subject: [PATCH] Clang: Unregister file with project immediately on project close Ensure that first the editors unregister with the removed project part, then unregister the project part. This makes testing and following the message logs easier. It also fixes the following race condition: * Unload project of opened file * Immediately close the editor before a new project part is calculated ==> The editor is closed, but the translation unit is not properly unregistered. Change-Id: I618930d221323435ba60ac6c051380bccc9fdaf1 Reviewed-by: Marco Bubke --- .../clangeditordocumentprocessor.cpp | 14 +++--- .../clangeditordocumentprocessor.h | 2 +- .../clangmodelmanagersupport.cpp | 43 ++++++++++++++++++- .../clangcodemodel/clangmodelmanagersupport.h | 2 + .../test/clangcodecompletion_test.cpp | 1 + 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 028613ebad6..6cc479ccd4e 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -94,9 +94,6 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor( connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated, this, &ClangEditorDocumentProcessor::semanticInfoUpdated); - connect(CppTools::CppModelManager::instance(), &CppTools::CppModelManager::projectPartsRemoved, - this, &ClangEditorDocumentProcessor::onProjectPartsRemoved); - m_semanticHighlighter.setHighlightingRunner( [this]() -> QFuture { const int firstLine = 1; @@ -184,6 +181,11 @@ CppTools::ProjectPart::Ptr ClangEditorDocumentProcessor::projectPart() const return m_projectPart; } +void ClangEditorDocumentProcessor::clearProjectPart() +{ + m_projectPart.clear(); +} + void ClangEditorDocumentProcessor::updateCodeWarnings(const QVector &diagnostics, uint documentRevision) { @@ -250,12 +252,6 @@ void ClangEditorDocumentProcessor::onParserFinished() updateProjectPartAndTranslationUnitForEditor(); } -void ClangEditorDocumentProcessor::onProjectPartsRemoved(const QStringList &projectPartIds) -{ - if (m_projectPart && projectPartIds.contains(m_projectPart->id())) - m_projectPart.clear(); -} - void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart &projectPart) { QTC_ASSERT(m_modelManagerSupport, return); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index e7d93a42286..26c156a2652 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -70,6 +70,7 @@ public: bool hasProjectPart() const; CppTools::ProjectPart::Ptr projectPart() const; + void clearProjectPart(); void updateCodeWarnings(const QVector &diagnostics, uint documentRevision); @@ -82,7 +83,6 @@ public: private slots: void onParserFinished(); - void onProjectPartsRemoved(const QStringList &projectPartIds); private: void updateProjectPartAndTranslationUnitForEditor(); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index dee58c99c4b..12f7f5b5119 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -271,8 +271,49 @@ void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *p void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectPartIds) { - if (!projectPartIds.isEmpty()) + if (!projectPartIds.isEmpty()) { + unregisterTranslationUnitsWithProjectParts(projectPartIds); m_ipcCommunicator.unregisterProjectPartsForEditor(projectPartIds); + } +} + +static QVector +clangProcessorsWithProjectParts(const QStringList &projectPartIds) +{ + QVector result; + + foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments()) { + auto *processor = editorDocument->processor(); + auto *clangProcessor = qobject_cast(processor); + if (clangProcessor && clangProcessor->hasProjectPart()) { + if (projectPartIds.contains(clangProcessor->projectPart()->id())) + result.append(clangProcessor); + } + } + + return result; +} + +static QVector +processorToFileContainer(ClangEditorDocumentProcessor *processor) +{ + QTC_ASSERT(processor, return QVector()); + + const QString filePath = processor->baseTextDocument()->filePath().toString(); + const QString projectPartId = processor->projectPart()->id(); + + return {ClangBackEnd::FileContainer(filePath, projectPartId)}; +} + +void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts( + const QStringList &projectPartIds) +{ + const auto processors = clangProcessorsWithProjectParts(projectPartIds); + foreach (ClangEditorDocumentProcessor *processor, processors) { + m_ipcCommunicator.unregisterTranslationUnitsForEditor(processorToFileContainer(processor)); + processor->clearProjectPart(); + processor->run(); + } } #ifdef QT_TESTLIB_LIB diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 057429c750d..b433f4c0ecf 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -89,6 +89,8 @@ private: void onProjectPartsUpdated(ProjectExplorer::Project *project); void onProjectPartsRemoved(const QStringList &projectPartIds); + void unregisterTranslationUnitsWithProjectParts(const QStringList &projectPartIds); + void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument); void connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument); void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget); diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index c89bb6bf43c..46046d6d72c 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -1010,6 +1010,7 @@ void ClangCodeCompletionTest::testChangingProjectDependentCompletion() } // Project closed // Check again completion without project + openEditor.waitUntilProjectPartChanged(QLatin1String("")); proposal = completionResults(openEditor.editor()); QVERIFY(hasItem(proposal, "noProjectConfigurationDetected")); }