diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 1717792837d..887522263fb 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #include @@ -223,6 +224,7 @@ public: void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) override; void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) override; + void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; private: ClangBackEnd::ConnectionClient &m_connection; @@ -294,6 +296,12 @@ void IpcSender::requestHighlighting(const RequestHighlightingMessage &message) m_connection.serverProxy().requestHighlighting(message); } +void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) +{ + QTC_CHECK(m_connection.isConnected()); + m_connection.serverProxy().updateVisibleTranslationUnits(message); +} + IpcCommunicator::IpcCommunicator() : m_connection(&m_ipcReceiver) , m_ipcSender(new IpcSender(m_connection)) @@ -370,6 +378,85 @@ void IpcCommunicator::registerFallbackProjectPart() registerProjectPartsForEditor({projectPartContainer}); } +namespace { +Utf8String currentCppEditorDocumentFilePath() +{ + Utf8String currentCppEditorDocumentFilePath; + + const auto currentEditor = Core::EditorManager::currentEditor(); + if (currentEditor && CppTools::CppModelManager::isCppEditor(currentEditor)) { + const auto currentDocument = currentEditor->document(); + if (currentDocument) + currentCppEditorDocumentFilePath = currentDocument->filePath().toString(); + } + + return currentCppEditorDocumentFilePath; +} + +void removeDuplicates(Utf8StringVector &visibleEditorDocumentsFilePaths) +{ + std::sort(visibleEditorDocumentsFilePaths.begin(), + visibleEditorDocumentsFilePaths.end()); + const auto end = std::unique(visibleEditorDocumentsFilePaths.begin(), + visibleEditorDocumentsFilePaths.end()); + visibleEditorDocumentsFilePaths.erase(end, + visibleEditorDocumentsFilePaths.end()); +} + +void removeNonCppEditors(QList &visibleEditors) +{ + const auto isNotCppEditor = [] (Core::IEditor *editor) { + return !CppTools::CppModelManager::isCppEditor(editor); + }; + + const auto end = std::remove_if(visibleEditors.begin(), + visibleEditors.end(), + isNotCppEditor); + + visibleEditors.erase(end, visibleEditors.end()); +} + +Utf8StringVector visibleCppEditorDocumentsFilePaths() +{ + auto visibleEditors = Core::EditorManager::visibleEditors(); + + removeNonCppEditors(visibleEditors); + + Utf8StringVector visibleCppEditorDocumentsFilePaths; + visibleCppEditorDocumentsFilePaths.reserve(visibleEditors.size()); + + const auto editorFilePaths = [] (Core::IEditor *editor) { + return Utf8String(editor->document()->filePath().toString()); + }; + + std::transform(visibleEditors.begin(), + visibleEditors.end(), + std::back_inserter(visibleCppEditorDocumentsFilePaths), + editorFilePaths); + + removeDuplicates(visibleCppEditorDocumentsFilePaths); + + return visibleCppEditorDocumentsFilePaths; +} + +} + +void IpcCommunicator::updateTranslationUnitVisiblity() +{ + updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); +} + +void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorsFilePaths) +{ + if (m_sendMode == IgnoreSendRequests) + return; + + const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths); + qCDebug(log) << ">>>" << message; + m_ipcSender->updateVisibleTranslationUnits(message); +} + void IpcCommunicator::registerCurrentProjectParts() { using namespace CppTools; @@ -561,6 +648,7 @@ void IpcCommunicator::initializeBackendWithCurrentData() registerCurrentProjectParts(); registerCurrentCppEditorDocuments(); registerCurrentCodeModelUiHeaders(); + updateTranslationUnitVisiblity(); emit backendReinitialized(); } diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index a6db278addd..160de329ef9 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -107,6 +107,7 @@ public: virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0; virtual void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) = 0; virtual void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) = 0; + virtual void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) = 0; }; class IpcCommunicator : public QObject @@ -149,6 +150,7 @@ public: void updateChangeContentStartPosition(const QString &filePath, int position); void registerFallbackProjectPart(); + void updateTranslationUnitVisiblity(); public: // for tests IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender); @@ -171,6 +173,9 @@ private: void onEditorAboutToClose(Core::IEditor *editor); void onCoreAboutToClose(); + void updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorsFilePaths); + private: IpcReceiver m_ipcReceiver; ClangBackEnd::ConnectionClient m_connection; diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 3d072696ab4..1485c944030 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -268,10 +268,12 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr if (projectPart->id() != m_projectPart->id()) { ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); ipcCommunicator.registerTranslationUnitsForEditor({fileContainerWithArguments(projectPart)}); + ipcCommunicator.updateTranslationUnitVisiblity(); requestDocumentAnnotations(projectPart->id()); } } else { ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArguments(projectPart)}}); + ipcCommunicator.updateTranslationUnitVisiblity(); requestDocumentAnnotations(projectPart->id()); } } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index c9e16252eb9..8dd11df681a 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -66,9 +66,14 @@ ModelManagerSupportClang::ModelManagerSupportClang() Core::EditorManager *editorManager = Core::EditorManager::instance(); connect(editorManager, &Core::EditorManager::currentEditorChanged, - this, &ModelManagerSupportClang::onCurrentEditorChanged); + this, &ModelManagerSupportClang::onCurrentEditorChanged, + Qt::QueuedConnection); connect(editorManager, &Core::EditorManager::editorOpened, - this, &ModelManagerSupportClang::onEditorOpened); + this, &ModelManagerSupportClang::onEditorOpened, + Qt::QueuedConnection); + connect(editorManager, &Core::EditorManager::editorsClosed, + this, &ModelManagerSupportClang::onEditorClosed, + Qt::QueuedConnection); CppTools::CppModelManager *modelManager = cppModelManager(); connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportContentsUpdated, @@ -111,6 +116,8 @@ void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent) m_previousCppEditor = newCurrent; else m_previousCppEditor.clear(); + + m_ipcCommunicator.updateTranslationUnitVisiblity(); } void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument) @@ -181,6 +188,11 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor) } } +void ModelManagerSupportClang::onEditorClosed(const QList &) +{ + m_ipcCommunicator.updateTranslationUnitVisiblity(); +} + void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit() { TextEditor::TextDocument *textDocument = qobject_cast(sender()); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 54478a6ee53..bbc44f4a6dc 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -71,6 +71,7 @@ public: private: void onEditorOpened(Core::IEditor *editor); + void onEditorClosed(const QList &editors); void onCurrentEditorChanged(Core::IEditor *newCurrent); void onCppDocumentAboutToReloadOnTranslationUnit(); void onCppDocumentReloadFinishedOnTranslationUnit(bool success); diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index fca3051875d..41d12cce5ea 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -385,6 +385,11 @@ QString toString(const RequestHighlightingMessage &) return QStringLiteral("RequestHighlightingMessage\n"); } +QString toString(const UpdateVisibleTranslationUnitsMessage &) +{ + return QStringLiteral("UpdateVisibleTranslationUnitsMessage\n"); +} + class IpcSenderSpy : public IpcSenderInterface { public: @@ -421,6 +426,9 @@ public: void requestHighlighting(const RequestHighlightingMessage &message) override { senderLog.append(toString(message)); } + void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override + { senderLog.append(toString(message)); } + public: QString senderLog; }; @@ -1074,6 +1082,7 @@ void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderInOtherEdi // Switch back to source file and check if modified header is reflected in completions. Core::EditorManager::activateEditor(openSource.editor()); + QCoreApplication::processEvents(); // connections are queued proposal = completionResults(openSource.editor()); QVERIFY(hasItem(proposal, "globalFromHeader")); QVERIFY(hasItem(proposal, "globalFromHeaderUnsaved")); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 079de7cfdd7..7a94dbb5809 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -936,7 +936,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() return part; } -bool CppModelManager::isCppEditor(Core::IEditor *editor) const +bool CppModelManager::isCppEditor(Core::IEditor *editor) { return editor->context().contains(ProjectExplorer::Constants::LANG_CXX); } diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index dac3973bce5..1c4b91ebf0f 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -120,7 +120,7 @@ public: const QByteArray &contents); void emitAbstractEditorSupportRemoved(const QString &filePath); - bool isCppEditor(Core::IEditor *editor) const; + static bool isCppEditor(Core::IEditor *editor); bool isClangCodeModelAvailable() const; bool isClangCodeModelActive() const;