LanguageClient: support versioned diagnostics

Change-Id: Id182431f371201c7266fe0683e78fe56a8a9735b
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-02-01 14:16:34 +01:00
parent 5860addcd2
commit e6d0ed3160
7 changed files with 37 additions and 17 deletions

View File

@@ -42,6 +42,10 @@ public:
void setDiagnostics(const QList<Diagnostic> &diagnostics) void setDiagnostics(const QList<Diagnostic> &diagnostics)
{ insertArray(diagnosticsKey, diagnostics); } { insertArray(diagnosticsKey, diagnostics); }
Utils::optional<int> version() const { return optionalValue<int>(versionKey); }
void setVersion(int version) { insert(versionKey, version); }
void clearVersion() { remove(versionKey); }
bool isValid(ErrorHierarchy *error) const override bool isValid(ErrorHierarchy *error) const override
{ return checkArray<Diagnostic>(error, diagnosticsKey); } { return checkArray<Diagnostic>(error, diagnosticsKey); }
}; };

View File

@@ -946,9 +946,9 @@ void Client::removeAssistProcessor(TextEditor::IAssistProcessor *processor)
m_runningAssistProcessors.remove(processor); m_runningAssistProcessors.remove(processor);
} }
QList<Diagnostic> Client::diagnosticsAt(const DocumentUri &uri, const Range &range) const QList<Diagnostic> Client::diagnosticsAt(const DocumentUri &uri, const QTextCursor &cursor) const
{ {
return m_diagnosticManager.diagnosticsAt(uri, range); return m_diagnosticManager.diagnosticsAt(uri, cursor);
} }
bool Client::start() bool Client::start()
@@ -1219,7 +1219,7 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams &params)
const DocumentUri &uri = params.uri(); const DocumentUri &uri = params.uri();
const QList<Diagnostic> &diagnostics = params.diagnostics(); const QList<Diagnostic> &diagnostics = params.diagnostics();
m_diagnosticManager.setDiagnostics(uri, diagnostics); m_diagnosticManager.setDiagnostics(uri, diagnostics, params.version());
if (LanguageClientManager::clientForUri(uri) == this) { if (LanguageClientManager::clientForUri(uri) == this) {
m_diagnosticManager.showDiagnostics(uri); m_diagnosticManager.showDiagnostics(uri);
requestCodeActions(uri, diagnostics); requestCodeActions(uri, diagnostics);

View File

@@ -152,7 +152,7 @@ public:
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt( QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
const LanguageServerProtocol::DocumentUri &uri, const LanguageServerProtocol::DocumentUri &uri,
const LanguageServerProtocol::Range &range) const; const QTextCursor &cursor) const;
bool start(); bool start();
bool reset(); bool reset();

View File

@@ -76,10 +76,11 @@ DiagnosticManager::~DiagnosticManager()
} }
void DiagnosticManager::setDiagnostics(const LanguageServerProtocol::DocumentUri &uri, void DiagnosticManager::setDiagnostics(const LanguageServerProtocol::DocumentUri &uri,
const QList<LanguageServerProtocol::Diagnostic> &diagnostics) const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
const Utils::optional<int> &version)
{ {
removeDiagnostics(uri); removeDiagnostics(uri);
m_diagnostics[uri] = diagnostics; m_diagnostics[uri] = {version, diagnostics};
} }
void DiagnosticManager::hideDiagnostics(TextDocument *doc) void DiagnosticManager::hideDiagnostics(TextDocument *doc)
@@ -115,10 +116,13 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri)
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);
for (const Diagnostic &diagnostic : m_diagnostics.value(uri)) { const int docRevision = doc->document()->revision();
doc->addMark(new TextMark(filePath, diagnostic, m_clientId)); if (versionedDiagnostics.version.value_or(docRevision) == docRevision) {
extraSelections << toDiagnosticsSelections(diagnostic, doc->document()); for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) {
doc->addMark(new TextMark(filePath, diagnostic, m_clientId));
extraSelections << toDiagnosticsSelections(diagnostic, doc->document());
}
} }
for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc)) { for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(doc)) {
@@ -134,9 +138,16 @@ void DiagnosticManager::clearDiagnostics()
removeDiagnostics(uri); removeDiagnostics(uri);
} }
QList<Diagnostic> DiagnosticManager::diagnosticsAt(const DocumentUri &uri, const Range &range) const QList<Diagnostic> DiagnosticManager::diagnosticsAt(const DocumentUri &uri,
const QTextCursor &cursor) const
{ {
return Utils::filtered(m_diagnostics.value(uri), [range](const Diagnostic &diagnostic) { const int documentRevision = cursor.document()->revision();
auto it = m_diagnostics.find(uri);
if (it == m_diagnostics.end())
return {};
if (documentRevision != it->version.value_or(documentRevision))
return {};
return Utils::filtered(it->diagnostics, [range = Range(cursor)](const Diagnostic &diagnostic) {
return diagnostic.range().overlaps(range); return diagnostic.range().overlaps(range);
}); });
} }

View File

@@ -42,7 +42,8 @@ public:
~DiagnosticManager(); ~DiagnosticManager();
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);
void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri); void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri); void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
@@ -52,10 +53,14 @@ public:
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt( QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
const LanguageServerProtocol::DocumentUri &uri, const LanguageServerProtocol::DocumentUri &uri,
const LanguageServerProtocol::Range &range) const; const QTextCursor &cursor) const;
private: private:
QMap<LanguageServerProtocol::DocumentUri, QList<LanguageServerProtocol::Diagnostic>> m_diagnostics; struct VersionedDiagnostics {
Utils::optional<int> version;
QList<LanguageServerProtocol::Diagnostic> diagnostics;
};
QMap<LanguageServerProtocol::DocumentUri, VersionedDiagnostics> m_diagnostics;
Utils::Id m_clientId; Utils::Id m_clientId;
}; };

View File

@@ -66,7 +66,7 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
auto uri = DocumentUri::fromFilePath(editorWidget->textDocument()->filePath()); auto uri = DocumentUri::fromFilePath(editorWidget->textDocument()->filePath());
QTextCursor tc = editorWidget->textCursor(); QTextCursor tc = editorWidget->textCursor();
tc.setPosition(pos); tc.setPosition(pos);
QList<Diagnostic> diagnostics = m_client->diagnosticsAt(uri, Range(Position(tc), Position(tc))); const QList<Diagnostic> &diagnostics = m_client->diagnosticsAt(uri, tc);
if (!diagnostics.isEmpty()) { if (!diagnostics.isEmpty()) {
const QStringList messages = Utils::transform(diagnostics, &Diagnostic::message); const QStringList messages = Utils::transform(diagnostics, &Diagnostic::message);
setToolTip(messages.join('\n')); setToolTip(messages.join('\n'));

View File

@@ -115,7 +115,7 @@ IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInte
auto uri = DocumentUri::fromFilePath(interface->filePath()); auto uri = DocumentUri::fromFilePath(interface->filePath());
params.setTextDocument(TextDocumentIdentifier(uri)); params.setTextDocument(TextDocumentIdentifier(uri));
CodeActionParams::CodeActionContext context; CodeActionParams::CodeActionContext context;
context.setDiagnostics(m_client->diagnosticsAt(uri, range)); context.setDiagnostics(m_client->diagnosticsAt(uri, cursor));
params.setContext(context); params.setContext(context);
CodeActionRequest request(params); CodeActionRequest request(params);