[clangd] Use the active file's language for hover code blocks
authorDavid Goldman <davg@google.com>
Mon, 23 Aug 2021 17:58:43 +0000 (13:58 -0400)
committerDavid Goldman <davg@google.com>
Fri, 3 Sep 2021 15:38:27 +0000 (11:38 -0400)
This helps improve the syntax highlighting for Objective-C code,
although it currently doesn't work well in VS Code with
methods/properties/ivars since we don't currently include the proper
decl context (e.g. class).

Differential Revision: https://reviews.llvm.org/D108584

clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

index 763125c..8ef7d20 100644 (file)
@@ -131,6 +131,13 @@ std::string printDefinition(const Decl *D, const PrintingPolicy &PP) {
   return Definition;
 }
 
+const char *getMarkdownLanguage(const ASTContext &Ctx) {
+  const auto &LangOpts = Ctx.getLangOpts();
+  if (LangOpts.ObjC && LangOpts.CPlusPlus)
+    return "objective-cpp";
+  return LangOpts.ObjC ? "objective-c" : "cpp";
+}
+
 std::string printType(QualType QT, const PrintingPolicy &PP) {
   // TypePrinter doesn't resolve decltypes, so resolve them here.
   // FIXME: This doesn't handle composite types that contain a decltype in them.
@@ -1007,6 +1014,7 @@ llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
   if (auto Formatted =
           tooling::applyAllReplacements(HI->Definition, Replacements))
     HI->Definition = *Formatted;
+  HI->DefinitionLanguage = getMarkdownLanguage(AST.getASTContext());
   HI->SymRange = halfOpenToRange(SM, HighlightRange);
 
   return HI;
index 457cc55..72efe5a 100644 (file)
@@ -939,6 +939,39 @@ class Foo {})cpp";
   }
 }
 
+TEST(Hover, DefinitionLanuage) {
+  struct {
+    const char *const Code;
+    const std::string ClangLanguageFlag;
+    const char *const ExpectedDefinitionLanguage;
+  } Cases[] = {{R"cpp(
+          void [[some^Global]]() {}
+          )cpp",
+                "", "cpp"},
+               {R"cpp(
+          void [[some^Global]]() {}
+          )cpp",
+                "-xobjective-c++", "objective-cpp"},
+               {R"cpp(
+          void [[some^Global]]() {}
+          )cpp",
+                "-xobjective-c", "objective-c"}};
+  for (const auto &Case : Cases) {
+    SCOPED_TRACE(Case.Code);
+
+    Annotations T(Case.Code);
+    TestTU TU = TestTU::withCode(T.code());
+    if (!Case.ClangLanguageFlag.empty())
+      TU.ExtraArgs.push_back(Case.ClangLanguageFlag);
+    auto AST = TU.build();
+
+    auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+    ASSERT_TRUE(H);
+
+    EXPECT_STREQ(H->DefinitionLanguage, Case.ExpectedDefinitionLanguage);
+  }
+}
+
 TEST(Hover, CallPassType) {
   const llvm::StringRef CodePrefix = R"cpp(
 class Base {};