diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp new file mode 100644 index 00000000000..fc5603b0c04 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -0,0 +1,581 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendcommunicator.h" + +#include "clangbackendlogging.h" +#include "clangcompletionassistprocessor.h" +#include "clangmodelmanagersupport.h" +#include "clangutils.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +using namespace CPlusPlus; +using namespace ClangBackEnd; +using namespace TextEditor; + +enum { backEndStartTimeOutInMs = 10000 }; + +static QString backendProcessPath() +{ + return Core::ICore::libexecPath() + + QStringLiteral("/clangbackend") + + QStringLiteral(QTC_HOST_EXE_SUFFIX); +} + +namespace ClangCodeModel { +namespace Internal { + +class DummyBackendSender : public BackendSender +{ +public: + DummyBackendSender() : BackendSender(nullptr) {} + + void end() override {} + void registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &) override {} + void updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &) override {} + void unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &) override {} + void registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &) override {} + void unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &) override {} + void registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &) override {} + void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &) override {} + void completeCode(const CompleteCodeMessage &) override {} + void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &) override {} + void requestReferences(const RequestReferencesMessage &) override {} + void requestFollowSymbol(const RequestFollowSymbolMessage &) override {} + void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &) override {} +}; + + +BackendCommunicator::BackendCommunicator() + : m_connection(&m_receiver) + , m_sender(new DummyBackendSender()) +{ + m_backendStartTimeOut.setSingleShot(true); + connect(&m_backendStartTimeOut, &QTimer::timeout, + this, &BackendCommunicator::logStartTimeOut); + + m_receiver.setAliveHandler([this]() { m_connection.resetProcessAliveTimer(); }); + + connect(Core::EditorManager::instance(), &Core::EditorManager::editorAboutToClose, + this, &BackendCommunicator::onEditorAboutToClose); + connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose, + this, &BackendCommunicator::setupDummySender); + + initializeBackend(); +} + +BackendCommunicator::~BackendCommunicator() +{ + disconnect(&m_connection, 0, this, 0); +} + +void BackendCommunicator::initializeBackend() +{ + const QString clangBackEndProcessPath = backendProcessPath(); + if (!QFileInfo(clangBackEndProcessPath).exists()) { + logExecutableDoesNotExist(); + return; + } + qCDebug(ipcLog) << "Starting" << clangBackEndProcessPath; + + m_connection.setProcessAliveTimerInterval(30 * 1000); + m_connection.setProcessPath(clangBackEndProcessPath); + + connect(&m_connection, &ConnectionClient::connectedToLocalSocket, + this, &BackendCommunicator::onConnectedToBackend); + connect(&m_connection, &ConnectionClient::disconnectedFromLocalSocket, + this, &BackendCommunicator::setupDummySender); + + m_connection.startProcessAndConnectToServerAsynchronously(); + m_backendStartTimeOut.start(backEndStartTimeOutInMs); +} + +static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart) +{ + const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, + CppTools::ProjectFile::Unsupported); // No language option + + return options; +} + +static ProjectPartContainer toProjectPartContainer( + const CppTools::ProjectPart::Ptr &projectPart) +{ + const QStringList options = projectPartOptions(projectPart); + + return ProjectPartContainer(projectPart->id(), Utf8StringVector(options)); +} + +static QVector toProjectPartContainers( + const QVector projectParts) +{ + QVector projectPartContainers; + projectPartContainers.reserve(projectParts.size()); + + foreach (const CppTools::ProjectPart::Ptr &projectPart, projectParts) + projectPartContainers << toProjectPartContainer(projectPart); + + return projectPartContainers; +} + +void BackendCommunicator::registerFallbackProjectPart() +{ + const auto projectPart = CppTools::CppModelManager::instance()->fallbackProjectPart(); + const auto projectPartContainer = toProjectPartContainer(projectPart); + + 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 = CppTools::CppToolsBridge::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 BackendCommunicator::updateTranslationUnitVisiblity() +{ + updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); +} + +bool BackendCommunicator::isNotWaitingForCompletion() const +{ + return !m_receiver.isExpectingCodeCompletedMessage(); +} + +void BackendCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorsFilePaths) +{ + const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths); + m_sender->updateVisibleTranslationUnits(message); +} + +void BackendCommunicator::registerCurrentProjectParts() +{ + using namespace CppTools; + + const QList projectInfos = CppModelManager::instance()->projectInfos(); + foreach (const ProjectInfo &projectInfo, projectInfos) + registerProjectsParts(projectInfo.projectParts()); +} + +void BackendCommunicator::restoreCppEditorDocuments() +{ + resetCppEditorDocumentProcessors(); + registerVisibleCppEditorDocumentAndMarkInvisibleDirty(); +} + +void BackendCommunicator::resetCppEditorDocumentProcessors() +{ + using namespace CppTools; + + const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments(); + foreach (CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) + cppEditorDocument->resetProcessor(); +} + +void BackendCommunicator::registerVisibleCppEditorDocumentAndMarkInvisibleDirty() +{ + CppTools::CppModelManager::instance()->updateCppEditorDocuments(); +} + +void BackendCommunicator::registerCurrentCodeModelUiHeaders() +{ + using namespace CppTools; + + const auto editorSupports = CppModelManager::instance()->abstractEditorSupports(); + foreach (const AbstractEditorSupport *es, editorSupports) { + const QString mappedPath + = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskPath(es->fileName()); + updateUnsavedFile(mappedPath, es->contents(), es->revision()); + } +} + +void BackendCommunicator::registerProjectsParts(const QVector projectParts) +{ + const auto projectPartContainers = toProjectPartContainers(projectParts); + registerProjectPartsForEditor(projectPartContainers); +} + +void BackendCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath) +{ + const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); + + updateTranslationUnit(filePath, document->contents(), document->revision()); +} + +void BackendCommunicator::updateUnsavedFileFromCppEditorDocument(const QString &filePath) +{ + const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); + + updateUnsavedFile(filePath, document->contents(), document->revision()); +} + +void BackendCommunicator::updateTranslationUnit(const QString &filePath, + const QByteArray &contents, + uint documentRevision) +{ + const bool hasUnsavedContent = true; + + updateTranslationUnitsForEditor({{filePath, + Utf8String(), + Utf8String::fromByteArray(contents), + hasUnsavedContent, + documentRevision}}); +} + +void BackendCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision) +{ + const bool hasUnsavedContent = true; + + // TODO: Send new only if changed + registerUnsavedFilesForEditor({{filePath, + Utf8String(), + Utf8String::fromByteArray(contents), + hasUnsavedContent, + documentRevision}}); +} + +static bool documentHasChanged(const QString &filePath, uint revision) +{ + if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) + return document->sendTracker().shouldSendRevision(revision); + + return true; +} + +static void setLastSentDocumentRevision(const QString &filePath, uint revision) +{ + if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) + document->sendTracker().setLastSentRevision(int(revision)); +} + +void BackendCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer &fileContainer) +{ + if (documentHasChanged(fileContainer.filePath(), fileContainer.documentRevision())) { + updateTranslationUnitsForEditor({fileContainer}); + setLastSentDocumentRevision(fileContainer.filePath(), + fileContainer.documentRevision()); + } +} + +void BackendCommunicator::requestDocumentAnnotations(const FileContainer &fileContainer) +{ + const RequestDocumentAnnotationsMessage message(fileContainer); + m_sender->requestDocumentAnnotations(message); +} + +QFuture BackendCommunicator::requestReferences( + const FileContainer &fileContainer, + quint32 line, + quint32 column, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses) +{ + const RequestReferencesMessage message(fileContainer, line, column); + m_sender->requestReferences(message); + + return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument, + localUses); +} + +QFuture BackendCommunicator::requestFollowSymbol( + const FileContainer &curFileContainer, + const QVector &dependentFiles, + quint32 line, + quint32 column) +{ + const RequestFollowSymbolMessage message(curFileContainer, + dependentFiles, + line, + column); + m_sender->requestFollowSymbol(message); + + return m_receiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber()); +} + +void BackendCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document) +{ + const auto textDocument = qobject_cast(document); + const auto filePath = textDocument->filePath().toString(); + const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); + + updateTranslationUnitWithRevisionCheck(FileContainer(filePath, + projectPartId, + Utf8StringVector(), + textDocument->document()->revision())); +} + +void BackendCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) +{ + if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) + document->sendTracker().applyContentChange(position); +} + +void BackendCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document) +{ + QTC_ASSERT(document, return); + if (Core::EditorManager::currentDocument() != document) + updateTranslationUnit(document); +} + +void BackendCommunicator::updateTranslationUnit(Core::IDocument *document) +{ + updateTranslationUnitFromCppEditorDocument(document->filePath().toString()); +} + +void BackendCommunicator::updateUnsavedFile(Core::IDocument *document) +{ + QTC_ASSERT(document, return); + + updateUnsavedFileFromCppEditorDocument(document->filePath().toString()); +} + +void BackendCommunicator::onConnectedToBackend() +{ + m_backendStartTimeOut.stop(); + + ++m_connectedCount; + if (m_connectedCount > 1) + logRestartedDueToUnexpectedFinish(); + + m_receiver.reset(); + m_sender.reset(new BackendSender(&m_connection)); + + initializeBackendWithCurrentData(); +} + +void BackendCommunicator::onEditorAboutToClose(Core::IEditor *editor) +{ + if (auto *textEditor = qobject_cast(editor)) + m_receiver.deleteProcessorsOfEditorWidget(textEditor->editorWidget()); +} + +void BackendCommunicator::setupDummySender() +{ + m_sender.reset(new DummyBackendSender); +} + +void BackendCommunicator::logExecutableDoesNotExist() +{ + const QString msg + = tr("Clang Code Model: Error: " + "The clangbackend executable \"%1\" does not exist.") + .arg(QDir::toNativeSeparators(backendProcessPath())); + + logError(msg); +} + +void BackendCommunicator::logStartTimeOut() +{ + const QString msg + = tr("Clang Code Model: Error: " + "The clangbackend executable \"%1\" could not be started (timeout after %2ms).") + .arg(QDir::toNativeSeparators(backendProcessPath())) + .arg(backEndStartTimeOutInMs); + + logError(msg); +} + +void BackendCommunicator::logRestartedDueToUnexpectedFinish() +{ + const QString msg + = tr("Clang Code Model: Error: " + "The clangbackend process has finished unexpectedly and was restarted."); + + logError(msg); +} + +void BackendCommunicator::logError(const QString &text) +{ + const QString textWithTimestamp = QDateTime::currentDateTime().toString(Qt::ISODate) + + ' ' + text; + Core::MessageManager::write(textWithTimestamp, Core::MessageManager::Flash); + qWarning("%s", qPrintable(textWithTimestamp)); +} + +void BackendCommunicator::initializeBackendWithCurrentData() +{ + registerFallbackProjectPart(); + registerCurrentProjectParts(); + registerCurrentCodeModelUiHeaders(); + restoreCppEditorDocuments(); + updateTranslationUnitVisiblity(); + + emit backendReinitialized(); +} + +BackendSender *BackendCommunicator::setBackendSender(BackendSender *sender) +{ + BackendSender *previousSender = m_sender.take(); + m_sender.reset(sender); + return previousSender; +} + +void BackendCommunicator::killBackendProcess() +{ + m_connection.processForTestOnly()->kill(); +} + +void BackendCommunicator::registerTranslationUnitsForEditor(const FileContainers &fileContainers) +{ + const RegisterTranslationUnitForEditorMessage message(fileContainers, + currentCppEditorDocumentFilePath(), + visibleCppEditorDocumentsFilePaths()); + m_sender->registerTranslationUnitsForEditor(message); +} + +void BackendCommunicator::updateTranslationUnitsForEditor(const FileContainers &fileContainers) +{ + const UpdateTranslationUnitsForEditorMessage message(fileContainers); + m_sender->updateTranslationUnitsForEditor(message); +} + +void BackendCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers) +{ + const UnregisterTranslationUnitsForEditorMessage message(fileContainers); + m_sender->unregisterTranslationUnitsForEditor(message); +} + +void BackendCommunicator::registerProjectPartsForEditor( + const ProjectPartContainers &projectPartContainers) +{ + const RegisterProjectPartsForEditorMessage message(projectPartContainers); + m_sender->registerProjectPartsForEditor(message); +} + +void BackendCommunicator::unregisterProjectPartsForEditor(const QStringList &projectPartIds) +{ + const UnregisterProjectPartsForEditorMessage message((Utf8StringVector(projectPartIds))); + m_sender->unregisterProjectPartsForEditor(message); +} + +void BackendCommunicator::registerUnsavedFilesForEditor(const FileContainers &fileContainers) +{ + const RegisterUnsavedFilesForEditorMessage message(fileContainers); + m_sender->registerUnsavedFilesForEditor(message); +} + +void BackendCommunicator::unregisterUnsavedFilesForEditor(const FileContainers &fileContainers) +{ + const UnregisterUnsavedFilesForEditorMessage message(fileContainers); + m_sender->unregisterUnsavedFilesForEditor(message); +} + +void BackendCommunicator::completeCode(ClangCompletionAssistProcessor *assistProcessor, + const QString &filePath, + quint32 line, + quint32 column, + const QString &projectFilePath, + qint32 funcNameStartLine, + qint32 funcNameStartColumn) +{ + const CompleteCodeMessage message(filePath, line, column, projectFilePath, funcNameStartLine, + funcNameStartColumn); + m_sender->completeCode(message); + m_receiver.addExpectedCodeCompletedMessage(message.ticketNumber(), assistProcessor); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendcommunicator.h similarity index 55% rename from src/plugins/clangcodemodel/clangbackendipcintegration.h rename to src/plugins/clangcodemodel/clangbackendcommunicator.h index 5c7eb6f9225..86054e566f0 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.h @@ -25,135 +25,42 @@ #pragma once +#include "clangbackendreceiver.h" +#include "clangbackendsender.h" + #include -#include -#include #include #include -#include #include #include #include -#include -#include -#include #include - -#include +#include namespace Core { class IEditor; class IDocument; } -namespace ClangBackEnd { -class DocumentAnnotationsChangedMessage; -} - -namespace TextEditor { -class TextEditorWidget; -class TextDocument; -} - namespace ClangCodeModel { namespace Internal { -class ModelManagerSupportClang; - class ClangCompletionAssistProcessor; -class IpcReceiver : public ClangBackEnd::ClangCodeModelClientInterface -{ -public: - IpcReceiver(); - ~IpcReceiver(); - - using AliveHandler = std::function; - void setAliveHandler(const AliveHandler &handler); - - void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor); - void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget); - - QFuture - addExpectedReferencesMessage(quint64 ticket, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses); - QFuture addExpectedRequestFollowSymbolMessage(quint64 ticket); - bool isExpectingCodeCompletedMessage() const; - - void reset(); - -private: - void alive() override; - void echo(const ClangBackEnd::EchoMessage &message) override; - void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override; - - void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override; - void references(const ClangBackEnd::ReferencesMessage &message) override; - void followSymbol(const ClangBackEnd::FollowSymbolMessage &message) override; - -private: - AliveHandler m_aliveHandler; - QHash m_assistProcessorsTable; - - struct ReferencesEntry { - ReferencesEntry() = default; - ReferencesEntry(QFutureInterface futureInterface, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses) - : futureInterface(futureInterface) - , textDocument(textDocument) - , localUses(localUses) {} - QFutureInterface futureInterface; - QPointer textDocument; - CppTools::SemanticInfo::LocalUseMap localUses; - }; - QHash m_referencesTable; - - QHash> m_followTable; -}; - -class IpcSender : public ClangBackEnd::ClangCodeModelServerInterface -{ -public: - IpcSender(ClangBackEnd::ClangCodeModelConnectionClient *connectionClient); - - void end() override; - void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; - void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override; - void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; - void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; - void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; - void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) override; - void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; - void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; - void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; - void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; - void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; - void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) override; - -private: - bool isConnected() const; - -private: - ClangBackEnd::ClangCodeModelConnectionClient *m_connection = nullptr; -}; - -class IpcCommunicator : public QObject +class BackendCommunicator : public QObject { Q_OBJECT public: - using Ptr = QSharedPointer; using FileContainer = ClangBackEnd::FileContainer; using FileContainers = QVector; using ProjectPartContainers = QVector; public: - IpcCommunicator(); - ~IpcCommunicator(); + BackendCommunicator(); + ~BackendCommunicator(); void registerTranslationUnitsForEditor(const FileContainers &fileContainers); void updateTranslationUnitsForEditor(const FileContainers &fileContainers); @@ -199,7 +106,7 @@ public: bool isNotWaitingForCompletion() const; public: // for tests - IpcSender *setIpcSender(IpcSender *ipcSender); + BackendSender *setBackendSender(BackendSender *sender); void killBackendProcess(); signals: // for tests @@ -229,10 +136,10 @@ private: const Utf8StringVector &visibleEditorsFilePaths); private: - IpcReceiver m_ipcReceiver; + BackendReceiver m_receiver; ClangBackEnd::ClangCodeModelConnectionClient m_connection; QTimer m_backendStartTimeOut; - QScopedPointer m_ipcSender; + QScopedPointer m_sender; int m_connectedCount = 0; }; diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp deleted file mode 100644 index 8a953af9c32..00000000000 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ /dev/null @@ -1,927 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "clangbackendipcintegration.h" - -#include "clangcompletionassistprocessor.h" -#include "clangeditordocumentprocessor.h" -#include "clangmodelmanagersupport.h" -#include "clangutils.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.ipc") - -using namespace CPlusPlus; -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; -using namespace ClangBackEnd; -using namespace TextEditor; - -static QString backendProcessPath() -{ - return Core::ICore::libexecPath() - + QStringLiteral("/clangbackend") - + QStringLiteral(QTC_HOST_EXE_SUFFIX); -} - -static bool printAliveMessageHelper() -{ - const bool print = qEnvironmentVariableIntValue("QTC_CLANG_FORCE_VERBOSE_ALIVE"); - if (!print) { - qCDebug(log) << "Hint: AliveMessage will not be printed. " - "Force it by setting QTC_CLANG_FORCE_VERBOSE_ALIVE=1."; - } - - return print; -} - -static bool printAliveMessage() -{ - static bool print = log().isDebugEnabled() ? printAliveMessageHelper() : false; - return print; -} - -IpcReceiver::IpcReceiver() -{ -} - -IpcReceiver::~IpcReceiver() -{ - reset(); -} - -void IpcReceiver::setAliveHandler(const IpcReceiver::AliveHandler &handler) -{ - m_aliveHandler = handler; -} - -void IpcReceiver::addExpectedCodeCompletedMessage( - quint64 ticket, - ClangCompletionAssistProcessor *processor) -{ - QTC_ASSERT(processor, return); - QTC_CHECK(!m_assistProcessorsTable.contains(ticket)); - m_assistProcessorsTable.insert(ticket, processor); -} - -void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget) -{ - QMutableHashIterator it(m_assistProcessorsTable); - while (it.hasNext()) { - it.next(); - ClangCompletionAssistProcessor *assistProcessor = it.value(); - if (assistProcessor->textEditorWidget() == textEditorWidget) { - delete assistProcessor; - it.remove(); - } - } -} - -QFuture IpcReceiver::addExpectedReferencesMessage( - quint64 ticket, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses) -{ - QTC_CHECK(textDocument); - QTC_CHECK(!m_referencesTable.contains(ticket)); - - QFutureInterface futureInterface; - futureInterface.reportStarted(); - - const ReferencesEntry entry{futureInterface, textDocument, localUses}; - m_referencesTable.insert(ticket, entry); - - return futureInterface.future(); -} - -QFuture IpcReceiver::addExpectedRequestFollowSymbolMessage(quint64 ticket) -{ - QTC_CHECK(!m_followTable.contains(ticket)); - - QFutureInterface futureInterface; - futureInterface.reportStarted(); - - m_followTable.insert(ticket, futureInterface); - - return futureInterface.future(); -} - -bool IpcReceiver::isExpectingCodeCompletedMessage() const -{ - return !m_assistProcessorsTable.isEmpty(); -} - -void IpcReceiver::reset() -{ - // Clean up waiting assist processors - qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end()); - m_assistProcessorsTable.clear(); - - // Clean up futures for references - for (ReferencesEntry &entry : m_referencesTable) - entry.futureInterface.cancel(); - m_referencesTable.clear(); - for (QFutureInterface &futureInterface : m_followTable) - futureInterface.cancel(); - m_followTable.clear(); -} - -void IpcReceiver::alive() -{ - if (printAliveMessage()) - qCDebug(log) << "<<< AliveMessage"; - QTC_ASSERT(m_aliveHandler, return); - m_aliveHandler(); -} - -void IpcReceiver::echo(const EchoMessage &message) -{ - qCDebug(log) << "<<<" << message; -} - -void IpcReceiver::codeCompleted(const CodeCompletedMessage &message) -{ - qCDebug(log) << "<<< CodeCompletedMessage with" << message.codeCompletions().size() << "items"; - - const quint64 ticket = message.ticketNumber(); - QScopedPointer processor(m_assistProcessorsTable.take(ticket)); - if (processor) { - processor->handleAvailableCompletions(message.codeCompletions(), - message.neededCorrection()); - } -} - -void IpcReceiver::documentAnnotationsChanged(const DocumentAnnotationsChangedMessage &message) -{ - qCDebug(log) << "<<< DocumentAnnotationsChangedMessage with" - << message.diagnostics().size() << "diagnostics" - << message.highlightingMarks().size() << "highlighting marks" - << message.skippedPreprocessorRanges().size() << "skipped preprocessor ranges"; - - auto processor = ClangEditorDocumentProcessor::get(message.fileContainer().filePath()); - - if (processor) { - const QString projectPartId = message.fileContainer().projectPartId(); - const QString filePath = message.fileContainer().filePath(); - const QString documentProjectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); - if (projectPartId == documentProjectPartId) { - const quint32 documentRevision = message.fileContainer().documentRevision(); - processor->updateCodeWarnings(message.diagnostics(), - message.firstHeaderErrorDiagnostic(), - documentRevision); - processor->updateHighlighting(message.highlightingMarks(), - message.skippedPreprocessorRanges(), - documentRevision); - } - } -} - -static -CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument, - const SourceRangeContainer &sourceRange) -{ - const SourceLocationContainer start = sourceRange.start(); - const SourceLocationContainer end = sourceRange.end(); - const unsigned length = end.column() - start.column(); - - const QTextBlock block = textDocument.findBlockByNumber(static_cast(start.line()) - 1); - const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), - static_cast(start.column())); - const uint column = start.column() - static_cast(shift); - - return CppTools::CursorInfo::Range(start.line(), column, length); -} - -static -CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses, - const ReferencesMessage &message) -{ - CppTools::CursorInfo result; - const QVector references = message.references(); - - result.areUseRangesForLocalVariable = message.isLocalVariable(); - for (const SourceRangeContainer &reference : references) - result.useRanges.append(toCursorInfoRange(textDocument, reference)); - - result.useRanges.reserve(references.size()); - result.localUses = localUses; - - return result; -} - -static -CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message) -{ - CppTools::SymbolInfo result; - const SourceRangeContainer &range = message.sourceRange(); - - const SourceLocationContainer start = range.start(); - const SourceLocationContainer end = range.end(); - result.startLine = static_cast(start.line()); - result.startColumn = static_cast(start.column()); - result.endLine = static_cast(end.line()); - result.endColumn = static_cast(end.column()); - result.fileName = start.filePath(); - - return result; -} - -void IpcReceiver::references(const ReferencesMessage &message) -{ - qCDebug(log) << "<<< ReferencesMessage with" - << message.references().size() << "references"; - - const quint64 ticket = message.ticketNumber(); - const ReferencesEntry entry = m_referencesTable.take(ticket); - QFutureInterface futureInterface = entry.futureInterface; - QTC_CHECK(futureInterface != QFutureInterface()); - - if (futureInterface.isCanceled()) - return; // Editor document closed or a new request was issued making this result outdated. - - QTC_ASSERT(entry.textDocument, return); - futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message)); - futureInterface.reportFinished(); -} - -void IpcReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message) -{ - qCDebug(log) << "<<< FollowSymbolMessage with" - << message.sourceRange() << "range"; - - const quint64 ticket = message.ticketNumber(); - QFutureInterface futureInterface = m_followTable.take(ticket); - QTC_CHECK(futureInterface != QFutureInterface()); - - if (futureInterface.isCanceled()) - return; // Editor document closed or a new request was issued making this result outdated. - - futureInterface.reportResult(toSymbolInfo(message)); - futureInterface.reportFinished(); -} - -IpcSender::IpcSender(ClangCodeModelConnectionClient *connectionClient) - : m_connection(connectionClient) -{} - -void IpcSender::end() -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << ClangBackEnd::EndMessage(); - m_connection->sendEndMessage(); -} - -void IpcSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().registerTranslationUnitsForEditor(message); -} - -void IpcSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().updateTranslationUnitsForEditor(message); -} - -void IpcSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().unregisterTranslationUnitsForEditor(message); -} - -void IpcSender::registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().registerProjectPartsForEditor(message); -} - -void IpcSender::unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().unregisterProjectPartsForEditor(message); -} - -void IpcSender::registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().registerUnsavedFilesForEditor(message); -} - -void IpcSender::unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().unregisterUnsavedFilesForEditor(message); -} - -void IpcSender::completeCode(const CompleteCodeMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().completeCode(message); -} - -void IpcSender::requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().requestDocumentAnnotations(message); -} - -void IpcSender::requestReferences(const RequestReferencesMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().requestReferences(message); -} - -void IpcSender::requestFollowSymbol(const RequestFollowSymbolMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().requestFollowSymbol(message); -} - -void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) -{ - QTC_CHECK(m_connection->isConnected()); - qCDebug(log) << ">>>" << message; - m_connection->serverProxy().updateVisibleTranslationUnits(message); -} - -bool IpcSender::isConnected() const -{ - return m_connection && m_connection->isConnected(); -} - -class DummyIpcSender : public IpcSender -{ -public: - DummyIpcSender() : IpcSender(nullptr) {} - - void end() override {} - void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &) override {} - void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &) override {} - void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &) override {} - void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &) override {} - void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &) override {} - void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &) override {} - void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &) override {} - void completeCode(const ClangBackEnd::CompleteCodeMessage &) override {} - void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &) override {} - void requestReferences(const ClangBackEnd::RequestReferencesMessage &) override {} - void requestFollowSymbol(const RequestFollowSymbolMessage &) override {} - void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &) override {} -}; - -enum { backEndStartTimeOutInMs = 10000 }; - -IpcCommunicator::IpcCommunicator() - : m_connection(&m_ipcReceiver) - , m_ipcSender(new DummyIpcSender()) -{ - m_backendStartTimeOut.setSingleShot(true); - connect(&m_backendStartTimeOut, &QTimer::timeout, - this, &IpcCommunicator::logStartTimeOut); - - m_ipcReceiver.setAliveHandler([this]() { m_connection.resetProcessAliveTimer(); }); - - connect(Core::EditorManager::instance(), &Core::EditorManager::editorAboutToClose, - this, &IpcCommunicator::onEditorAboutToClose); - connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose, - this, &IpcCommunicator::setupDummySender); - - initializeBackend(); -} - -IpcCommunicator::~IpcCommunicator() -{ - disconnect(&m_connection, 0, this, 0); -} - -void IpcCommunicator::initializeBackend() -{ - const QString clangBackEndProcessPath = backendProcessPath(); - if (!QFileInfo(clangBackEndProcessPath).exists()) { - logExecutableDoesNotExist(); - return; - } - qCDebug(log) << "Starting" << clangBackEndProcessPath; - - m_connection.setProcessAliveTimerInterval(30 * 1000); - m_connection.setProcessPath(clangBackEndProcessPath); - - connect(&m_connection, &ConnectionClient::connectedToLocalSocket, - this, &IpcCommunicator::onConnectedToBackend); - connect(&m_connection, &ConnectionClient::disconnectedFromLocalSocket, - this, &IpcCommunicator::setupDummySender); - - m_connection.startProcessAndConnectToServerAsynchronously(); - m_backendStartTimeOut.start(backEndStartTimeOutInMs); -} - -static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart) -{ - const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, - CppTools::ProjectFile::Unsupported); // No language option - - return options; -} - -static ClangBackEnd::ProjectPartContainer toProjectPartContainer( - const CppTools::ProjectPart::Ptr &projectPart) -{ - const QStringList options = projectPartOptions(projectPart); - - return ClangBackEnd::ProjectPartContainer(projectPart->id(), Utf8StringVector(options)); -} - -static QVector toProjectPartContainers( - const QVector projectParts) -{ - QVector projectPartContainers; - projectPartContainers.reserve(projectParts.size()); - - foreach (const CppTools::ProjectPart::Ptr &projectPart, projectParts) - projectPartContainers << toProjectPartContainer(projectPart); - - return projectPartContainers; -} - -void IpcCommunicator::registerFallbackProjectPart() -{ - const auto projectPart = CppTools::CppModelManager::instance()->fallbackProjectPart(); - const auto projectPartContainer = toProjectPartContainer(projectPart); - - 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 = CppTools::CppToolsBridge::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()); -} - -bool IpcCommunicator::isNotWaitingForCompletion() const -{ - return !m_ipcReceiver.isExpectingCodeCompletedMessage(); -} - -void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, - const Utf8StringVector &visibleEditorsFilePaths) -{ - const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths); - m_ipcSender->updateVisibleTranslationUnits(message); -} - -void IpcCommunicator::registerCurrentProjectParts() -{ - using namespace CppTools; - - const QList projectInfos = CppModelManager::instance()->projectInfos(); - foreach (const ProjectInfo &projectInfo, projectInfos) - registerProjectsParts(projectInfo.projectParts()); -} - -void IpcCommunicator::restoreCppEditorDocuments() -{ - resetCppEditorDocumentProcessors(); - registerVisibleCppEditorDocumentAndMarkInvisibleDirty(); -} - -void IpcCommunicator::resetCppEditorDocumentProcessors() -{ - using namespace CppTools; - - const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments(); - foreach (CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) - cppEditorDocument->resetProcessor(); -} - -void IpcCommunicator::registerVisibleCppEditorDocumentAndMarkInvisibleDirty() -{ - CppTools::CppModelManager::instance()->updateCppEditorDocuments(); -} - -void IpcCommunicator::registerCurrentCodeModelUiHeaders() -{ - using namespace CppTools; - - const auto editorSupports = CppModelManager::instance()->abstractEditorSupports(); - foreach (const AbstractEditorSupport *es, editorSupports) { - const QString mappedPath - = ModelManagerSupportClang::instance()->dummyUiHeaderOnDiskPath(es->fileName()); - updateUnsavedFile(mappedPath, es->contents(), es->revision()); - } -} - -void IpcCommunicator::registerProjectsParts(const QVector projectParts) -{ - const auto projectPartContainers = toProjectPartContainers(projectParts); - registerProjectPartsForEditor(projectPartContainers); -} - -void IpcCommunicator::updateTranslationUnitFromCppEditorDocument(const QString &filePath) -{ - const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); - - updateTranslationUnit(filePath, document->contents(), document->revision()); -} - -void IpcCommunicator::updateUnsavedFileFromCppEditorDocument(const QString &filePath) -{ - const CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath); - - updateUnsavedFile(filePath, document->contents(), document->revision()); -} - -namespace { - - -} - -void IpcCommunicator::updateTranslationUnit(const QString &filePath, - const QByteArray &contents, - uint documentRevision) -{ - const bool hasUnsavedContent = true; - - updateTranslationUnitsForEditor({{filePath, - Utf8String(), - Utf8String::fromByteArray(contents), - hasUnsavedContent, - documentRevision}}); -} - -void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision) -{ - const bool hasUnsavedContent = true; - - // TODO: Send new only if changed - registerUnsavedFilesForEditor({{filePath, - Utf8String(), - Utf8String::fromByteArray(contents), - hasUnsavedContent, - documentRevision}}); -} - -static bool documentHasChanged(const QString &filePath, uint revision) -{ - if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) - return document->sendTracker().shouldSendRevision(revision); - - return true; -} - -static void setLastSentDocumentRevision(const QString &filePath, uint revision) -{ - if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) - document->sendTracker().setLastSentRevision(int(revision)); -} - -void IpcCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer &fileContainer) -{ - if (documentHasChanged(fileContainer.filePath(), fileContainer.documentRevision())) { - updateTranslationUnitsForEditor({fileContainer}); - setLastSentDocumentRevision(fileContainer.filePath(), - fileContainer.documentRevision()); - } -} - -void IpcCommunicator::requestDocumentAnnotations(const FileContainer &fileContainer) -{ - const RequestDocumentAnnotationsMessage message(fileContainer); - m_ipcSender->requestDocumentAnnotations(message); -} - -QFuture IpcCommunicator::requestReferences( - const FileContainer &fileContainer, - quint32 line, - quint32 column, - QTextDocument *textDocument, - const CppTools::SemanticInfo::LocalUseMap &localUses) -{ - const RequestReferencesMessage message(fileContainer, line, column); - m_ipcSender->requestReferences(message); - - return m_ipcReceiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument, - localUses); -} - -QFuture IpcCommunicator::requestFollowSymbol( - const FileContainer &curFileContainer, - const QVector &dependentFiles, - quint32 line, - quint32 column) -{ - const RequestFollowSymbolMessage message(curFileContainer, - dependentFiles, - line, - column); - m_ipcSender->requestFollowSymbol(message); - - return m_ipcReceiver.addExpectedRequestFollowSymbolMessage(message.ticketNumber()); -} - -void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document) -{ - const auto textDocument = qobject_cast(document); - const auto filePath = textDocument->filePath().toString(); - const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); - - updateTranslationUnitWithRevisionCheck(FileContainer(filePath, - projectPartId, - Utf8StringVector(), - textDocument->document()->revision())); -} - -void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) -{ - if (CppTools::CppEditorDocumentHandle *document = ClangCodeModel::Utils::cppDocument(filePath)) - document->sendTracker().applyContentChange(position); -} - -void IpcCommunicator::updateTranslationUnitIfNotCurrentDocument(Core::IDocument *document) -{ - QTC_ASSERT(document, return); - if (Core::EditorManager::currentDocument() != document) - updateTranslationUnit(document); -} - -void IpcCommunicator::updateTranslationUnit(Core::IDocument *document) -{ - updateTranslationUnitFromCppEditorDocument(document->filePath().toString()); -} - -void IpcCommunicator::updateUnsavedFile(Core::IDocument *document) -{ - QTC_ASSERT(document, return); - - updateUnsavedFileFromCppEditorDocument(document->filePath().toString()); -} - -void IpcCommunicator::onConnectedToBackend() -{ - m_backendStartTimeOut.stop(); - - ++m_connectedCount; - if (m_connectedCount > 1) - logRestartedDueToUnexpectedFinish(); - - m_ipcReceiver.reset(); - m_ipcSender.reset(new IpcSender(&m_connection)); - - initializeBackendWithCurrentData(); -} - -void IpcCommunicator::onEditorAboutToClose(Core::IEditor *editor) -{ - if (auto *textEditor = qobject_cast(editor)) - m_ipcReceiver.deleteProcessorsOfEditorWidget(textEditor->editorWidget()); -} - -void IpcCommunicator::setupDummySender() -{ - m_ipcSender.reset(new DummyIpcSender); -} - -void IpcCommunicator::logExecutableDoesNotExist() -{ - const QString msg - = tr("Clang Code Model: Error: " - "The clangbackend executable \"%1\" does not exist.") - .arg(QDir::toNativeSeparators(backendProcessPath())); - - logError(msg); -} - -void IpcCommunicator::logStartTimeOut() -{ - const QString msg - = tr("Clang Code Model: Error: " - "The clangbackend executable \"%1\" could not be started (timeout after %2ms).") - .arg(QDir::toNativeSeparators(backendProcessPath())) - .arg(backEndStartTimeOutInMs); - - logError(msg); -} - -void IpcCommunicator::logRestartedDueToUnexpectedFinish() -{ - const QString msg - = tr("Clang Code Model: Error: " - "The clangbackend process has finished unexpectedly and was restarted."); - - logError(msg); -} - -void IpcCommunicator::logError(const QString &text) -{ - const QString textWithTimestamp = QDateTime::currentDateTime().toString(Qt::ISODate) - + ' ' + text; - Core::MessageManager::write(textWithTimestamp, Core::MessageManager::Flash); - qWarning("%s", qPrintable(textWithTimestamp)); -} - -void IpcCommunicator::initializeBackendWithCurrentData() -{ - registerFallbackProjectPart(); - registerCurrentProjectParts(); - registerCurrentCodeModelUiHeaders(); - restoreCppEditorDocuments(); - updateTranslationUnitVisiblity(); - - emit backendReinitialized(); -} - -IpcSender *IpcCommunicator::setIpcSender(IpcSender *ipcSender) -{ - IpcSender *previousMessageSender = m_ipcSender.take(); - m_ipcSender.reset(ipcSender); - return previousMessageSender; -} - -void IpcCommunicator::killBackendProcess() -{ - m_connection.processForTestOnly()->kill(); -} - -void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fileContainers) -{ - const RegisterTranslationUnitForEditorMessage message(fileContainers, - currentCppEditorDocumentFilePath(), - visibleCppEditorDocumentsFilePaths()); - m_ipcSender->registerTranslationUnitsForEditor(message); -} - -void IpcCommunicator::updateTranslationUnitsForEditor(const IpcCommunicator::FileContainers &fileContainers) -{ - const UpdateTranslationUnitsForEditorMessage message(fileContainers); - m_ipcSender->updateTranslationUnitsForEditor(message); -} - -void IpcCommunicator::unregisterTranslationUnitsForEditor(const FileContainers &fileContainers) -{ - const UnregisterTranslationUnitsForEditorMessage message(fileContainers); - m_ipcSender->unregisterTranslationUnitsForEditor(message); -} - -void IpcCommunicator::registerProjectPartsForEditor( - const ProjectPartContainers &projectPartContainers) -{ - const RegisterProjectPartsForEditorMessage message(projectPartContainers); - m_ipcSender->registerProjectPartsForEditor(message); -} - -void IpcCommunicator::unregisterProjectPartsForEditor(const QStringList &projectPartIds) -{ - const UnregisterProjectPartsForEditorMessage message((Utf8StringVector(projectPartIds))); - m_ipcSender->unregisterProjectPartsForEditor(message); -} - -void IpcCommunicator::registerUnsavedFilesForEditor(const IpcCommunicator::FileContainers &fileContainers) -{ - const RegisterUnsavedFilesForEditorMessage message(fileContainers); - m_ipcSender->registerUnsavedFilesForEditor(message); -} - -void IpcCommunicator::unregisterUnsavedFilesForEditor(const IpcCommunicator::FileContainers &fileContainers) -{ - const UnregisterUnsavedFilesForEditorMessage message(fileContainers); - m_ipcSender->unregisterUnsavedFilesForEditor(message); -} - -void IpcCommunicator::completeCode(ClangCompletionAssistProcessor *assistProcessor, - const QString &filePath, - quint32 line, - quint32 column, - const QString &projectFilePath, - qint32 funcNameStartLine, - qint32 funcNameStartColumn) -{ - const CompleteCodeMessage message(filePath, line, column, projectFilePath, funcNameStartLine, - funcNameStartColumn); - m_ipcSender->completeCode(message); - m_ipcReceiver.addExpectedCodeCompletedMessage(message.ticketNumber(), assistProcessor); -} diff --git a/src/plugins/clangcodemodel/clangbackendlogging.cpp b/src/plugins/clangcodemodel/clangbackendlogging.cpp new file mode 100644 index 00000000000..47118ca22d5 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendlogging.cpp @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendlogging.h" + +namespace ClangCodeModel { +namespace Internal { + +Q_LOGGING_CATEGORY(ipcLog, "qtc.clangcodemodel.ipc") + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendlogging.h b/src/plugins/clangcodemodel/clangbackendlogging.h new file mode 100644 index 00000000000..6e2e3ec6893 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendlogging.h @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace ClangCodeModel { namespace Internal { + +Q_DECLARE_LOGGING_CATEGORY(ipcLog) + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp new file mode 100644 index 00000000000..9d620d6697d --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendreceiver.h" + +#include "clangbackendlogging.h" + +#include "clangcompletionassistprocessor.h" +#include "clangeditordocumentprocessor.h" + +#include + +#include + +#include +#include + +#include + +static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.ipc") + +using namespace ClangBackEnd; + +namespace ClangCodeModel { +namespace Internal { + +static bool printAliveMessageHelper() +{ + const bool print = qEnvironmentVariableIntValue("QTC_CLANG_FORCE_VERBOSE_ALIVE"); + if (!print) { + qCDebug(log) << "Hint: AliveMessage will not be printed. " + "Force it by setting QTC_CLANG_FORCE_VERBOSE_ALIVE=1."; + } + + return print; +} + +static bool printAliveMessage() +{ + static bool print = log().isDebugEnabled() ? printAliveMessageHelper() : false; + return print; +} + +BackendReceiver::BackendReceiver() +{ +} + +BackendReceiver::~BackendReceiver() +{ + reset(); +} + +void BackendReceiver::setAliveHandler(const BackendReceiver::AliveHandler &handler) +{ + m_aliveHandler = handler; +} + +void BackendReceiver::addExpectedCodeCompletedMessage( + quint64 ticket, + ClangCompletionAssistProcessor *processor) +{ + QTC_ASSERT(processor, return); + QTC_CHECK(!m_assistProcessorsTable.contains(ticket)); + m_assistProcessorsTable.insert(ticket, processor); +} + +void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget) +{ + QMutableHashIterator it(m_assistProcessorsTable); + while (it.hasNext()) { + it.next(); + ClangCompletionAssistProcessor *assistProcessor = it.value(); + if (assistProcessor->textEditorWidget() == textEditorWidget) { + delete assistProcessor; + it.remove(); + } + } +} + +QFuture BackendReceiver::addExpectedReferencesMessage( + quint64 ticket, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses) +{ + QTC_CHECK(textDocument); + QTC_CHECK(!m_referencesTable.contains(ticket)); + + QFutureInterface futureInterface; + futureInterface.reportStarted(); + + const ReferencesEntry entry{futureInterface, textDocument, localUses}; + m_referencesTable.insert(ticket, entry); + + return futureInterface.future(); +} + +QFuture BackendReceiver::addExpectedRequestFollowSymbolMessage(quint64 ticket) +{ + QTC_CHECK(!m_followTable.contains(ticket)); + + QFutureInterface futureInterface; + futureInterface.reportStarted(); + + m_followTable.insert(ticket, futureInterface); + + return futureInterface.future(); +} + +bool BackendReceiver::isExpectingCodeCompletedMessage() const +{ + return !m_assistProcessorsTable.isEmpty(); +} + +void BackendReceiver::reset() +{ + // Clean up waiting assist processors + qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end()); + m_assistProcessorsTable.clear(); + + // Clean up futures for references + for (ReferencesEntry &entry : m_referencesTable) + entry.futureInterface.cancel(); + m_referencesTable.clear(); + for (QFutureInterface &futureInterface : m_followTable) + futureInterface.cancel(); + m_followTable.clear(); +} + +void BackendReceiver::alive() +{ + if (printAliveMessage()) + qCDebug(log) << "<<< AliveMessage"; + QTC_ASSERT(m_aliveHandler, return); + m_aliveHandler(); +} + +void BackendReceiver::echo(const EchoMessage &message) +{ + qCDebug(log) << "<<<" << message; +} + +void BackendReceiver::codeCompleted(const CodeCompletedMessage &message) +{ + qCDebug(log) << "<<< CodeCompletedMessage with" << message.codeCompletions().size() << "items"; + + const quint64 ticket = message.ticketNumber(); + QScopedPointer processor(m_assistProcessorsTable.take(ticket)); + if (processor) { + processor->handleAvailableCompletions(message.codeCompletions(), + message.neededCorrection()); + } +} + +void BackendReceiver::documentAnnotationsChanged(const DocumentAnnotationsChangedMessage &message) +{ + qCDebug(log) << "<<< DocumentAnnotationsChangedMessage with" + << message.diagnostics().size() << "diagnostics" + << message.highlightingMarks().size() << "highlighting marks" + << message.skippedPreprocessorRanges().size() << "skipped preprocessor ranges"; + + auto processor = ClangEditorDocumentProcessor::get(message.fileContainer().filePath()); + + if (processor) { + const QString projectPartId = message.fileContainer().projectPartId(); + const QString filePath = message.fileContainer().filePath(); + const QString documentProjectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); + if (projectPartId == documentProjectPartId) { + const quint32 documentRevision = message.fileContainer().documentRevision(); + processor->updateCodeWarnings(message.diagnostics(), + message.firstHeaderErrorDiagnostic(), + documentRevision); + processor->updateHighlighting(message.highlightingMarks(), + message.skippedPreprocessorRanges(), + documentRevision); + } + } +} + +static +CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument, + const SourceRangeContainer &sourceRange) +{ + const SourceLocationContainer start = sourceRange.start(); + const SourceLocationContainer end = sourceRange.end(); + const unsigned length = end.column() - start.column(); + + const QTextBlock block = textDocument.findBlockByNumber(static_cast(start.line()) - 1); + const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), + static_cast(start.column())); + const uint column = start.column() - static_cast(shift); + + return CppTools::CursorInfo::Range(start.line(), column, length); +} + +static +CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses, + const ReferencesMessage &message) +{ + CppTools::CursorInfo result; + const QVector references = message.references(); + + result.areUseRangesForLocalVariable = message.isLocalVariable(); + for (const SourceRangeContainer &reference : references) + result.useRanges.append(toCursorInfoRange(textDocument, reference)); + + result.useRanges.reserve(references.size()); + result.localUses = localUses; + + return result; +} + +static +CppTools::SymbolInfo toSymbolInfo(const FollowSymbolMessage &message) +{ + CppTools::SymbolInfo result; + const SourceRangeContainer &range = message.sourceRange(); + + const SourceLocationContainer start = range.start(); + const SourceLocationContainer end = range.end(); + result.startLine = static_cast(start.line()); + result.startColumn = static_cast(start.column()); + result.endLine = static_cast(end.line()); + result.endColumn = static_cast(end.column()); + result.fileName = start.filePath(); + + return result; +} + +void BackendReceiver::references(const ReferencesMessage &message) +{ + qCDebug(log) << "<<< ReferencesMessage with" + << message.references().size() << "references"; + + const quint64 ticket = message.ticketNumber(); + const ReferencesEntry entry = m_referencesTable.take(ticket); + QFutureInterface futureInterface = entry.futureInterface; + QTC_CHECK(futureInterface != QFutureInterface()); + + if (futureInterface.isCanceled()) + return; // Editor document closed or a new request was issued making this result outdated. + + QTC_ASSERT(entry.textDocument, return); + futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message)); + futureInterface.reportFinished(); +} + +void BackendReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message) +{ + qCDebug(log) << "<<< FollowSymbolMessage with" + << message.sourceRange() << "range"; + + const quint64 ticket = message.ticketNumber(); + QFutureInterface futureInterface = m_followTable.take(ticket); + QTC_CHECK(futureInterface != QFutureInterface()); + + if (futureInterface.isCanceled()) + return; // Editor document closed or a new request was issued making this result outdated. + + futureInterface.reportResult(toSymbolInfo(message)); + futureInterface.reportFinished(); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.h b/src/plugins/clangcodemodel/clangbackendreceiver.h new file mode 100644 index 00000000000..d67db732239 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendreceiver.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include + +#include + +#include +#include +#include + +namespace TextEditor { class TextEditorWidget; } + +namespace ClangCodeModel { +namespace Internal { + +class ClangCompletionAssistProcessor; + +class BackendReceiver : public ClangBackEnd::ClangCodeModelClientInterface +{ +public: + BackendReceiver(); + ~BackendReceiver() override; + + using AliveHandler = std::function; + void setAliveHandler(const AliveHandler &handler); + + void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor); + void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget); + + QFuture + addExpectedReferencesMessage(quint64 ticket, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses); + QFuture addExpectedRequestFollowSymbolMessage(quint64 ticket); + bool isExpectingCodeCompletedMessage() const; + + void reset(); + +private: + void alive() override; + void echo(const ClangBackEnd::EchoMessage &message) override; + void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override; + + void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override; + void references(const ClangBackEnd::ReferencesMessage &message) override; + void followSymbol(const ClangBackEnd::FollowSymbolMessage &message) override; + +private: + AliveHandler m_aliveHandler; + QHash m_assistProcessorsTable; + + struct ReferencesEntry { + ReferencesEntry() = default; + ReferencesEntry(QFutureInterface futureInterface, + QTextDocument *textDocument, + const CppTools::SemanticInfo::LocalUseMap &localUses) + : futureInterface(futureInterface) + , textDocument(textDocument) + , localUses(localUses) {} + QFutureInterface futureInterface; + QPointer textDocument; + CppTools::SemanticInfo::LocalUseMap localUses; + }; + QHash m_referencesTable; + + QHash> m_followTable; +}; + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendsender.cpp b/src/plugins/clangcodemodel/clangbackendsender.cpp new file mode 100644 index 00000000000..b43b5dee4e2 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendsender.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clangbackendsender.h" + +#include "clangbackendlogging.h" + +#include +#include + +#include + +using namespace ClangBackEnd; + +namespace ClangCodeModel { +namespace Internal { + +BackendSender::BackendSender(ClangCodeModelConnectionClient *connectionClient) + : m_connection(connectionClient) +{} + +void BackendSender::end() +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << ClangBackEnd::EndMessage(); + m_connection->sendEndMessage(); +} + +void BackendSender::registerTranslationUnitsForEditor(const RegisterTranslationUnitForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().registerTranslationUnitsForEditor(message); +} + +void BackendSender::updateTranslationUnitsForEditor(const UpdateTranslationUnitsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().updateTranslationUnitsForEditor(message); +} + +void BackendSender::unregisterTranslationUnitsForEditor(const UnregisterTranslationUnitsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().unregisterTranslationUnitsForEditor(message); +} + +void BackendSender::registerProjectPartsForEditor(const RegisterProjectPartsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().registerProjectPartsForEditor(message); +} + +void BackendSender::unregisterProjectPartsForEditor(const UnregisterProjectPartsForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().unregisterProjectPartsForEditor(message); +} + +void BackendSender::registerUnsavedFilesForEditor(const RegisterUnsavedFilesForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().registerUnsavedFilesForEditor(message); +} + +void BackendSender::unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().unregisterUnsavedFilesForEditor(message); +} + +void BackendSender::completeCode(const CompleteCodeMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().completeCode(message); +} + +void BackendSender::requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestDocumentAnnotations(message); +} + +void BackendSender::requestReferences(const RequestReferencesMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestReferences(message); +} + +void BackendSender::requestFollowSymbol(const RequestFollowSymbolMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestFollowSymbol(message); +} + +void BackendSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().updateVisibleTranslationUnits(message); +} + +bool BackendSender::isConnected() const +{ + return m_connection && m_connection->isConnected(); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangbackendsender.h b/src/plugins/clangcodemodel/clangbackendsender.h new file mode 100644 index 00000000000..ca9238ae651 --- /dev/null +++ b/src/plugins/clangcodemodel/clangbackendsender.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace ClangBackEnd { class ClangCodeModelConnectionClient; } + +namespace ClangCodeModel { +namespace Internal { + +class BackendSender : public ClangBackEnd::ClangCodeModelServerInterface +{ +public: + BackendSender(ClangBackEnd::ClangCodeModelConnectionClient *connectionClient); + + void end() override; + void registerTranslationUnitsForEditor(const ClangBackEnd::RegisterTranslationUnitForEditorMessage &message) override; + void updateTranslationUnitsForEditor(const ClangBackEnd::UpdateTranslationUnitsForEditorMessage &message) override; + void unregisterTranslationUnitsForEditor(const ClangBackEnd::UnregisterTranslationUnitsForEditorMessage &message) override; + void registerProjectPartsForEditor(const ClangBackEnd::RegisterProjectPartsForEditorMessage &message) override; + void unregisterProjectPartsForEditor(const ClangBackEnd::UnregisterProjectPartsForEditorMessage &message) override; + void registerUnsavedFilesForEditor(const ClangBackEnd::RegisterUnsavedFilesForEditorMessage &message) override; + void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; + void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; + void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; + void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; + void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; + void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) override; + +private: + bool isConnected() const; + +private: + ClangBackEnd::ClangCodeModelConnectionClient *m_connection = nullptr; +}; + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index d48ce960ded..9f632dd4642 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -9,7 +9,10 @@ SOURCES += \ clangassistproposal.cpp \ clangassistproposalitem.cpp \ clangassistproposalmodel.cpp \ - clangbackendipcintegration.cpp \ + clangbackendcommunicator.cpp \ + clangbackendlogging.cpp \ + clangbackendreceiver.cpp \ + clangbackendsender.cpp \ clangcodemodelplugin.cpp \ clangcompletionassistinterface.cpp \ clangcompletionassistprocessor.cpp \ @@ -40,7 +43,10 @@ HEADERS += \ clangassistproposal.h \ clangassistproposalitem.h \ clangassistproposalmodel.h \ - clangbackendipcintegration.h \ + clangbackendcommunicator.h \ + clangbackendlogging.h \ + clangbackendreceiver.h \ + clangbackendsender.h \ clangcodemodelplugin.h \ clangcompletionassistinterface.h \ clangcompletionassistprocessor.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 699e5730329..cfee39fdbfe 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -41,8 +41,14 @@ QtcPlugin { "clangassistproposalitem.h", "clangassistproposalmodel.cpp", "clangassistproposalmodel.h", - "clangbackendipcintegration.cpp", - "clangbackendipcintegration.h", + "clangbackendcommunicator.cpp", + "clangbackendcommunicator.h", + "clangbackendlogging.cpp", + "clangbackendlogging.h", + "clangbackendreceiver.cpp", + "clangbackendreceiver.h", + "clangbackendsender.cpp", + "clangbackendsender.h", "clangcodemodelplugin.cpp", "clangcodemodelplugin.h", "clangcodemodel.qrc", diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp index 57e2cbcdf1a..0f5ec7bc1df 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp @@ -31,7 +31,7 @@ namespace ClangCodeModel { namespace Internal { ClangCompletionAssistInterface::ClangCompletionAssistInterface( - IpcCommunicator &ipcCommunicator, + BackendCommunicator &communicator, const TextEditor::TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -39,7 +39,7 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface( const CppTools::ProjectPartHeaderPaths &headerPaths, const CPlusPlus::LanguageFeatures &features) : AssistInterface(textEditorWidget->document(), position, fileName, reason) - , m_ipcCommunicator(ipcCommunicator) + , m_communicator(communicator) , m_headerPaths(headerPaths) , m_languageFeatures(features) , m_textEditorWidget(textEditorWidget) @@ -71,9 +71,9 @@ const TextEditor::TextEditorWidget *ClangCompletionAssistInterface::textEditorWi return m_textEditorWidget; } -IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const +BackendCommunicator &ClangCompletionAssistInterface::communicator() const { - return m_ipcCommunicator; + return m_communicator; } } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.h b/src/plugins/clangcodemodel/clangcompletionassistinterface.h index fc0724777e0..df198d8fcf5 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.h +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.h @@ -25,7 +25,7 @@ #pragma once -#include "clangbackendipcintegration.h" +#include "clangbackendcommunicator.h" #include "clangutils.h" #include @@ -36,7 +36,7 @@ namespace Internal { class ClangCompletionAssistInterface: public TextEditor::AssistInterface { public: - ClangCompletionAssistInterface(IpcCommunicator &ipcCommunicator, + ClangCompletionAssistInterface(BackendCommunicator &communicator, const TextEditor::TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -44,7 +44,7 @@ public: const CppTools::ProjectPartHeaderPaths &headerPaths, const CPlusPlus::LanguageFeatures &features); - IpcCommunicator &ipcCommunicator() const; + BackendCommunicator &communicator() const; bool objcEnabled() const; const CppTools::ProjectPartHeaderPaths &headerPaths() const; CPlusPlus::LanguageFeatures languageFeatures() const; @@ -53,7 +53,7 @@ public: void setHeaderPaths(const CppTools::ProjectPartHeaderPaths &headerPaths); // For tests private: - IpcCommunicator &m_ipcCommunicator; + BackendCommunicator &m_communicator; QStringList m_options; CppTools::ProjectPartHeaderPaths m_headerPaths; CPlusPlus::LanguageFeatures m_languageFeatures; diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index e60ac37ec6c..54d960ff03c 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -495,12 +495,12 @@ void ClangCompletionAssistProcessor::sendFileContent(const QByteArray &customFil // TODO: Revert custom modification after the completions const UnsavedFileContentInfo info = unsavedFileContent(customFileContent); - IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator(); - ipcCommunicator.updateTranslationUnitsForEditor({{m_interface->fileName(), - Utf8String(), - Utf8String::fromByteArray(info.unsavedContent), - info.isDocumentModified, - uint(m_interface->textDocument()->revision())}}); + BackendCommunicator &communicator = m_interface->communicator(); + communicator.updateTranslationUnitsForEditor({{m_interface->fileName(), + Utf8String(), + Utf8String::fromByteArray(info.unsavedContent), + info.isDocumentModified, + uint(m_interface->textDocument()->revision())}}); } namespace { bool shouldSendDocumentForCompletion(const QString &filePath, @@ -568,10 +568,9 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position, { const QString filePath = m_interface->fileName(); - auto &ipcCommunicator = m_interface->ipcCommunicator(); + auto &communicator = m_interface->communicator(); - if (shouldSendCodeCompletion(filePath, position) - || ipcCommunicator.isNotWaitingForCompletion()) { + if (shouldSendCodeCompletion(filePath, position) || communicator.isNotWaitingForCompletion()) { if (shouldSendDocumentForCompletion(filePath, position)) { sendFileContent(customFileContent); setLastDocumentRevision(filePath); @@ -580,9 +579,9 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position, const Position cursorPosition = extractLineColumn(position); const Position functionNameStart = extractLineColumn(functionNameStartPosition); const QString projectPartId = CppTools::CppToolsBridge::projectPartIdForFile(filePath); - ipcCommunicator.completeCode(this, filePath, uint(cursorPosition.line), - uint(cursorPosition.column), projectPartId, - functionNameStart.line, functionNameStart.column); + communicator.completeCode(this, filePath, uint(cursorPosition.line), + uint(cursorPosition.column), projectPartId, + functionNameStart.line, functionNameStart.column); setLastCompletionPosition(filePath, position); return true; } diff --git a/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp b/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp index 99abf8ab257..64b97957e74 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp @@ -43,8 +43,8 @@ namespace ClangCodeModel { namespace Internal { -ClangCompletionAssistProvider::ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator) - : m_ipcCommunicator(ipcCommunicator) +ClangCompletionAssistProvider::ClangCompletionAssistProvider(BackendCommunicator &communicator) + : m_communicator(communicator) { } @@ -67,7 +67,7 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac { const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath); if (projectPart) { - return new ClangCompletionAssistInterface(m_ipcCommunicator, + return new ClangCompletionAssistInterface(m_communicator, textEditorWidget, position, filePath, diff --git a/src/plugins/clangcodemodel/clangcompletionassistprovider.h b/src/plugins/clangcodemodel/clangcompletionassistprovider.h index 7c1ac168be2..12139b35d77 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprovider.h +++ b/src/plugins/clangcodemodel/clangcompletionassistprovider.h @@ -25,7 +25,7 @@ #pragma once -#include "clangbackendipcintegration.h" +#include "clangbackendcommunicator.h" #include @@ -39,7 +39,7 @@ class ClangCompletionAssistProvider : public CppTools::CppCompletionAssistProvid Q_OBJECT public: - ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator); + ClangCompletionAssistProvider(BackendCommunicator &communicator); IAssistProvider::RunType runType() const override; @@ -52,7 +52,7 @@ public: TextEditor::AssistReason reason) const override; private: - IpcCommunicator &m_ipcCommunicator; + BackendCommunicator &m_communicator; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 81053cef60e..3d2f2f5267e 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -25,7 +25,7 @@ #include "clangeditordocumentprocessor.h" -#include "clangbackendipcintegration.h" +#include "clangbackendcommunicator.h" #include "clangdiagnostictooltipwidget.h" #include "clangfixitoperation.h" #include "clangfixitoperationsextractor.h" @@ -67,12 +67,12 @@ namespace ClangCodeModel { namespace Internal { ClangEditorDocumentProcessor::ClangEditorDocumentProcessor( - IpcCommunicator &ipcCommunicator, + BackendCommunicator &communicator, TextEditor::TextDocument *document) : BaseEditorDocumentProcessor(document->document(), document->filePath().toString()) , m_document(*document) , m_diagnosticManager(document) - , m_ipcCommunicator(ipcCommunicator) + , m_communicator(communicator) , m_parser(new ClangEditorDocumentParser(document->filePath().toString())) , m_parserRevision(0) , m_semanticHighlighter(document) @@ -102,7 +102,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() m_parserWatcher.waitForFinished(); if (m_projectPart) { - m_ipcCommunicator.unregisterTranslationUnitsForEditor( + m_communicator.unregisterTranslationUnitsForEditor( {ClangBackEnd::FileContainer(filePath(), m_projectPart->id())}); } } @@ -343,11 +343,11 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams ¶m const CppTools::SemanticInfo::LocalUseMap localUses = CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column); - return m_ipcCommunicator.requestReferences(simpleFileContainer(), - static_cast(line), - static_cast(column), - textDocument(), - localUses); + return m_communicator.requestReferences(simpleFileContainer(), + static_cast(line), + static_cast(column), + textDocument(), + localUses); } static QVector prioritizeByBaseName(const QString &curPath, @@ -392,10 +392,10 @@ ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column) dependentFiles = prioritizeByBaseName(filePath(), fileDeps); } - return m_ipcCommunicator.requestFollowSymbol(simpleFileContainer(), - dependentFiles, - static_cast(line), - static_cast(column)); + return m_communicator.requestFollowSymbol(simpleFileContainer(), + dependentFiles, + static_cast(line), + static_cast(column)); } ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const @@ -456,10 +456,10 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr if (m_projectPart) { if (projectPart->id() == m_projectPart->id()) return; - m_ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); + m_communicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); } - m_ipcCommunicator.registerTranslationUnitsForEditor( + m_communicator.registerTranslationUnitsForEditor( {fileContainerWithArgumentsAndDocumentContent(projectPart)}); ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision()); } @@ -469,7 +469,7 @@ void ClangEditorDocumentProcessor::updateTranslationUnitIfProjectPartExists() if (m_projectPart) { const ClangBackEnd::FileContainer fileContainer = fileContainerWithDocumentContent(m_projectPart->id()); - m_ipcCommunicator.updateTranslationUnitWithRevisionCheck(fileContainer); + m_communicator.updateTranslationUnitWithRevisionCheck(fileContainer); } } @@ -477,7 +477,7 @@ void ClangEditorDocumentProcessor::requestDocumentAnnotations(const QString &pro { const auto fileContainer = fileContainerWithDocumentContent(projectpartId); - m_ipcCommunicator.requestDocumentAnnotations(fileContainer); + m_communicator.requestDocumentAnnotations(fileContainer); } CppTools::BaseEditorDocumentProcessor::HeaderErrorDiagnosticWidgetCreator diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index d7f7f966f50..a040cba256b 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -43,14 +43,14 @@ class FileContainer; namespace ClangCodeModel { namespace Internal { -class IpcCommunicator; +class BackendCommunicator; class ClangEditorDocumentProcessor : public CppTools::BaseEditorDocumentProcessor { Q_OBJECT public: - ClangEditorDocumentProcessor(IpcCommunicator &ipcCommunicator, + ClangEditorDocumentProcessor(BackendCommunicator &communicator, TextEditor::TextDocument *document); ~ClangEditorDocumentProcessor(); @@ -114,7 +114,7 @@ private: private: TextEditor::TextDocument &m_document; ClangDiagnosticManager m_diagnosticManager; - IpcCommunicator &m_ipcCommunicator; + BackendCommunicator &m_communicator; QSharedPointer m_parser; CppTools::ProjectPart::Ptr m_projectPart; bool m_isProjectFile = false; diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index c5d85045c51..df1e96869c3 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -66,7 +66,7 @@ static CppTools::CppModelManager *cppModelManager() } ModelManagerSupportClang::ModelManagerSupportClang() - : m_completionAssistProvider(m_ipcCommunicator) + : m_completionAssistProvider(m_communicator) { QTC_CHECK(!m_instance); m_instance = this; @@ -96,7 +96,7 @@ ModelManagerSupportClang::ModelManagerSupportClang() connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved, this, &ModelManagerSupportClang::onProjectPartsRemoved); - m_ipcCommunicator.registerFallbackProjectPart(); + m_communicator.registerFallbackProjectPart(); } ModelManagerSupportClang::~ModelManagerSupportClang() @@ -117,12 +117,12 @@ CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) { - return new ClangEditorDocumentProcessor(m_ipcCommunicator, baseTextDocument); + return new ClangEditorDocumentProcessor(m_communicator, baseTextDocument); } void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *) { - m_ipcCommunicator.updateTranslationUnitVisiblity(); + m_communicator.updateTranslationUnitVisiblity(); } void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument) @@ -195,7 +195,7 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor) void ModelManagerSupportClang::onEditorClosed(const QList &) { - m_ipcCommunicator.updateTranslationUnitVisiblity(); + m_communicator.updateTranslationUnitVisiblity(); } void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit() @@ -210,7 +210,7 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool if (success) { TextEditor::TextDocument *textDocument = qobject_cast(sender()); connectToTextDocumentContentsChangedForTranslationUnit(textDocument); - m_ipcCommunicator.updateTranslationUnitWithRevisionCheck(textDocument); + m_communicator.updateTranslationUnitWithRevisionCheck(textDocument); } } @@ -229,9 +229,9 @@ void ModelManagerSupportClang::onCppDocumentContentsChangedOnTranslationUnit(int { Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator.updateChangeContentStartPosition(document->filePath().toString(), + m_communicator.updateChangeContentStartPosition(document->filePath().toString(), position); - m_ipcCommunicator.updateTranslationUnitIfNotCurrentDocument(document); + m_communicator.updateTranslationUnitIfNotCurrentDocument(document); clearDiagnosticFixIts(document->filePath().toString()); } @@ -248,14 +248,14 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnUnsavedFile(bool suc if (success) { TextEditor::TextDocument *textDocument = qobject_cast(sender()); connectToTextDocumentContentsChangedForUnsavedFile(textDocument); - m_ipcCommunicator.updateUnsavedFile(textDocument); + m_communicator.updateUnsavedFile(textDocument); } } void ModelManagerSupportClang::onCppDocumentContentsChangedOnUnsavedFile() { Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator.updateUnsavedFile(document); + m_communicator.updateUnsavedFile(document); } void ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated(const QString &filePath, @@ -264,7 +264,7 @@ void ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated(const QStr QTC_ASSERT(!filePath.isEmpty(), return); const QString mappedPath = m_uiHeaderOnDiskManager.createIfNeeded(filePath); - m_ipcCommunicator.updateUnsavedFile(mappedPath, content, 0); + m_communicator.updateUnsavedFile(mappedPath, content, 0); } void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &filePath) @@ -274,7 +274,7 @@ void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &fil if (!cppModelManager()->cppEditorDocument(filePath)) { const QString mappedPath = m_uiHeaderOnDiskManager.remove(filePath); const QString projectPartId = Utils::projectPartIdForFile(filePath); - m_ipcCommunicator.unregisterUnsavedFilesForEditor({{mappedPath, projectPartId}}); + m_communicator.unregisterUnsavedFilesForEditor({{mappedPath, projectPartId}}); } } @@ -328,16 +328,16 @@ void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *p const CppTools::ProjectInfo projectInfo = cppModelManager()->projectInfo(project); QTC_ASSERT(projectInfo.isValid(), return); - m_ipcCommunicator.registerProjectsParts(projectInfo.projectParts()); - m_ipcCommunicator.registerFallbackProjectPart(); + m_communicator.registerProjectsParts(projectInfo.projectParts()); + m_communicator.registerFallbackProjectPart(); } void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectPartIds) { if (!projectPartIds.isEmpty()) { unregisterTranslationUnitsWithProjectParts(projectPartIds); - m_ipcCommunicator.unregisterProjectPartsForEditor(projectPartIds); - m_ipcCommunicator.registerFallbackProjectPart(); + m_communicator.unregisterProjectPartsForEditor(projectPartIds); + m_communicator.registerFallbackProjectPart(); } } @@ -363,7 +363,7 @@ void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts( { const auto processors = clangProcessorsWithProjectParts(projectPartIds); foreach (ClangEditorDocumentProcessor *processor, processors) { - m_ipcCommunicator.unregisterTranslationUnitsForEditor({processor->fileContainerWithArguments()}); + m_communicator.unregisterTranslationUnitsForEditor({processor->fileContainerWithArguments()}); processor->clearProjectPart(); processor->run(); } @@ -374,9 +374,9 @@ ModelManagerSupportClang *ModelManagerSupportClang::instance() return m_instance; } -IpcCommunicator &ModelManagerSupportClang::ipcCommunicator() +BackendCommunicator &ModelManagerSupportClang::communicator() { - return m_ipcCommunicator; + return m_communicator; } QString ModelManagerSupportClang::dummyUiHeaderOnDiskPath(const QString &filePath) const diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 78e5cd5694a..f87ac11923a 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -62,7 +62,7 @@ public: TextEditor::TextDocument *baseTextDocument) override; CppTools::FollowSymbolInterface &followSymbolInterface() override; - IpcCommunicator &ipcCommunicator(); + BackendCommunicator &communicator(); QString dummyUiHeaderOnDiskDirPath() const; QString dummyUiHeaderOnDiskPath(const QString &filePath) const; @@ -102,7 +102,7 @@ private: private: UiHeaderOnDiskManager m_uiHeaderOnDiskManager; - IpcCommunicator m_ipcCommunicator; + BackendCommunicator m_communicator; ClangCompletionAssistProvider m_completionAssistProvider; std::unique_ptr m_followSymbol; };