forked from qt-creator/qt-creator
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:
@@ -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
|
||||||
|
@@ -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 ¶ms);
|
explicit HoverRequest(const TextDocumentPositionParams ¶ms);
|
||||||
|
@@ -2344,35 +2344,38 @@ 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 MarkupContent * const markup = Utils::get_if<MarkupContent>(&content);
|
const HoverContent content = hover->content();
|
||||||
if (markup) {
|
const MarkupContent *const markup = Utils::get_if<MarkupContent>(&content);
|
||||||
const QString markupString = markup->content();
|
if (markup) {
|
||||||
|
const QString markupString = markup->content();
|
||||||
|
|
||||||
// Macros aren't locatable via the AST, so parse the formatted string.
|
// Macros aren't locatable via the AST, so parse the formatted string.
|
||||||
static const QString magicMacroPrefix = "### macro `";
|
static const QString magicMacroPrefix = "### macro `";
|
||||||
if (markupString.startsWith(magicMacroPrefix)) {
|
if (markupString.startsWith(magicMacroPrefix)) {
|
||||||
const int nameStart = magicMacroPrefix.length();
|
const int nameStart = magicMacroPrefix.length();
|
||||||
const int closingQuoteIndex = markupString.indexOf('`', nameStart);
|
const int closingQuoteIndex = markupString.indexOf('`', nameStart);
|
||||||
if (closingQuoteIndex != -1) {
|
if (closingQuoteIndex != -1) {
|
||||||
const QString macroName = markupString.mid(nameStart,
|
const QString macroName = markupString.mid(nameStart,
|
||||||
closingQuoteIndex - nameStart);
|
closingQuoteIndex - nameStart);
|
||||||
d->setHelpItemForTooltip(hoverResponse.id(), macroName, HelpItem::Macro);
|
d->setHelpItemForTooltip(hoverResponse.id(), macroName, HelpItem::Macro);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Is it the file path for an include directive?
|
// Is it the file path for an include directive?
|
||||||
QString cleanString = markupString;
|
QString cleanString = markupString;
|
||||||
cleanString.remove('`');
|
cleanString.remove('`');
|
||||||
const QStringList lines = cleanString.trimmed().split('\n');
|
const QStringList lines = cleanString.trimmed().split('\n');
|
||||||
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(),
|
||||||
HelpItem::Brief);
|
filePath.fileName(),
|
||||||
return;
|
HelpItem::Brief);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2382,7 +2385,11 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
|
|||||||
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);
|
||||||
|
@@ -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 (m_helpItemProvider) {
|
if (auto hover = Utils::get_if<Hover>(&(*result))) {
|
||||||
m_response = response;
|
if (m_helpItemProvider) {
|
||||||
m_helpItemProvider(response, m_uri);
|
m_response = response;
|
||||||
return;
|
m_helpItemProvider(response, m_uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setContent(hover->content());
|
||||||
}
|
}
|
||||||
setContent(result->content());
|
|
||||||
}
|
}
|
||||||
m_report(priority());
|
m_report(priority());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user