Author: Kadir Cetinkaya Date: 2021-03-11T20:30:35+01:00 New Revision: ac292dafa776fa9ee18d38d60c7de2da58f939f0
URL: https://github.com/llvm/llvm-project/commit/ac292dafa776fa9ee18d38d60c7de2da58f939f0 DIFF: https://github.com/llvm/llvm-project/commit/ac292dafa776fa9ee18d38d60c7de2da58f939f0.diff LOG: [clangd] Add config block for Completion and option for AllScopes Depends on D98029 Differential Revision: https://reviews.llvm.org/D98037 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/Config.h clang-tools-extra/clangd/ConfigCompile.cpp clang-tools-extra/clangd/ConfigFragment.h clang-tools-extra/clangd/ConfigYAML.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index df3dd363800a..164e387bd454 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -362,6 +362,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos, ParseInput.Index = Index; CodeCompleteOpts.MainFileSignals = IP->Signals; + CodeCompleteOpts.AllScopes = Config::current().Completion.AllScopes; // FIXME(ibiryukov): even if Preamble is non-null, we may want to check // both the old and the new version in case only one of them matches. CodeCompleteResult Result = clangd::codeComplete( diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h index 391632cb086a..7064edd76b8f 100644 --- a/clang-tools-extra/clangd/Config.h +++ b/clang-tools-extra/clangd/Config.h @@ -106,6 +106,13 @@ struct Config { // ::). All nested namespaces are affected as well. std::vector<std::string> FullyQualifiedNamespaces; } Style; + + /// Configures code completion feature. + struct { + /// Whether code completion includes results that are not visible in current + /// scopes. + bool AllScopes = true; + } Completion; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp index dadc578c3a81..9aed3c4679f5 100644 --- a/clang-tools-extra/clangd/ConfigCompile.cpp +++ b/clang-tools-extra/clangd/ConfigCompile.cpp @@ -192,6 +192,7 @@ struct FragmentCompiler { compile(std::move(F.CompileFlags)); compile(std::move(F.Index)); compile(std::move(F.Diagnostics)); + compile(std::move(F.Completion)); } void compile(Fragment::IfBlock &&F) { @@ -463,6 +464,15 @@ struct FragmentCompiler { } } + void compile(Fragment::CompletionBlock &&F) { + if (F.AllScopes) { + Out.Apply.push_back( + [AllScopes(**F.AllScopes)](const Params &, Config &C) { + C.Completion.AllScopes = AllScopes; + }); + } + } + 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 index c36b07f5e8e2..1365ed4c1037 100644 --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -238,6 +238,14 @@ struct Fragment { std::vector<Located<std::string>> FullyQualifiedNamespaces; }; StyleBlock Style; + + /// Describes code completion preferences. + struct CompletionBlock { + /// Whether code completion should include suggestions from scopes that are + /// not visible. The required scope prefix will be inserted. + llvm::Optional<Located<bool>> AllScopes; + }; + CompletionBlock Completion; }; } // namespace config diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp index 348ee9dd1f75..d50c01168a8d 100644 --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -63,6 +63,7 @@ class Parser { Dict.handle("Index", [&](Node &N) { parse(F.Index, N); }); 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.parse(N); return !(N.failed() || HadError); } @@ -165,6 +166,19 @@ class Parser { Dict.parse(N); } + void parse(Fragment::CompletionBlock &F, Node &N) { + DictParser Dict("Completion", this); + Dict.handle("AllScopes", [&](Node &N) { + if (auto Value = scalarValue(N, "AllScopes")) { + if (auto AllScopes = llvm::yaml::parseBool(**Value)) + F.AllScopes = *AllScopes; + else + warning("AllScopes 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/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index ad8d3c928b3c..3c5b6473be0d 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -623,6 +623,7 @@ class FlagsConfigProvider : public config::Provider { if (!EnableBackgroundIndex) { BGPolicy = Config::BackgroundPolicy::Skip; } + Frag = [=](const config::Params &, Config &C) { if (CDBSearch) C.CompileFlags.CDBSearch = *CDBSearch; @@ -630,6 +631,8 @@ class FlagsConfigProvider : public config::Provider { C.Index.External = *IndexSpec; if (BGPolicy) C.Index.Background = *BGPolicy; + if (AllScopesCompletion.getNumOccurrences()) + C.Completion.AllScopes = AllScopesCompletion; return true; }; } @@ -827,7 +830,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var Opts.CodeComplete.IncludeIndicator.NoInsert.clear(); } Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets; - Opts.CodeComplete.AllScopes = AllScopesCompletion; Opts.CodeComplete.RunParser = CodeCompletionParse; Opts.CodeComplete.RankingModel = RankingModel; diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp index d9aa171f3102..b68d7e5f5e17 100644 --- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -443,6 +443,22 @@ TEST_F(ConfigCompileTests, ExternalBlockMountPoint) { ASSERT_FALSE(Conf.Index.External); #endif } + +TEST_F(ConfigCompileTests, AllScopes) { + // Defaults to true. + EXPECT_TRUE(compileAndApply()); + EXPECT_TRUE(Conf.Completion.AllScopes); + + Frag = {}; + Frag.Completion.AllScopes = false; + EXPECT_TRUE(compileAndApply()); + EXPECT_FALSE(Conf.Completion.AllScopes); + + Frag = {}; + Frag.Completion.AllScopes = true; + EXPECT_TRUE(compileAndApply()); + EXPECT_TRUE(Conf.Completion.AllScopes); +} } // namespace } // namespace config } // namespace clangd diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp index e1c81344de20..0c216c208706 100644 --- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp @@ -10,10 +10,12 @@ #include "ConfigFragment.h" #include "ConfigTesting.h" #include "Protocol.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Testing/Support/SupportHelpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -164,6 +166,35 @@ TEST(ParseYAML, ExternalBlock) { EXPECT_THAT(*Results[0].Index.External.getValue()->Server, Val("bar")); } +TEST(ParseYAML, AllScopes) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Completion: + AllScopes: 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].Completion.AllScopes, llvm::ValueIs(Val(true))); +} + +TEST(ParseYAML, AllScopesWarn) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Completion: + AllScopes: $diagrange[[Truex]] + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + EXPECT_THAT(Diags.Diagnostics, + ElementsAre(AllOf(DiagMessage("AllScopes should be a boolean"), + DiagKind(llvm::SourceMgr::DK_Warning), + DiagPos(YAML.range("diagrange").start), + DiagRange(YAML.range("diagrange"))))); + ASSERT_EQ(Results.size(), 1u); + EXPECT_THAT(Results[0].Completion.AllScopes, testing::Eq(llvm::None)); +} } // namespace } // namespace config } // namespace clangd _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits