LanguageClient: track all created diagnostic marks

Removing a block results in taking marks of that line out of the
document, but does not delete those marks. So we cannot rely on
iterating over marks of a document to delete all marks for a specific
file. Instead save all marks from text mark creator for a file path and
iterate this list to delete diagnostic marks.

Fixes: QTCREATORBUG-26585
Change-Id: Idc41fce5de4ade68f4a29c23ba02844701b44d3c
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-02-22 10:29:10 +01:00
parent ee4757a8e8
commit 3cf6d15096
3 changed files with 19 additions and 20 deletions

View File

@@ -617,7 +617,7 @@ void Client::activateDocument(TextEditor::TextDocument *document)
void Client::deactivateDocument(TextEditor::TextDocument *document) void Client::deactivateDocument(TextEditor::TextDocument *document)
{ {
m_diagnosticManager.hideDiagnostics(document); m_diagnosticManager.hideDiagnostics(document->filePath());
resetAssistProviders(document); resetAssistProviders(document);
document->setFormatter(nullptr); document->setFormatter(nullptr);
m_tokenSupport.clearHighlight(document); m_tokenSupport.clearHighlight(document);

View File

@@ -88,26 +88,19 @@ void DiagnosticManager::setDiagnostics(const LanguageServerProtocol::DocumentUri
const QList<LanguageServerProtocol::Diagnostic> &diagnostics, const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
const Utils::optional<int> &version) const Utils::optional<int> &version)
{ {
removeDiagnostics(uri); hideDiagnostics(uri.toFilePath());
m_diagnostics[uri] = {version, diagnostics}; m_diagnostics[uri] = {version, diagnostics};
} }
void DiagnosticManager::hideDiagnostics(TextDocument *doc) void DiagnosticManager::hideDiagnostics(const Utils::FilePath &filePath)
{ {
if (!doc)
return;
if (m_hideHandler) if (m_hideHandler)
m_hideHandler(); m_hideHandler();
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc)) if (auto doc = TextDocument::textDocumentForFilePath(filePath)) {
editor->editorWidget()->setExtraSelections(TextEditorWidget::CodeWarningsSelection, {}); for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc))
qDeleteAll(Utils::filtered(doc->marks(), Utils::equal(&TextMark::category, m_client->id()))); editor->editorWidget()->setExtraSelections(TextEditorWidget::CodeWarningsSelection, {});
} }
qDeleteAll(m_marks.take(filePath));
void DiagnosticManager::removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri)
{
hideDiagnostics(TextDocument::textDocumentForFilePath(uri.toFilePath()));
m_diagnostics.remove(uri);
} }
static QTextEdit::ExtraSelection toDiagnosticsSelections(const Diagnostic &diagnostic, static QTextEdit::ExtraSelection toDiagnosticsSelections(const Diagnostic &diagnostic,
@@ -130,11 +123,11 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version)
const FilePath &filePath = uri.toFilePath(); const FilePath &filePath = uri.toFilePath();
if (TextDocument *doc = TextDocument::textDocumentForFilePath(filePath)) { if (TextDocument *doc = TextDocument::textDocumentForFilePath(filePath)) {
QList<QTextEdit::ExtraSelection> extraSelections; QList<QTextEdit::ExtraSelection> extraSelections;
const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri); const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri);
if (versionedDiagnostics.version.value_or(version) == version) { if (versionedDiagnostics.version.value_or(version) == version) {
for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) { for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) {
extraSelections << toDiagnosticsSelections(diagnostic, doc->document()); extraSelections << toDiagnosticsSelections(diagnostic, doc->document());
doc->addMark(m_textMarkCreator(filePath, diagnostic)); m_marks[filePath].append(m_textMarkCreator(filePath, diagnostic));
} }
} }
@@ -164,7 +157,13 @@ TextEditor::TextMark *DiagnosticManager::createTextMark(const FilePath &filePath
void DiagnosticManager::clearDiagnostics() void DiagnosticManager::clearDiagnostics()
{ {
for (const DocumentUri &uri : m_diagnostics.keys()) for (const DocumentUri &uri : m_diagnostics.keys())
removeDiagnostics(uri); hideDiagnostics(uri.toFilePath());
m_diagnostics.clear();
if (!QTC_GUARD(m_marks.isEmpty())) {
for (const QList<TextEditor::TextMark *> &marks : qAsConst(m_marks))
qDeleteAll(marks);
m_marks.clear();
}
} }
QList<Diagnostic> DiagnosticManager::diagnosticsAt(const DocumentUri &uri, QList<Diagnostic> DiagnosticManager::diagnosticsAt(const DocumentUri &uri,

View File

@@ -56,10 +56,9 @@ public:
void setDiagnostics(const LanguageServerProtocol::DocumentUri &uri, void setDiagnostics(const LanguageServerProtocol::DocumentUri &uri,
const QList<LanguageServerProtocol::Diagnostic> &diagnostics, const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
const Utils::optional<int> &version); const Utils::optional<int> &version);
void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri, int version); void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri, int version);
void hideDiagnostics(TextEditor::TextDocument *doc); void hideDiagnostics(const Utils::FilePath &filePath);
void clearDiagnostics(); void clearDiagnostics();
@@ -81,6 +80,7 @@ private:
QList<LanguageServerProtocol::Diagnostic> diagnostics; QList<LanguageServerProtocol::Diagnostic> diagnostics;
}; };
QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics; QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics;
QMap<Utils::FilePath, QList<TextEditor::TextMark *>> m_marks;
TextMarkCreator m_textMarkCreator; TextMarkCreator m_textMarkCreator;
HideDiagnosticsHandler m_hideHandler; HideDiagnosticsHandler m_hideHandler;
Client *m_client; Client *m_client;