malaperle updated this revision to Diff 185959.
malaperle marked an inline comment as not done.
malaperle added a comment.

Remove temporary code.


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
@@ -331,6 +331,16 @@
 SymbolKind adjustKindToCapability(SymbolKind Kind,
                                   SymbolKindBitset &supportedSymbolKinds);
 
+enum class MarkupKind {
+  PlainText,
+  Markdown,
+};
+bool fromJSON(const llvm::json::Value &, MarkupKind &);
+constexpr auto MarkupKindMin = static_cast<size_t>(MarkupKind::PlainText);
+constexpr auto MarkupKindMax = static_cast<size_t>(MarkupKind::Markdown);
+using MarkupKindBitset = std::bitset<MarkupKindMax + 1>;
+bool fromJSON(const llvm::json::Value &, MarkupKindBitset &);
+
 // This struct doesn't mirror LSP!
 // The protocol defines deeply nested structures for client capabilities.
 // Instead of mapping them all, this just parses out the bits we care about.
@@ -362,6 +372,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.
+  llvm::Optional<MarkupKindBitset> HoverMarkupKinds;
 };
 bool fromJSON(const llvm::json::Value &, ClientCapabilities &);
 
@@ -818,11 +832,6 @@
 };
 bool fromJSON(const llvm::json::Value &, CompletionParams &);
 
-enum class MarkupKind {
-  PlainText,
-  Markdown,
-};
-
 struct MarkupContent {
   MarkupKind kind = MarkupKind::PlainText;
   std::string value;
Index: clangd/Protocol.cpp
===================================================================
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -245,6 +245,13 @@
               DocumentSymbol->getBoolean("hierarchicalDocumentSymbolSupport"))
         R.HierarchicalDocumentSymbol = *HierarchicalSupport;
     }
+    if (auto *Hover = TextDocument->getObject("hover")) {
+      if (auto HoverMarkupKinds = Hover->get("contentFormat")) {
+        R.HoverMarkupKinds.emplace();
+        if (!fromJSON(*HoverMarkupKinds, *R.HoverMarkupKinds))
+          return false;
+      }
+    }
   }
   if (auto *Workspace = O->getObject("workspace")) {
     if (auto *Symbol = Workspace->getObject("symbol")) {
@@ -615,6 +622,30 @@
       {"value", MC.value},
   };
 }
+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;
+}
+
+bool fromJSON(const llvm::json::Value &E, MarkupKindBitset &Out) {
+  if (auto *A = E.getAsArray()) {
+    for (size_t I = 0; I < A->size(); ++I) {
+      MarkupKind KindOut;
+      if (fromJSON((*A)[I], KindOut))
+        Out.set(size_t(KindOut));
+    }
+    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.
+  MarkupKindBitset HoverMarkupKinds;
+
   // Store of the current versions of the open documents.
   DraftStore DraftMgr;
 
Index: clangd/ClangdLSPServer.cpp
===================================================================
--- clangd/ClangdLSPServer.cpp
+++ clangd/ClangdLSPServer.cpp
@@ -331,6 +331,9 @@
   SupportsHierarchicalDocumentSymbol =
       Params.capabilities.HierarchicalDocumentSymbol;
   SupportFileStatus = Params.initializationOptions.FileStatus;
+  if (Params.capabilities.HoverMarkupKinds)
+    HoverMarkupKinds |= *Params.capabilities.HoverMarkupKinds;
+
   Reply(llvm::json::Object{
       {{"capabilities",
         llvm::json::Object{
@@ -802,8 +805,27 @@
 
 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.
+            const size_t MarkDownVal =
+                static_cast<size_t>(MarkupKind::Markdown);
+            if (*H && MarkDownVal < HoverMarkupKinds.size() &&
+                HoverMarkupKinds[MarkDownVal]) {
+              (*H)->contents.kind = MarkupKind::Markdown;
+              (*H)->contents.value =
+                  llvm::formatv("```C++\n{0}\n```", (*H)->contents.value);
+            }
+
+            Reply(std::move(*H));
+          },
+          std::move(Reply)));
 }
 
 void ClangdLSPServer::applyConfiguration(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to