diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -116,6 +116,12 @@ /// scopes. bool AllScopes = true; } Completion; + + /// Configures hover feature. + struct { + /// Whether hover show a.k.a type. + bool ShowAKA = false; + } Hover; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -196,6 +196,7 @@ compile(std::move(F.Index)); compile(std::move(F.Diagnostics)); compile(std::move(F.Completion)); + compile(std::move(F.Hover)); } void compile(Fragment::IfBlock &&F) { @@ -507,6 +508,14 @@ } } + void compile(Fragment::HoverBlock &&F) { + if (F.ShowAKA) { + Out.Apply.push_back([ShowAKA(**F.ShowAKA)](const Params &, Config &C) { + C.Hover.ShowAKA = ShowAKA; + }); + } + } + constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error; constexpr static llvm::SourceMgr::DiagKind Warning = llvm::SourceMgr::DK_Warning; diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -266,6 +266,13 @@ llvm::Optional> AllScopes; }; CompletionBlock Completion; + + /// Describes hover preferences. + struct HoverBlock { + /// Whether hover show a.k.a type. + llvm::Optional> ShowAKA; + }; + HoverBlock Hover; }; } // namespace config diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -65,6 +65,7 @@ Dict.handle("Style", [&](Node &N) { parse(F.Style, N); }); Dict.handle("Diagnostics", [&](Node &N) { parse(F.Diagnostics, N); }); Dict.handle("Completion", [&](Node &N) { parse(F.Completion, N); }); + Dict.handle("Hover", [&](Node &N) { parse(F.Hover, N); }); Dict.parse(N); return !(N.failed() || HadError); } @@ -204,6 +205,19 @@ Dict.parse(N); } + void parse(Fragment::HoverBlock &F, Node &N) { + DictParser Dict("Hover", this); + Dict.handle("ShowAKA", [&](Node &N) { + if (auto Value = scalarValue(N, "ShowAKA")) { + if (auto ShowAKA = llvm::yaml::parseBool(**Value)) + F.ShowAKA = *ShowAKA; + else + warning("ShowAKA should be a boolean", N); + } + }); + Dict.parse(N); + } + // Helper for parsing mapping nodes (dictionaries). // We don't use YamlIO as we want to control over unknown keys. class DictParser { diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -10,6 +10,7 @@ #include "AST.h" #include "CodeCompletionStrings.h" +#include "Config.h" #include "FindTarget.h" #include "ParsedAST.h" #include "Selection.h" @@ -159,7 +160,9 @@ } QT.print(OS, PP); OS.flush(); - if (!QT.isNull()) { + + const Config &Cfg = Config::current(); + if (!QT.isNull() && Cfg.Hover.ShowAKA) { bool ShouldAKA = false; QualType DesugaredTy = clang::desugarForDiagnostic(ASTCtx, QT, ShouldAKA); if (ShouldAKA) diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp --- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp @@ -215,6 +215,19 @@ ASSERT_EQ(Results.size(), 1u); EXPECT_THAT(Results[0].Completion.AllScopes, testing::Eq(llvm::None)); } + +TEST(ParseYAML, ShowAKA) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Hover: + ShowAKA: True + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + ASSERT_THAT(Diags.Diagnostics, IsEmpty()); + ASSERT_EQ(Results.size(), 1u); + EXPECT_THAT(Results[0].Hover.ShowAKA, llvm::ValueIs(Val(true))); +} } // namespace } // namespace config } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -8,6 +8,7 @@ #include "AST.h" #include "Annotations.h" +#include "Config.h" #include "Hover.h" #include "TestIndex.h" #include "TestTU.h" @@ -1008,6 +1009,9 @@ // fixed one to make sure tests passes on different platform. TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu"); auto AST = TU.build(); + Config Cfg; + Cfg.Hover.ShowAKA = true; + WithContextValue WithCfg(Config::Key, std::move(Cfg)); auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); ASSERT_TRUE(H); @@ -2539,7 +2543,9 @@ // fixed one to make sure tests passes on different platform. TU.ExtraArgs.push_back("--target=x86_64-pc-linux-gnu"); auto AST = TU.build(); - + Config Cfg; + Cfg.Hover.ShowAKA = true; + WithContextValue WithCfg(Config::Key, std::move(Cfg)); auto H = getHover(AST, T.point(), format::getLLVMStyle(), Index.get()); ASSERT_TRUE(H); HoverInfo Expected; @@ -2928,6 +2934,9 @@ for (const auto &C : Cases) { HoverInfo HI; C.Builder(HI); + Config Cfg; + Cfg.Hover.ShowAKA = true; + WithContextValue WithCfg(Config::Key, std::move(Cfg)); EXPECT_EQ(HI.present().asPlainText(), C.ExpectedRender); } } @@ -3098,6 +3107,25 @@ EXPECT_EQ(*HI->Value, "&bar"); } +TEST(Hover, DisableShowAKA) { + Annotations T(R"cpp( + using m_int = int; + m_int ^[[a]]; + )cpp"); + + Config Cfg; + Cfg.Hover.ShowAKA = false; + WithContextValue WithCfg(Config::Key, std::move(Cfg)); + + TestTU TU = TestTU::withCode(T.code()); + TU.ExtraArgs.push_back("-std=c++17"); + auto AST = TU.build(); + auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); + + ASSERT_TRUE(H); + EXPECT_EQ(H->Type, HoverInfo::PrintedType("m_int")); +} + } // namespace } // namespace clangd } // namespace clang