kadircet updated this revision to Diff 198630.
kadircet marked 23 inline comments as done.
kadircet added a comment.

- Address comments
- Make little modifications to existing tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61497/new/

https://reviews.llvm.org/D61497

Files:
  clang-tools-extra/clangd/ClangdLSPServer.cpp
  clang-tools-extra/clangd/ClangdServer.cpp
  clang-tools-extra/clangd/ClangdServer.h
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/XRefs.h
  clang-tools-extra/clangd/unittests/XRefsTests.cpp

Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -937,7 +937,7 @@
               ^auto i = {1,2};
             }
           )cpp",
-          "class std::initializer_list<int>",
+          "template<> class initializer_list<int> {}",
       },
       {
           R"cpp(// User defined conversion to auto
@@ -1012,7 +1012,7 @@
               return Bar();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// trailing return type
@@ -1021,7 +1021,7 @@
               return Bar();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// auto in function return
@@ -1030,7 +1030,7 @@
               return Bar();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// auto& in function return
@@ -1039,7 +1039,7 @@
               return Bar();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// auto* in function return
@@ -1049,7 +1049,7 @@
               return bar;
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// const auto& in function return
@@ -1058,7 +1058,7 @@
               return Bar();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// decltype(auto) in function return
@@ -1067,7 +1067,7 @@
               return Bar();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// decltype(auto) reference in function return
@@ -1136,7 +1136,7 @@
               ^decltype(test()) i = test();
             }
           )cpp",
-          "struct Bar",
+          "struct Bar {}",
       },
       {
           R"cpp(// decltype of var with decltype.
@@ -1185,7 +1185,8 @@
     auto AST = TU.build();
     if (auto H = getHover(AST, T.point())) {
       EXPECT_NE("", Test.ExpectedHover) << Test.Input;
-      EXPECT_EQ(H->contents.value, Test.ExpectedHover.str()) << Test.Input;
+      EXPECT_EQ(H->render().contents.value, Test.ExpectedHover.str())
+          << Test.Input;
     } else
       EXPECT_EQ("", Test.ExpectedHover.str()) << Test.Input;
   }
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -16,7 +16,10 @@
 #include "ClangdUnit.h"
 #include "Protocol.h"
 #include "index/Index.h"
+#include "index/SymbolLocation.h"
+#include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/Support/raw_ostream.h"
 #include <vector>
 
 namespace clang {
@@ -46,8 +49,53 @@
 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
                                                       Position Pos);
 
+/// Contains detailed information about a Symbol. Especially useful when
+/// generating hover responses. It is not serialized so that embedding clients
+/// can choose to serialize it w.r.t their UI capabilities.
+struct HoverInfo {
+  /// Represents parameters of a function, a template or a macro.
+  /// For example:
+  /// - void foo(ParamType Name = DefaultValue)
+  /// - #define FOO(Name)
+  /// - template <ParamType Name = DefaultType> class Foo {};
+  struct Param {
+    /// The pretty-printed parameter type, e.g. "int", or "typename" (in
+    /// TemplateParameters)
+    llvm::Optional<std::string> Type;
+    /// None for unnamed parameters.
+    llvm::Optional<std::string> Name;
+    /// None if no default is provided.
+    llvm::Optional<std::string> Default;
+  };
+
+  std::string Name;
+  std::string Scope;
+  llvm::Optional<Range> SymRange;
+  /// Scope containing the symbol. e.g, "global namespace", "function x::Y"
+  /// - None for deduced types, e.g "auto", "decltype" keywords.
+  llvm::Optional<std::string> ContainedIn;
+  SymbolKind Kind;
+  std::string Documentation;
+  /// Source code containing the definition of the symbol.
+  std::string Definition;
+
+  /// Pretty-printed variable type.
+  /// Set only for variables.
+  llvm::Optional<std::string> Type;
+  /// Set for functions and lambadas.
+  llvm::Optional<std::string> ReturnType;
+  /// Set for functions, lambdas and macros with parameters.
+  llvm::Optional<std::vector<Param>> Parameters;
+  /// Set for all template declarations(function, class, variable).
+  llvm::Optional<std::vector<Param>> TemplateParameters;
+
+  /// Lower to LSP struct.
+  Hover render() const;
+};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &);
+
 /// Get the hover information when hovering at \p Pos.
-llvm::Optional<Hover> getHover(ParsedAST &AST, Position Pos);
+llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos);
 
 /// Returns reference locations of the symbol at a specified \p Pos.
 /// \p Limit limits the number of results returned (0 means no limit).
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -7,21 +7,33 @@
 //===----------------------------------------------------------------------===//
 #include "XRefs.h"
 #include "AST.h"
+#include "CodeCompletionStrings.h"
 #include "FindSymbols.h"
 #include "Logger.h"
+#include "Protocol.h"
 #include "SourceCode.h"
 #include "URI.h"
 #include "index/Merge.h"
 #include "index/SymbolCollector.h"
 #include "index/SymbolLocation.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/IndexSymbol.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace clangd {
@@ -241,17 +253,17 @@
   return {DeclMacrosFinder.getFoundDecls(), DeclMacrosFinder.takeMacroInfos()};
 }
 
-Range getTokenRange(ParsedAST &AST, SourceLocation TokLoc) {
-  const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
-  SourceLocation LocEnd = Lexer::getLocForEndOfToken(
-      TokLoc, 0, SourceMgr, AST.getASTContext().getLangOpts());
+Range getTokenRange(ASTContext &AST, SourceLocation TokLoc) {
+  const SourceManager &SourceMgr = AST.getSourceManager();
+  SourceLocation LocEnd =
+      Lexer::getLocForEndOfToken(TokLoc, 0, SourceMgr, AST.getLangOpts());
   return {sourceLocToPosition(SourceMgr, TokLoc),
           sourceLocToPosition(SourceMgr, LocEnd)};
 }
 
-llvm::Optional<Location> makeLocation(ParsedAST &AST, SourceLocation TokLoc,
+llvm::Optional<Location> makeLocation(ASTContext &AST, SourceLocation TokLoc,
                                       llvm::StringRef TUPath) {
-  const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
+  const SourceManager &SourceMgr = AST.getSourceManager();
   const FileEntry *F = SourceMgr.getFileEntryForID(SourceMgr.getFileID(TokLoc));
   if (!F)
     return None;
@@ -299,8 +311,8 @@
   // As a consequence, there's no need to look them up in the index either.
   std::vector<LocatedSymbol> Result;
   for (auto M : Symbols.Macros) {
-    if (auto Loc =
-            makeLocation(AST, M.Info->getDefinitionLoc(), *MainFilePath)) {
+    if (auto Loc = makeLocation(AST.getASTContext(), M.Info->getDefinitionLoc(),
+                                *MainFilePath)) {
       LocatedSymbol Macro;
       Macro.Name = M.Name;
       Macro.PreferredDeclaration = *Loc;
@@ -320,7 +332,7 @@
 
   // Emit all symbol locations (declaration or definition) from AST.
   for (const Decl *D : Symbols.Decls) {
-    auto Loc = makeLocation(AST, findNameLoc(D), *MainFilePath);
+    auto Loc = makeLocation(AST.getASTContext(), findNameLoc(D), *MainFilePath);
     if (!Loc)
       continue;
 
@@ -441,6 +453,73 @@
   return std::move(RefFinder).take();
 }
 
+// FIXME: Expose in AST/Decl ?
+void printSpecifiers(llvm::raw_ostream &Out, const FunctionDecl *D) {
+  switch (D->getStorageClass()) {
+  case SC_None:
+    break;
+  case SC_Extern:
+    Out << "extern ";
+    break;
+  case SC_Static:
+    Out << "static ";
+    break;
+  case SC_PrivateExtern:
+    Out << "__private_extern__ ";
+    break;
+  case SC_Auto:
+  case SC_Register:
+    llvm_unreachable("invalid for functions");
+  }
+
+  if (D->isInlineSpecified())
+    Out << "inline ";
+  if (D->isVirtualAsWritten())
+    Out << "virtual ";
+  if (D->isModulePrivate())
+    Out << "__module_private__ ";
+  if (D->isConstexpr() && !D->isExplicitlyDefaulted())
+    Out << "constexpr ";
+
+  const CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
+  const CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
+  const CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
+  if ((CDecl && CDecl->isExplicitSpecified()) ||
+      (ConversionDecl && ConversionDecl->isExplicitSpecified()) ||
+      (GuideDecl && GuideDecl->isExplicitSpecified()))
+    Out << "explicit ";
+}
+
+void printSpecifiers(llvm::raw_ostream &Out, const DeclaratorDecl *DD) {
+  const VarDecl *D = dyn_cast<VarDecl>(DD);
+  if (!D)
+    return;
+
+  StorageClass SC = D->getStorageClass();
+  if (SC != SC_None)
+    Out << VarDecl::getStorageClassSpecifierString(SC) << " ";
+
+  switch (D->getTSCSpec()) {
+  case TSCS_unspecified:
+    break;
+  case TSCS___thread:
+    Out << "__thread ";
+    break;
+  case TSCS__Thread_local:
+    Out << "_Thread_local ";
+    break;
+  case TSCS_thread_local:
+    Out << "thread_local ";
+    break;
+  }
+
+  if (D->isModulePrivate())
+    Out << "__module_private__ ";
+
+  if (D->isConstexpr())
+    Out << "constexpr ";
+}
+
 } // namespace
 
 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
@@ -453,7 +532,7 @@
   std::vector<DocumentHighlight> Result;
   for (const auto &Ref : References) {
     DocumentHighlight DH;
-    DH.range = getTokenRange(AST, Ref.Loc);
+    DH.range = getTokenRange(AST.getASTContext(), Ref.Loc);
     if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write))
       DH.kind = DocumentHighlightKind::Write;
     else if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Read))
@@ -525,54 +604,175 @@
   return None;
 }
 
-/// Generate a \p Hover object given the declaration \p D.
-static Hover getHoverContents(const Decl *D) {
-  Hover H;
-  llvm::Optional<std::string> NamedScope = getScopeName(D);
+static std::string printDefinition(const Decl *D) {
+  std::string Definition;
+  {
+    llvm::raw_string_ostream OS(Definition);
+    PrintingPolicy Policy =
+        printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
+    D->print(OS, Policy);
+  }
+  return Definition;
+}
 
-  // Generate the "Declared in" section.
-  if (NamedScope) {
-    assert(!NamedScope->empty());
+static void printParams(llvm::raw_ostream &OS,
+                        const std::vector<HoverInfo::Param> &Params) {
+  for (size_t I = 0, E = Params.size(); I != E; ++I) {
+    if (I)
+      OS << ", ";
+    OS << Params.at(I);
+  }
+}
 
-    H.contents.value += "Declared in ";
-    H.contents.value += *NamedScope;
-    H.contents.value += "\n\n";
+static std::vector<HoverInfo::Param>
+fetchTemplateParameters(const TemplateParameterList *Params,
+                        const PrintingPolicy &PP) {
+  assert(Params);
+  std::vector<HoverInfo::Param> TempParameters;
+
+  for (const Decl *Param : *Params) {
+    HoverInfo::Param P;
+    P.Type.emplace();
+    if (const auto TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+      P.Type = TTP->wasDeclaredWithTypename() ? "typename" : "class";
+      if (TTP->isParameterPack())
+        *P.Type += "...";
+
+      P.Name.emplace();
+      llvm::raw_string_ostream Out(*P.Name);
+      Out << *TTP;
+      if (TTP->hasDefaultArgument())
+        P.Default = TTP->getDefaultArgument().getAsString(PP);
+    } else if (const auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+      if (IdentifierInfo *II = NTTP->getIdentifier())
+        P.Name = II->getName().str();
+
+      llvm::raw_string_ostream Out(*P.Type);
+      NTTP->getType().print(Out, PP);
+      if (NTTP->isParameterPack())
+        Out << "...";
+
+      if (NTTP->hasDefaultArgument()) {
+        P.Default.emplace();
+        llvm::raw_string_ostream Out(*P.Default);
+        NTTP->getDefaultArgument()->printPretty(Out, nullptr, PP);
+      }
+    } else if (const auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
+      llvm::raw_string_ostream OS(*P.Type);
+      OS << "template <";
+      printParams(
+          OS, fetchTemplateParameters(
+                  TTPD->getDescribedTemplate()->getTemplateParameters(), PP));
+      OS << "> class"; // FIXME: TemplateTemplateParameter doesn't store the
+                       // info on whether this param was a "typename" or
+                       // "class".
+      if (TTPD->hasDefaultArgument()) {
+        P.Default.emplace();
+        llvm::raw_string_ostream Out(*P.Default);
+        TTPD->getDefaultArgument().getArgument().print(PP, Out);
+      }
+    }
+    TempParameters.push_back(std::move(P));
   }
 
-  // We want to include the template in the Hover.
-  if (TemplateDecl *TD = D->getDescribedTemplate())
-    D = TD;
+  return TempParameters;
+}
 
-  std::string DeclText;
-  llvm::raw_string_ostream OS(DeclText);
+/// Generate a \p Hover object given the declaration \p D.
+static HoverInfo getHoverContents(const Decl *D) {
+  HoverInfo HI;
 
   PrintingPolicy Policy =
       printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
+  if (const NamedDecl *ND = llvm::dyn_cast<NamedDecl>(D)) {
+    HI.Documentation = getDeclComment(ND->getASTContext(), *ND);
+    HI.Name = printName(D->getASTContext(), *ND);
+    HI.Scope = splitQualifiedName(printQualifiedName(*ND)).first.str();
+  }
 
-  D->print(OS, Policy);
+  if (llvm::Optional<std::string> NamedScope = getScopeName(D)) {
+    assert(!NamedScope->empty());
+    HI.ContainedIn = std::move(*NamedScope);
+  }
+  HI.Kind = indexSymbolKindToSymbolKind(index::getSymbolInfo(D).Kind);
+
+  // Fill in template params.
+  if (const TemplateDecl *TD = D->getDescribedTemplate()) {
+    HI.TemplateParameters =
+        fetchTemplateParameters(TD->getTemplateParameters(), Policy);
+    D = TD;
+  } else if (const FunctionDecl *FD = D->getAsFunction()) {
+    if (const auto FTD = FD->getDescribedTemplate()) {
+      HI.TemplateParameters =
+          fetchTemplateParameters(FTD->getTemplateParameters(), Policy);
+      D = FTD;
+    }
+  }
 
-  OS.flush();
+  // Fill in types and params.
+  if (const FunctionDecl *FD = D->getAsFunction()) {
+    HI.ReturnType.emplace();
+    llvm::raw_string_ostream OS(*HI.ReturnType);
+    printSpecifiers(OS, FD);
+    FD->getReturnType().print(OS, Policy);
+
+    HI.Parameters.emplace();
+    for (const ParmVarDecl *PVD : FD->parameters()) {
+      HI.Parameters->emplace_back();
+      auto &P = HI.Parameters->back();
+      if (!PVD->getType().isNull()) {
+        P.Type.emplace();
+        llvm::raw_string_ostream OS(*P.Type);
+        printSpecifiers(OS, PVD);
+        PVD->getType().print(OS, Policy);
+      }
+      if (!PVD->getName().empty())
+        P.Name = PVD->getNameAsString();
+      if (PVD->hasDefaultArg()) {
+        P.Default.emplace();
+        llvm::raw_string_ostream Out(*P.Default);
+        PVD->getDefaultArg()->printPretty(Out, nullptr, Policy);
+      }
+    }
+    if (FD->isVariadic()) {
+      HI.Parameters->emplace_back();
+      HI.Parameters->back().Type = "...";
+    }
+  } else if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
+    HI.Type.emplace();
+    llvm::raw_string_ostream OS(*HI.Type);
+    printSpecifiers(OS, DD);
+    DD->getType().print(OS, Policy);
+  }
 
-  H.contents.value += DeclText;
-  return H;
+  HI.Definition = printDefinition(D);
+  return HI;
 }
 
 /// Generate a \p Hover object given the type \p T.
-static Hover getHoverContents(QualType T, ASTContext &ASTCtx) {
-  Hover H;
-  std::string TypeText;
-  llvm::raw_string_ostream OS(TypeText);
+static HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx) {
+  HoverInfo HI;
+  llvm::raw_string_ostream OS(HI.Name);
   PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
   T.print(OS, Policy);
-  OS.flush();
-  H.contents.value += TypeText;
-  return H;
+
+  if (const TagDecl *TD = T.getTypePtr()->getAsTagDecl()) {
+    HI.Scope = printQualifiedName(*TD);
+    HI.Kind = indexSymbolKindToSymbolKind(index::getSymbolInfo(TD).Kind);
+    HI.Definition = printDefinition(TD);
+    // FIXME: Populate documentation
+  }
+  return HI;
 }
 
 /// Generate a \p Hover object given the macro \p MacroDecl.
-static Hover getHoverContents(MacroDecl Decl, ParsedAST &AST) {
+static HoverInfo getHoverContents(MacroDecl Decl, ParsedAST &AST) {
+  HoverInfo HI;
   SourceManager &SM = AST.getASTContext().getSourceManager();
-  std::string Definition = Decl.Name;
+  HI.Name = Decl.Name;
+  HI.Kind = indexSymbolKindToSymbolKind(
+      index::getSymbolInfoForMacro(*Decl.Info).Kind);
+  // FIXME: Populate documentation
 
   // Try to get the full definition, not just the name
   SourceLocation StartLoc = Decl.Info->getDefinitionLoc();
@@ -586,14 +786,12 @@
       unsigned StartOffset = SM.getFileOffset(StartLoc);
       unsigned EndOffset = SM.getFileOffset(EndLoc);
       if (EndOffset <= Buffer.size() && StartOffset < EndOffset)
-        Definition = Buffer.substr(StartOffset, EndOffset - StartOffset).str();
+        HI.Definition =
+            ("#define " + Buffer.substr(StartOffset, EndOffset - StartOffset))
+                .str();
     }
   }
-
-  Hover H;
-  H.contents.kind = MarkupKind::PlainText;
-  H.contents.value = "#define " + Definition;
-  return H;
+  return HI;
 }
 
 namespace {
@@ -708,7 +906,7 @@
   return V.getDeducedType();
 }
 
-llvm::Optional<Hover> getHover(ParsedAST &AST, Position Pos) {
+llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   SourceLocation SourceLocationBeg =
       getBeginningOfIdentifier(AST, Pos, SourceMgr.getMainFileID());
@@ -748,7 +946,7 @@
   auto MainFileRefs = findRefs(Symbols.Decls, AST);
   for (const auto &Ref : MainFileRefs) {
     Location Result;
-    Result.range = getTokenRange(AST, Ref.Loc);
+    Result.range = getTokenRange(AST.getASTContext(), Ref.Loc);
     Result.uri = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
     Results.push_back(std::move(Result));
   }
@@ -991,5 +1189,69 @@
   return Result;
 }
 
+Hover HoverInfo::render() const {
+  Hover H;
+  H.range = SymRange;
+  H.contents.kind = MarkupKind::PlainText;
+  std::vector<std::string> Output;
+
+  if (ContainedIn)
+    H.contents.value = llvm::formatv("Declared in {0}\n\n", *ContainedIn);
+
+  if (Kind == SymbolKind::String) {
+    // We use SymbolKind::String for macro kinds
+    Output.push_back(Definition);
+  } else if (Type || ReturnType) {
+    // Variables or Functions
+    if (!Definition.empty())
+      Output.push_back(Definition);
+    else {
+      if (TemplateParameters) {
+        Output.emplace_back();
+        llvm::raw_string_ostream OS(Output.back());
+        OS << "template <";
+        printParams(OS, *TemplateParameters);
+        OS << '>';
+      }
+      if (Type)
+        Output.push_back(*Type);
+      else if (ReturnType)
+        Output.push_back(*ReturnType);
+
+      if (!Name.empty())
+        Output.push_back(Name);
+
+      if (Parameters) {
+        // We don't want space before parameters.
+        llvm::raw_string_ostream OS(Output.back());
+        OS << '(';
+        printParams(OS, *Parameters);
+        OS << ')';
+      }
+    }
+  } else {
+    // Types and namespaces
+    if (!Definition.empty())
+      Output.push_back(Definition);
+    else
+      Output.push_back(Name);
+  }
+  H.contents.value += llvm::join(Output, " ");
+  return H;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const HoverInfo::Param &P) {
+  std::vector<llvm::StringRef> Output;
+  if (P.Type)
+    Output.push_back(*P.Type);
+  if (P.Name)
+    Output.push_back(*P.Name);
+  OS << llvm::join(Output, " ");
+  if (P.Default)
+    OS << " = " << P.Default;
+  return OS;
+}
+
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -180,7 +180,7 @@
 
   /// Get code hover for a given position.
   void findHover(PathRef File, Position Pos,
-                 Callback<llvm::Optional<Hover>> CB);
+                 Callback<llvm::Optional<HoverInfo>> CB);
 
   /// Get information about type hierarchy for a given position.
   void typeHierarchy(PathRef File, Position Pos, int Resolve,
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -523,8 +523,8 @@
 }
 
 void ClangdServer::findHover(PathRef File, Position Pos,
-                             Callback<llvm::Optional<Hover>> CB) {
-  auto Action = [Pos](Callback<llvm::Optional<Hover>> CB,
+                             Callback<llvm::Optional<HoverInfo>> CB) {
+  auto Action = [Pos](Callback<llvm::Optional<HoverInfo>> CB,
                       llvm::Expected<InputsAndAST> InpAST) {
     if (!InpAST)
       return CB(InpAST.takeError());
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -839,7 +839,17 @@
 void ClangdLSPServer::onHover(const TextDocumentPositionParams &Params,
                               Callback<llvm::Optional<Hover>> Reply) {
   Server->findHover(Params.textDocument.uri.file(), Params.position,
-                    std::move(Reply));
+                    Bind(
+                        [](decltype(Reply) Reply,
+                           llvm::Expected<llvm::Optional<HoverInfo>> HIorErr) {
+                          if (!HIorErr)
+                            return Reply(HIorErr.takeError());
+                          const auto &HI = HIorErr.get();
+                          if (!HI)
+                            return Reply(llvm::None);
+                          return Reply(HI->render());
+                        },
+                        std::move(Reply)));
 }
 
 void ClangdLSPServer::onTypeHierarchy(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to