[clangd] Implement textDocument/hover
Summary: Implemention of textDocument/hover as described in LSP definition.
This patch adds a basic Hover implementation. When hovering a variable,
function, method or namespace, clangd will return a text containing the
declaration's scope, as well as the declaration of the hovered entity.
For example, for a variable:
Declared in class Foo::Bar
int hello = 2
For macros, the macro definition is returned.
This patch doesn't include:
- markdown support (the client I use doesn't support it yet)
- range support (optional in the Hover response)
- comments associated to variables/functions/classes
They are kept as future work to keep this patch simpler.
I added tests in XRefsTests.cpp. hover.test contains one simple
smoketest to make sure the feature works from a black box perspective.
Reviewers: malaperle, krasimir, bkramer, ilya-biryukov
Subscribers: sammccall, mgrang, klimek, rwols, ilya-biryukov, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D35894
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
Signed-off-by: William Enright <william.enright@polymtl.ca>
llvm-svn: 325395
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 07b563a..fb3f05a 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -386,6 +386,35 @@
O.map("position", R.position);
}
+static StringRef toTextKind(MarkupKind Kind) {
+ switch (Kind) {
+ case MarkupKind::PlainText:
+ return "plaintext";
+ case MarkupKind::Markdown:
+ return "markdown";
+ }
+ llvm_unreachable("Invalid MarkupKind");
+}
+
+json::Expr toJSON(const MarkupContent &MC) {
+ if (MC.Value.empty())
+ return nullptr;
+
+ return json::obj{
+ {"kind", toTextKind(MC.Kind)},
+ {"value", MC.Value},
+ };
+}
+
+json::Expr toJSON(const Hover &H) {
+ json::obj Result{{"contents", toJSON(H.Contents)}};
+
+ if (H.Range.hasValue())
+ Result["range"] = toJSON(*H.Range);
+
+ return std::move(Result);
+}
+
json::Expr toJSON(const CompletionItem &CI) {
assert(!CI.label.empty() && "completion item label is required");
json::obj Result{{"label", CI.label}};