forked from qt-creator/qt-creator
LanguageClient: support versioned diagnostics
Change-Id: Id182431f371201c7266fe0683e78fe56a8a9735b Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -42,6 +42,10 @@ public:
|
||||
void setDiagnostics(const QList<Diagnostic> &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
|
||||
{ return checkArray<Diagnostic>(error, diagnosticsKey); }
|
||||
};
|
||||
|
||||
@@ -946,9 +946,9 @@ void Client::removeAssistProcessor(TextEditor::IAssistProcessor *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()
|
||||
@@ -1219,7 +1219,7 @@ void Client::handleDiagnostics(const PublishDiagnosticsParams ¶ms)
|
||||
const DocumentUri &uri = params.uri();
|
||||
|
||||
const QList<Diagnostic> &diagnostics = params.diagnostics();
|
||||
m_diagnosticManager.setDiagnostics(uri, diagnostics);
|
||||
m_diagnosticManager.setDiagnostics(uri, diagnostics, params.version());
|
||||
if (LanguageClientManager::clientForUri(uri) == this) {
|
||||
m_diagnosticManager.showDiagnostics(uri);
|
||||
requestCodeActions(uri, diagnostics);
|
||||
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
|
||||
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
|
||||
const LanguageServerProtocol::DocumentUri &uri,
|
||||
const LanguageServerProtocol::Range &range) const;
|
||||
const QTextCursor &cursor) const;
|
||||
|
||||
bool start();
|
||||
bool reset();
|
||||
|
||||
@@ -76,10 +76,11 @@ DiagnosticManager::~DiagnosticManager()
|
||||
}
|
||||
|
||||
void DiagnosticManager::setDiagnostics(const LanguageServerProtocol::DocumentUri &uri,
|
||||
const QList<LanguageServerProtocol::Diagnostic> &diagnostics)
|
||||
const QList<LanguageServerProtocol::Diagnostic> &diagnostics,
|
||||
const Utils::optional<int> &version)
|
||||
{
|
||||
removeDiagnostics(uri);
|
||||
m_diagnostics[uri] = diagnostics;
|
||||
m_diagnostics[uri] = {version, diagnostics};
|
||||
}
|
||||
|
||||
void DiagnosticManager::hideDiagnostics(TextDocument *doc)
|
||||
@@ -115,10 +116,13 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri)
|
||||
const FilePath &filePath = uri.toFilePath();
|
||||
if (TextDocument *doc = TextDocument::textDocumentForFilePath(filePath)) {
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
for (const Diagnostic &diagnostic : m_diagnostics.value(uri)) {
|
||||
doc->addMark(new TextMark(filePath, diagnostic, m_clientId));
|
||||
extraSelections << toDiagnosticsSelections(diagnostic, doc->document());
|
||||
const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri);
|
||||
const int docRevision = doc->document()->revision();
|
||||
if (versionedDiagnostics.version.value_or(docRevision) == docRevision) {
|
||||
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)) {
|
||||
@@ -134,9 +138,16 @@ void DiagnosticManager::clearDiagnostics()
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ public:
|
||||
~DiagnosticManager();
|
||||
|
||||
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 showDiagnostics(const LanguageServerProtocol::DocumentUri &uri);
|
||||
@@ -52,10 +53,14 @@ public:
|
||||
|
||||
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
|
||||
const LanguageServerProtocol::DocumentUri &uri,
|
||||
const LanguageServerProtocol::Range &range) const;
|
||||
const QTextCursor &cursor) const;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ void HoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidget,
|
||||
auto uri = DocumentUri::fromFilePath(editorWidget->textDocument()->filePath());
|
||||
QTextCursor tc = editorWidget->textCursor();
|
||||
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()) {
|
||||
const QStringList messages = Utils::transform(diagnostics, &Diagnostic::message);
|
||||
setToolTip(messages.join('\n'));
|
||||
|
||||
@@ -115,7 +115,7 @@ IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInte
|
||||
auto uri = DocumentUri::fromFilePath(interface->filePath());
|
||||
params.setTextDocument(TextDocumentIdentifier(uri));
|
||||
CodeActionParams::CodeActionContext context;
|
||||
context.setDiagnostics(m_client->diagnosticsAt(uri, range));
|
||||
context.setDiagnostics(m_client->diagnosticsAt(uri, cursor));
|
||||
params.setContext(context);
|
||||
|
||||
CodeActionRequest request(params);
|
||||
|
||||
Reference in New Issue
Block a user