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 @@ -162,6 +162,23 @@ /// This is checked for translation units only, not headers they include. /// Legal values are "Build" or "Skip". llvm::Optional> Background; + /// Configuration information for an external index. If both File and Server + /// are set, Server will be ignored. This will be used by index + /// implementations to distribute queries to different index sources based + /// on the file. + struct ExternalBlock { + /// Path to a monolithic index on disk. Absolute in case of a global + /// config, relative to location the config file containing the fragment + /// otherwise. + llvm::Optional> File; + /// Address and port number for a remote-index. e.g. `123.1.1.1:13337`. + llvm::Optional> Server; + /// Source root governed by this index. None implies current config file + /// location. Absolute in case of user config and relative otherwise. + /// Should always use forward-slashes. + llvm::Optional> MountPoint; + }; + llvm::Optional External; }; IndexBlock Index; 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 @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - #include "ConfigFragment.h" +#include "Features.inc" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringRef.h" @@ -86,6 +86,25 @@ DictParser Dict("Index", this); Dict.handle("Background", [&](Node &N) { F.Background = scalarValue(N, "Background"); }); + Dict.handle("External", [&](Node &N) { + F.External.emplace(); + parse(*F.External, N); + }); + Dict.parse(N); + } + + void parse(Fragment::IndexBlock::ExternalBlock &F, Node &N) { + DictParser Dict("External", this); + Dict.handle("File", [&](Node &N) { F.File = scalarValue(N, "File"); }); + Dict.handle("Server", [&](Node &N) { +#if CLANGD_ENABLE_REMOTE + F.Server = scalarValue(N, "Server"); +#else + warning("Remote index support isn't enabled for this clangd.", N); +#endif + }); + Dict.handle("MountPoint", + [&](Node &N) { F.MountPoint = scalarValue(N, "MountPoint"); }); Dict.parse(N); } 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 @@ -9,7 +9,9 @@ #include "Annotations.h" #include "ConfigFragment.h" #include "ConfigTesting.h" +#include "Features.inc" #include "Protocol.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/SourceMgr.h" @@ -124,6 +126,34 @@ ASSERT_THAT(Results, IsEmpty()); } +TEST(ParseYAML, ExternalBlock) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Index: + External: + File: "foo" + Server: ^"bar" + MountPoint: "baz" + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + ASSERT_EQ(Results.size(), 1u); + ASSERT_TRUE(Results[0].Index.External); + EXPECT_THAT(*Results[0].Index.External->File, Val("foo")); + EXPECT_THAT(*Results[0].Index.External->MountPoint, Val("baz")); +#if CLANGD_ENABLE_REMOTE + ASSERT_THAT(Diags.Diagnostics, IsEmpty()); + EXPECT_THAT(*Results[0].Index.External->Server, Val("bar")); +#else + EXPECT_FALSE(Results[0].Index.External->Server); + EXPECT_THAT( + Diags.Diagnostics, + ElementsAre(AllOf( + DiagMessage("Remote index support isn't enabled for this clangd."), + DiagPos(YAML.point()), DiagKind(llvm::SourceMgr::DK_Warning)))); +#endif +} + } // namespace } // namespace config } // namespace clangd