malaperle updated this revision to Diff 187783.
malaperle added a comment.
Address comments.
Repository:
rCTE Clang Tools Extra
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55250/new/
https://reviews.llvm.org/D55250
Files:
clangd/ClangdLSPServer.cpp
clangd/ClangdLSPServer.h
clangd/Protocol.cpp
clangd/Protocol.h
clangd/XRefs.cpp
unittests/clangd/XRefsTests.cpp
Index: unittests/clangd/XRefsTests.cpp
===================================================================
--- unittests/clangd/XRefsTests.cpp
+++ unittests/clangd/XRefsTests.cpp
@@ -648,7 +648,25 @@
#define MACRO 2
#undef macro
)cpp",
- "#define MACRO",
+ "#define MACRO 1",
+ },
+ {
+ R"cpp(// Macro
+ #define MACRO 0
+ #define MACRO2 ^MACRO
+ )cpp",
+ "#define MACRO 0",
+ },
+ {
+ R"cpp(// Macro
+ #define MACRO {\
+ return 0;\
+ }
+ int main() ^MACRO
+ )cpp",
+ R"cpp(#define MACRO {\
+ return 0;\
+ })cpp",
},
{
R"cpp(// Forward class declaration
Index: clangd/XRefs.cpp
===================================================================
--- clangd/XRefs.cpp
+++ clangd/XRefs.cpp
@@ -537,13 +537,30 @@
return H;
}
-/// Generate a \p Hover object given the macro \p MacroInf.
-static Hover getHoverContents(llvm::StringRef MacroName) {
- Hover H;
-
- H.contents.value = "#define ";
- H.contents.value += MacroName;
+/// Generate a \p Hover object given the macro \p MacroDecl.
+static Hover getHoverContents(MacroDecl Decl, ParsedAST &AST) {
+ SourceManager &SM = AST.getASTContext().getSourceManager();
+ std::string Definition = Decl.Name;
+
+ // Try to get the full definition, not just the name
+ SourceLocation StartLoc = Decl.Info->getDefinitionLoc();
+ SourceLocation EndLoc = Decl.Info->getDefinitionEndLoc();
+ if (EndLoc.isValid()) {
+ EndLoc = Lexer::getLocForEndOfToken(EndLoc, 0, SM,
+ AST.getASTContext().getLangOpts());
+ bool Invalid;
+ StringRef Buffer = SM.getBufferData(SM.getFileID(StartLoc), &Invalid);
+ if (!Invalid) {
+ unsigned StartOffset = SM.getFileOffset(StartLoc);
+ unsigned EndOffset = SM.getFileOffset(EndLoc);
+ if (EndOffset <= Buffer.size() && StartOffset < EndOffset)
+ Definition = Buffer.substr(StartOffset, EndOffset - StartOffset).str();
+ }
+ }
+ Hover H;
+ H.contents.kind = MarkupKind::PlainText;
+ H.contents.value = "#define " + Definition;
return H;
}
@@ -667,7 +684,7 @@
auto Symbols = getSymbolAtPosition(AST, SourceLocationBeg);
if (!Symbols.Macros.empty())
- return getHoverContents(Symbols.Macros[0].Name);
+ return getHoverContents(Symbols.Macros[0], AST);
if (!Symbols.Decls.empty())
return getHoverContents(Symbols.Decls[0].D);
Index: clangd/Protocol.h
===================================================================
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -362,6 +362,10 @@
/// Client supports CodeAction return value for textDocument/codeAction.
/// textDocument.codeAction.codeActionLiteralSupport.
bool CodeActionStructure = false;
+
+ /// The supported set of MarkupKinds for hover.
+ /// textDocument.hover.contentFormat.
+ bool HoverSupportsMarkdown = false;
};
bool fromJSON(const llvm::json::Value &, ClientCapabilities &);
@@ -822,6 +826,7 @@
PlainText,
Markdown,
};
+bool fromJSON(const llvm::json::Value &, MarkupKind &);
struct MarkupContent {
MarkupKind kind = MarkupKind::PlainText;
Index: clangd/Protocol.cpp
===================================================================
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -245,6 +245,24 @@
DocumentSymbol->getBoolean("hierarchicalDocumentSymbolSupport"))
R.HierarchicalDocumentSymbol = *HierarchicalSupport;
}
+ if (auto *Hover = TextDocument->getObject("hover")) {
+ if (auto HoverMarkupKinds = Hover->get("contentFormat")) {
+ auto *A = HoverMarkupKinds->getAsArray();
+ if (!A) {
+ return false;
+ }
+
+ for (size_t I = 0; I < A->size(); ++I) {
+ MarkupKind KindOut;
+ if (fromJSON((*A)[I], KindOut)) {
+ if (KindOut == MarkupKind::Markdown) {
+ R.HoverSupportsMarkdown = true;
+ break;
+ }
+ }
+ }
+ }
+ }
}
if (auto *Workspace = O->getObject("workspace")) {
if (auto *Symbol = Workspace->getObject("symbol")) {
@@ -616,6 +634,19 @@
};
}
+bool fromJSON(const llvm::json::Value &E, MarkupKind &Out) {
+ if (auto T = E.getAsString()) {
+ if (*T == "plaintext")
+ Out = MarkupKind::PlainText;
+ else if (*T == "markdown")
+ Out = MarkupKind::Markdown;
+ else
+ return false;
+ return true;
+ }
+ return false;
+}
+
llvm::json::Value toJSON(const Hover &H) {
llvm::json::Object Result{{"contents", toJSON(H.contents)}};
Index: clangd/ClangdLSPServer.h
===================================================================
--- clangd/ClangdLSPServer.h
+++ clangd/ClangdLSPServer.h
@@ -146,6 +146,9 @@
bool SupportsHierarchicalDocumentSymbol = false;
/// Whether the client supports showing file status.
bool SupportFileStatus = false;
+ /// From capabilities of textDocument/hover.
+ bool HoverSupportsMarkdown = false;
+
// Store of the current versions of the open documents.
DraftStore DraftMgr;
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -331,6 +331,8 @@
SupportsHierarchicalDocumentSymbol =
Params.capabilities.HierarchicalDocumentSymbol;
SupportFileStatus = Params.initializationOptions.FileStatus;
+ HoverSupportsMarkdown = Params.capabilities.HoverSupportsMarkdown;
+
Reply(llvm::json::Object{
{{"capabilities",
llvm::json::Object{
@@ -802,8 +804,24 @@
void ClangdLSPServer::onHover(const TextDocumentPositionParams &Params,
Callback<llvm::Optional<Hover>> Reply) {
- Server->findHover(Params.textDocument.uri.file(), Params.position,
- std::move(Reply));
+
+ Server->findHover(
+ Params.textDocument.uri.file(), Params.position,
+ Bind(
+ [this](decltype(Reply) Reply, Expected<Optional<Hover>> H) {
+ if (!H)
+ return Reply(H.takeError());
+
+ // If the client supports Markdown, convert from plaintext here.
+ if (*H && HoverSupportsMarkdown) {
+ (*H)->contents.kind = MarkupKind::Markdown;
+ (*H)->contents.value =
+ llvm::formatv("```\n{0}\n```", (*H)->contents.value);
+ }
+
+ Reply(std::move(*H));
+ },
+ std::move(Reply)));
}
void ClangdLSPServer::applyConfiguration(
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits