LSP: fix hover request result

According to the protocol a hover request can also return a Null as a
result. Reflect this in the protocol implementation and adapt usages.

Change-Id: I14ce71639c64b6de00e9c1198617083c1a3de9eb
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-05-16 13:31:10 +02:00
parent 2b8d96465a
commit 52770b746e
4 changed files with 71 additions and 36 deletions

View File

@@ -403,4 +403,19 @@ Utils::optional<QJsonValue> CodeLens::data() const
return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt; return contains(dataKey) ? Utils::make_optional(value(dataKey)) : Utils::nullopt;
} }
HoverResult::HoverResult(const QJsonValue &value)
{
if (value.isObject())
emplace<Hover>(Hover(value.toObject()));
else
emplace<std::nullptr_t>(nullptr);
}
bool HoverResult::isValid() const
{
if (auto hover = Utils::get_if<Hover>(this))
return hover->isValid();
return true;
}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -101,8 +101,17 @@ public:
bool isValid() const override { return contains(contentsKey); } bool isValid() const override { return contains(contentsKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT HoverResult : public Utils::variant<Hover, std::nullptr_t>
{
public:
HoverResult() : variant(nullptr) {}
explicit HoverResult(const Hover &hover) : variant(hover) {}
explicit HoverResult(const QJsonValue &value);
bool isValid() const;
};
class LANGUAGESERVERPROTOCOL_EXPORT HoverRequest class LANGUAGESERVERPROTOCOL_EXPORT HoverRequest
: public Request<Hover, std::nullptr_t, TextDocumentPositionParams> : public Request<HoverResult, std::nullptr_t, TextDocumentPositionParams>
{ {
public: public:
explicit HoverRequest(const TextDocumentPositionParams &params); explicit HoverRequest(const TextDocumentPositionParams &params);

View File

@@ -2344,8 +2344,9 @@ void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cu
void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverResponse, void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverResponse,
const DocumentUri &uri) const DocumentUri &uri)
{ {
if (const Utils::optional<Hover> result = hoverResponse.result()) { if (const Utils::optional<HoverResult> result = hoverResponse.result()) {
const HoverContent content = result->content(); if (auto hover = Utils::get_if<Hover>(&(*result))) {
const HoverContent content = hover->content();
const MarkupContent *const markup = Utils::get_if<MarkupContent>(&content); const MarkupContent *const markup = Utils::get_if<MarkupContent>(&content);
if (markup) { if (markup) {
const QString markupString = markup->content(); const QString markupString = markup->content();
@@ -2370,19 +2371,25 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
if (!lines.isEmpty()) { if (!lines.isEmpty()) {
const auto filePath = Utils::FilePath::fromUserInput(lines.last().simplified()); const auto filePath = Utils::FilePath::fromUserInput(lines.last().simplified());
if (filePath.exists()) { if (filePath.exists()) {
d->setHelpItemForTooltip(hoverResponse.id(), filePath.fileName(), d->setHelpItemForTooltip(hoverResponse.id(),
filePath.fileName(),
HelpItem::Brief); HelpItem::Brief);
return; return;
} }
} }
} }
} }
}
const TextDocument * const doc = documentForFilePath(uri.toFilePath()); const TextDocument * const doc = documentForFilePath(uri.toFilePath());
QTC_ASSERT(doc, return); QTC_ASSERT(doc, return);
const auto astHandler = [this, uri, hoverResponse](const AstNode &ast, const MessageId &) { const auto astHandler = [this, uri, hoverResponse](const AstNode &ast, const MessageId &) {
const MessageId id = hoverResponse.id(); const MessageId id = hoverResponse.id();
const Range range = hoverResponse.result()->range().value_or(Range()); Range range;
if (const Utils::optional<HoverResult> result = hoverResponse.result()) {
if (auto hover = Utils::get_if<Hover>(&(*result)))
range = hover->range().value_or(Range());
}
const QList<AstNode> path = getAstPath(ast, range); const QList<AstNode> path = getAstPath(ast, range);
if (path.isEmpty()) { if (path.isEmpty()) {
d->setHelpItemForTooltip(id); d->setHelpItemForTooltip(id);

View File

@@ -58,8 +58,10 @@ void HoverHandler::setHelpItem(const LanguageServerProtocol::MessageId &msgId,
const Core::HelpItem &help) const Core::HelpItem &help)
{ {
if (msgId == m_response.id()) { if (msgId == m_response.id()) {
if (Utils::optional<Hover> result = m_response.result()) if (Utils::optional<HoverResult> result = m_response.result()) {
setContent(result->content()); if (auto hover = Utils::get_if<Hover>(&(*result)))
setContent(hover->content());
}
m_response = {}; m_response = {};
setLastHelpItemIdentified(help); setLastHelpItemIdentified(help);
m_report(priority()); m_report(priority());
@@ -129,13 +131,15 @@ void HoverHandler::handleResponse(const HoverRequest::Response &response)
if (m_client) if (m_client)
m_client->log(*error); m_client->log(*error);
} }
if (Utils::optional<Hover> result = response.result()) { if (Utils::optional<HoverResult> result = response.result()) {
if (auto hover = Utils::get_if<Hover>(&(*result))) {
if (m_helpItemProvider) { if (m_helpItemProvider) {
m_response = response; m_response = response;
m_helpItemProvider(response, m_uri); m_helpItemProvider(response, m_uri);
return; return;
} }
setContent(result->content()); setContent(hover->content());
}
} }
m_report(priority()); m_report(priority());
} }