ClangCodeModel: Stop communicating with clangbackend

Change-Id: I9a5f4e7f0f94d33de9816cb643e6ec88cbf9ca15
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-04-28 17:15:39 +02:00
parent 6da7babc4a
commit 356b43e9aa
8 changed files with 9 additions and 315 deletions

View File

@@ -55,6 +55,7 @@
#include <cppeditor/cppvirtualfunctionassistprovider.h>
#include <cppeditor/cppvirtualfunctionproposalitem.h>
#include <cppeditor/semantichighlighter.h>
#include <cppeditor/cppsemanticinfo.h>
#include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h>
#include <languageclient/languageclientutils.h>

View File

@@ -66,21 +66,12 @@
namespace ClangCodeModel {
namespace Internal {
ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
BackendCommunicator &communicator,
TextEditor::TextDocument *document)
ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(TextEditor::TextDocument *document)
: BaseEditorDocumentProcessor(document->document(), document->filePath().toString())
, m_document(*document)
, m_communicator(communicator)
, m_parser(new ClangEditorDocumentParser(document->filePath().toString()))
, m_parserRevision(0)
, m_builtinProcessor(document)
{
m_updateBackendDocumentTimer.setSingleShot(true);
m_updateBackendDocumentTimer.setInterval(350);
connect(&m_updateBackendDocumentTimer, &QTimer::timeout,
this, &ClangEditorDocumentProcessor::updateBackendDocumentIfProjectPartExists);
connect(m_parser.data(), &ClangEditorDocumentParser::projectPartInfoUpdated,
this, &BaseEditorDocumentProcessor::projectPartInfoUpdated);
@@ -99,33 +90,9 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
m_parserSynchronizer.setCancelOnWait(true);
}
ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor()
{
m_updateBackendDocumentTimer.stop();
if (m_projectPart)
closeBackendDocument();
}
void ClangEditorDocumentProcessor::runImpl(
const CppEditor::BaseEditorDocumentParser::UpdateParams &updateParams)
{
m_updateBackendDocumentTimer.start();
// Run clang parser
disconnect(&m_parserWatcher, &QFutureWatcher<void>::finished,
this, &ClangEditorDocumentProcessor::onParserFinished);
m_parserWatcher.cancel();
m_parserWatcher.setFuture(QFuture<void>());
m_parserRevision = revision();
connect(&m_parserWatcher, &QFutureWatcher<void>::finished,
this, &ClangEditorDocumentProcessor::onParserFinished);
const QFuture<void> future = ::Utils::runAsync(&runParser, parser(), updateParams);
m_parserWatcher.setFuture(future);
m_parserSynchronizer.addFuture(future);
// Run builtin processor
m_builtinProcessor.runImpl(updateParams);
}
@@ -163,7 +130,7 @@ CPlusPlus::Snapshot ClangEditorDocumentProcessor::snapshot()
bool ClangEditorDocumentProcessor::isParserRunning() const
{
return m_parserWatcher.isRunning();
return m_builtinProcessor.isParserRunning();
}
bool ClangEditorDocumentProcessor::hasProjectPart() const
@@ -186,12 +153,6 @@ void ClangEditorDocumentProcessor::clearProjectPart()
return m_diagnosticConfigId;
}
void ClangEditorDocumentProcessor::editorDocumentTimerRestarted()
{
m_updateBackendDocumentTimer.stop(); // Wait for the next call to run().
m_invalidationState = InvalidationState::Scheduled;
}
void ClangEditorDocumentProcessor::setParserConfig(
const CppEditor::BaseEditorDocumentParser::Configuration &config)
{
@@ -217,110 +178,5 @@ ClangEditorDocumentProcessor *ClangEditorDocumentProcessor::get(const QString &f
CppEditor::CppModelManager::cppEditorDocumentProcessor(filePath));
}
static bool isProjectPartLoadedOrIsFallback(CppEditor::ProjectPart::ConstPtr projectPart)
{
return projectPart
&& (projectPart->id().isEmpty() || isProjectPartLoaded(projectPart));
}
void ClangEditorDocumentProcessor::updateBackendProjectPartAndDocument()
{
const CppEditor::ProjectPart::ConstPtr projectPart = m_parser->projectPartInfo().projectPart;
if (isProjectPartLoadedOrIsFallback(projectPart)) {
updateBackendDocument(*projectPart.data());
m_projectPart = projectPart;
m_isProjectFile = m_parser->projectPartInfo().hints
& CppEditor::ProjectPartInfo::IsFromProjectMatch;
}
}
void ClangEditorDocumentProcessor::onParserFinished()
{
if (revision() != m_parserRevision)
return;
updateBackendProjectPartAndDocument();
}
void ClangEditorDocumentProcessor::updateBackendDocument(const CppEditor::ProjectPart &projectPart)
{
// On registration we send the document content immediately as an unsaved
// file, because
// (1) a refactoring action might have opened and already modified
// this document.
// (2) it prevents an extra preamble generation on first user
// modification of the document in case the line endings on disk
// differ from the ones returned by textDocument()->toPlainText(),
// like on Windows.
if (m_projectPart) {
if (projectPart.id() == m_projectPart->id())
return;
}
ProjectExplorer::Project * const project = CppEditor::projectForProjectPart(projectPart);
const CppEditor::ClangDiagnosticConfig config = warningsConfigForProject(project);
const QStringList clangOptions = createClangOptions(projectPart, filePath(), config,
optionsForProject(project));
m_diagnosticConfigId = config.id();
m_communicator.documentsOpened(
{fileContainerWithOptionsAndDocumentContent(clangOptions, projectPart.headerPaths)});
setLastSentDocumentRevision(filePath(), revision());
}
void ClangEditorDocumentProcessor::closeBackendDocument()
{
QTC_ASSERT(m_projectPart, return);
m_communicator.documentsClosed({ClangBackEnd::FileContainer(filePath(), m_projectPart->id())});
}
void ClangEditorDocumentProcessor::updateBackendDocumentIfProjectPartExists()
{
if (m_projectPart) {
const ClangBackEnd::FileContainer fileContainer = fileContainerWithDocumentContent();
m_communicator.documentsChangedWithRevisionCheck(fileContainer);
}
}
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer(
const QByteArray &codecName) const
{
return ClangBackEnd::FileContainer(filePath(),
Utf8String(),
false,
revision(),
Utf8String::fromByteArray(codecName));
}
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithOptionsAndDocumentContent(
const QStringList &compilationArguments, const ProjectExplorer::HeaderPaths headerPaths) const
{
auto theHeaderPaths
= ::Utils::transform<QVector>(headerPaths, [](const ProjectExplorer::HeaderPath path) {
return Utf8String(QDir::toNativeSeparators(path.path));
});
theHeaderPaths << QDir::toNativeSeparators(
ClangModelManagerSupport::instance()->dummyUiHeaderOnDiskDirPath());
return ClangBackEnd::FileContainer(filePath(),
Utf8StringVector(compilationArguments),
theHeaderPaths,
textDocument()->toPlainText(),
true,
revision());
}
ClangBackEnd::FileContainer
ClangEditorDocumentProcessor::fileContainerWithDocumentContent() const
{
return ClangBackEnd::FileContainer(filePath(),
textDocument()->toPlainText(),
true,
revision());
}
} // namespace Internal
} // namespace ClangCodeModel

View File

@@ -35,7 +35,6 @@
#include <utils/id.h>
#include <QFutureWatcher>
#include <QTimer>
namespace ClangBackEnd {
class DiagnosticContainer;
@@ -46,16 +45,12 @@ class FileContainer;
namespace ClangCodeModel {
namespace Internal {
class BackendCommunicator;
class ClangEditorDocumentProcessor : public CppEditor::BaseEditorDocumentProcessor
{
Q_OBJECT
public:
ClangEditorDocumentProcessor(BackendCommunicator &communicator,
TextEditor::TextDocument *document);
~ClangEditorDocumentProcessor() override;
ClangEditorDocumentProcessor(TextEditor::TextDocument *document);
// BaseEditorDocumentProcessor interface
void runImpl(const CppEditor::BaseEditorDocumentParser::UpdateParams &updateParams) override;
@@ -72,15 +67,11 @@ public:
::Utils::Id diagnosticConfigId() const;
void editorDocumentTimerRestarted() override;
void setParserConfig(const CppEditor::BaseEditorDocumentParser::Configuration &config) override;
CppEditor::BaseEditorDocumentParser::Configuration parserConfig() const;
QFuture<CppEditor::CursorInfo> cursorInfo(const CppEditor::CursorInfoParams &params) override;
void closeBackendDocument();
public:
static ClangEditorDocumentProcessor *get(const QString &filePath);
@@ -88,30 +79,11 @@ signals:
void parserConfigChanged(const Utils::FilePath &filePath,
const CppEditor::BaseEditorDocumentParser::Configuration &config);
private:
void onParserFinished();
void updateBackendProjectPartAndDocument();
void updateBackendDocument(const CppEditor::ProjectPart &projectPart);
void updateBackendDocumentIfProjectPartExists();
ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const;
ClangBackEnd::FileContainer fileContainerWithOptionsAndDocumentContent(
const QStringList &compilationArguments,
const ProjectExplorer::HeaderPaths headerPaths) const;
ClangBackEnd::FileContainer fileContainerWithDocumentContent() const;
private:
TextEditor::TextDocument &m_document;
BackendCommunicator &m_communicator;
QSharedPointer<ClangEditorDocumentParser> m_parser;
CppEditor::ProjectPart::ConstPtr m_projectPart;
::Utils::Id m_diagnosticConfigId;
bool m_isProjectFile = false;
QFutureWatcher<void> m_parserWatcher;
QTimer m_updateBackendDocumentTimer;
unsigned m_parserRevision;
enum class InvalidationState { Off, Scheduled, Canceled } m_invalidationState;
CppEditor::BuiltinEditorDocumentProcessor m_builtinProcessor;
Utils::FutureSynchronizer m_parserSynchronizer;

View File

@@ -122,8 +122,6 @@ ClangModelManagerSupport::ClangModelManagerSupport() : m_refactoringEngine(new R
this, &ClangModelManagerSupport::onEditorOpened);
connect(editorManager, &Core::EditorManager::currentEditorChanged,
this, &ClangModelManagerSupport::onCurrentEditorChanged);
connect(editorManager, &Core::EditorManager::editorsClosed,
this, &ClangModelManagerSupport::onEditorClosed);
CppEditor::CppModelManager *modelManager = cppModelManager();
connect(modelManager, &CppEditor::CppModelManager::abstractEditorSupportContentsUpdated,
@@ -242,7 +240,7 @@ bool ClangModelManagerSupport::hasSpecialHoverHandler(
CppEditor::BaseEditorDocumentProcessor *ClangModelManagerSupport::createEditorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument)
{
const auto processor = new ClangEditorDocumentProcessor(m_communicator, baseTextDocument);
const auto processor = new ClangEditorDocumentProcessor(baseTextDocument);
const auto handleConfigChange = [this](const Utils::FilePath &fp,
const BaseEditorDocumentParser::Configuration &config) {
if (const auto client = clientForFile(fp))
@@ -255,8 +253,6 @@ CppEditor::BaseEditorDocumentProcessor *ClangModelManagerSupport::createEditorDo
void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
{
m_communicator.documentVisibilityChanged();
// Update task hub issues for current CppEditorDocument
ProjectExplorer::TaskHub::clearTasks(Constants::TASK_CATEGORY_DIAGNOSTICS);
if (!editor || !editor->document() || !cppModelManager()->isCppEditor(editor))
@@ -270,50 +266,6 @@ void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
}
}
void ClangModelManagerSupport::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument)
{
// Handle externally changed documents
connect(textDocument, &Core::IDocument::aboutToReload,
this, &ClangModelManagerSupport::onCppDocumentAboutToReloadOnTranslationUnit,
Qt::UniqueConnection);
connect(textDocument, &Core::IDocument::reloadFinished,
this, &ClangModelManagerSupport::onCppDocumentReloadFinishedOnTranslationUnit,
Qt::UniqueConnection);
// Handle changes from e.g. refactoring actions
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
}
void ClangModelManagerSupport::connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument)
{
// Handle externally changed documents
connect(textDocument, &Core::IDocument::aboutToReload,
this, &ClangModelManagerSupport::onCppDocumentAboutToReloadOnUnsavedFile,
Qt::UniqueConnection);
connect(textDocument, &Core::IDocument::reloadFinished,
this, &ClangModelManagerSupport::onCppDocumentReloadFinishedOnUnsavedFile,
Qt::UniqueConnection);
// Handle changes from e.g. refactoring actions
connectToTextDocumentContentsChangedForUnsavedFile(textDocument);
}
void ClangModelManagerSupport::connectToTextDocumentContentsChangedForTranslationUnit(
TextEditor::TextDocument *textDocument)
{
connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
this, &ClangModelManagerSupport::onCppDocumentContentsChangedOnTranslationUnit,
Qt::UniqueConnection);
}
void ClangModelManagerSupport::connectToTextDocumentContentsChangedForUnsavedFile(
TextEditor::TextDocument *textDocument)
{
connect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
this, &ClangModelManagerSupport::onCppDocumentContentsChangedOnUnsavedFile,
Qt::UniqueConnection);
}
void ClangModelManagerSupport::connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget)
{
const auto widget = qobject_cast<TextEditor::TextEditorWidget *>(editorWidget);
@@ -589,7 +541,6 @@ void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor)
auto textDocument = qobject_cast<TextEditor::TextDocument *>(document);
if (textDocument && cppModelManager()->isCppEditor(editor)) {
connectTextDocumentToTranslationUnit(textDocument);
connectToWidgetsMarkContextMenuRequested(editor->widget());
// TODO: Ensure that not fully loaded documents are updated?
@@ -606,60 +557,6 @@ void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor)
}
}
void ClangModelManagerSupport::onEditorClosed(const QList<Core::IEditor *> &)
{
m_communicator.documentVisibilityChanged();
}
void ClangModelManagerSupport::onCppDocumentAboutToReloadOnTranslationUnit()
{
auto textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
disconnect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
this, &ClangModelManagerSupport::onCppDocumentContentsChangedOnTranslationUnit);
}
void ClangModelManagerSupport::onCppDocumentReloadFinishedOnTranslationUnit(bool success)
{
if (success) {
auto textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
connectToTextDocumentContentsChangedForTranslationUnit(textDocument);
m_communicator.documentsChangedWithRevisionCheck(textDocument);
}
}
void ClangModelManagerSupport::onCppDocumentContentsChangedOnTranslationUnit(int position,
int /*charsRemoved*/,
int /*charsAdded*/)
{
auto document = qobject_cast<Core::IDocument *>(sender());
m_communicator.updateChangeContentStartPosition(document->filePath().toString(),
position);
m_communicator.documentsChangedIfNotCurrentDocument(document);
}
void ClangModelManagerSupport::onCppDocumentAboutToReloadOnUnsavedFile()
{
auto textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
disconnect(textDocument, &TextEditor::TextDocument::contentsChangedWithPosition,
this, &ClangModelManagerSupport::onCppDocumentContentsChangedOnUnsavedFile);
}
void ClangModelManagerSupport::onCppDocumentReloadFinishedOnUnsavedFile(bool success)
{
if (success) {
auto textDocument = qobject_cast<TextEditor::TextDocument *>(sender());
connectToTextDocumentContentsChangedForUnsavedFile(textDocument);
m_communicator.unsavedFilesUpdated(textDocument);
}
}
void ClangModelManagerSupport::onCppDocumentContentsChangedOnUnsavedFile()
{
auto document = qobject_cast<Core::IDocument *>(sender());
m_communicator.unsavedFilesUpdated(document);
}
void ClangModelManagerSupport::onAbstractEditorSupportContentsUpdated(const QString &filePath,
const QString &,
const QByteArray &content)
@@ -669,8 +566,7 @@ void ClangModelManagerSupport::onAbstractEditorSupportContentsUpdated(const QStr
if (content.size() == 0)
return; // Generation not yet finished.
const QString mappedPath = m_uiHeaderOnDiskManager.write(filePath, content);
m_communicator.unsavedFilesUpdated(mappedPath, content, 0);
m_uiHeaderOnDiskManager.write(filePath, content);
ClangdClient::handleUiHeaderChange(Utils::FilePath::fromString(filePath).fileName());
}
@@ -679,9 +575,7 @@ void ClangModelManagerSupport::onAbstractEditorSupportRemoved(const QString &fil
QTC_ASSERT(!filePath.isEmpty(), return);
if (!cppModelManager()->cppEditorDocument(filePath)) {
const QString mappedPath = m_uiHeaderOnDiskManager.remove(filePath);
const QString projectPartId = projectPartIdForFile(filePath);
m_communicator.unsavedFilesRemoved({{mappedPath, projectPartId}});
m_uiHeaderOnDiskManager.remove(filePath);
ClangdClient::handleUiHeaderChange(Utils::FilePath::fromString(filePath).fileName());
}
}
@@ -860,7 +754,6 @@ void ClangModelManagerSupport::reinitializeBackendDocuments(const QStringList &p
{
const auto processors = clangProcessorsWithProjectParts(projectPartIds);
foreach (ClangEditorDocumentProcessor *processor, processors) {
processor->closeBackendDocument();
processor->clearProjectPart();
processor->run();
}
@@ -871,11 +764,6 @@ ClangModelManagerSupport *ClangModelManagerSupport::instance()
return m_instance;
}
BackendCommunicator &ClangModelManagerSupport::communicator()
{
return m_communicator;
}
QString ClangModelManagerSupport::dummyUiHeaderOnDiskPath(const QString &filePath) const
{
return m_uiHeaderOnDiskManager.mapPath(filePath);

View File

@@ -25,7 +25,6 @@
#pragma once
#include "clangbackendcommunicator.h"
#include "clanguiheaderondiskmanager.h"
#include <cppeditor/cppmodelmanagersupport.h>
@@ -44,8 +43,9 @@ class QMenu;
class QWidget;
QT_END_NAMESPACE
namespace TextEditor { class TextEditorWidget; }
namespace Core { class IEditor; }
namespace CppEditor { class RefactoringEngineInterface; }
namespace TextEditor { class TextEditorWidget; }
namespace ClangCodeModel {
namespace Internal {
@@ -74,7 +74,6 @@ public:
bool supportsLocalUses(const TextEditor::TextDocument *document) const override;
bool hasSpecialHoverHandler(const TextEditor::TextDocument *document) const override;
BackendCommunicator &communicator();
QString dummyUiHeaderOnDiskDirPath() const;
QString dummyUiHeaderOnDiskPath(const QString &filePath) const;
@@ -96,16 +95,7 @@ private:
Utils::ProcessLinkCallback &&processLinkCallback) override;
void onEditorOpened(Core::IEditor *editor);
void onEditorClosed(const QList<Core::IEditor *> &editors);
void onCurrentEditorChanged(Core::IEditor *newCurrent);
void onCppDocumentAboutToReloadOnTranslationUnit();
void onCppDocumentReloadFinishedOnTranslationUnit(bool success);
void onCppDocumentContentsChangedOnTranslationUnit(int position,
int charsRemoved,
int charsAdded);
void onCppDocumentAboutToReloadOnUnsavedFile();
void onCppDocumentReloadFinishedOnUnsavedFile(bool success);
void onCppDocumentContentsChangedOnUnsavedFile();
void onAbstractEditorSupportContentsUpdated(const QString &filePath,
const QString &sourceFilePath,
@@ -128,10 +118,6 @@ private:
void reinitializeBackendDocuments(const QStringList &projectPartIds);
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
void connectTextDocumentToUnsavedFiles(TextEditor::TextDocument *textDocument);
void connectToTextDocumentContentsChangedForTranslationUnit(
TextEditor::TextDocument *textDocument);
void connectToTextDocumentContentsChangedForUnsavedFile(TextEditor::TextDocument *textDocument);
void connectToWidgetsMarkContextMenuRequested(QWidget *editorWidget);
void updateLanguageClient(ProjectExplorer::Project *project,
@@ -142,7 +128,6 @@ private:
void watchForInternalChanges();
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
BackendCommunicator m_communicator;
std::unique_ptr<CppEditor::RefactoringEngineInterface> m_refactoringEngine;
QHash<ProjectExplorer::Project *, ClangProjectSettings *> m_projectSettings;

View File

@@ -70,10 +70,6 @@ BaseEditorDocumentProcessor::extraRefactoringOperations(const TextEditor::Assist
return TextEditor::QuickFixOperations();
}
void BaseEditorDocumentProcessor::editorDocumentTimerRestarted()
{
}
void BaseEditorDocumentProcessor::invalidateDiagnostics()
{
}

View File

@@ -83,8 +83,6 @@ public:
virtual void invalidateDiagnostics();
virtual void editorDocumentTimerRestarted();
virtual void setParserConfig(const BaseEditorDocumentParser::Configuration &config);
virtual QFuture<CursorInfo> cursorInfo(const CursorInfoParams &params) = 0;

View File

@@ -282,7 +282,6 @@ void CppEditorDocument::scheduleProcessDocument()
m_processorRevision = document()->revision();
m_processorTimer.start();
processor()->editorDocumentTimerRestarted();
}
void CppEditorDocument::processDocument()
@@ -291,7 +290,6 @@ void CppEditorDocument::processDocument()
if (processor()->isParserRunning() || m_processorRevision != contentsRevision()) {
m_processorTimer.start();
processor()->editorDocumentTimerRestarted();
return;
}