From d579608e8a74c2179d44192556cf0b9debe817a4 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 1 Dec 2015 11:57:08 +0100 Subject: [PATCH] Clang: Prioritize current and visible translation units We reparse first the current and then the visible translation units before we reparse all other units. The signals connections are queued to wait for the visible editor update. Change-Id: I5e2b8bc80568450268ca24e26720b3f5af640995 Reviewed-by: Nikolai Kosjar --- .../clangbackendipcintegration.cpp | 88 +++++++++++++++++++ .../clangbackendipcintegration.h | 5 ++ .../clangeditordocumentprocessor.cpp | 2 + .../clangmodelmanagersupport.cpp | 16 +++- .../clangcodemodel/clangmodelmanagersupport.h | 1 + .../test/clangcodecompletion_test.cpp | 9 ++ src/plugins/cpptools/cppmodelmanager.cpp | 2 +- src/plugins/cpptools/cppmodelmanager.h | 2 +- 8 files changed, 121 insertions(+), 4 deletions(-) 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;