diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -62,6 +62,7 @@ DraftStore.cpp DumpAST.cpp ExpectedTypes.cpp + FeatureModule.cpp FindSymbols.cpp FindTarget.cpp FileDistance.cpp @@ -75,7 +76,6 @@ Hover.cpp IncludeFixer.cpp JSONTransport.cpp - Module.cpp PathMapping.cpp Protocol.cpp Quality.cpp diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -580,8 +580,8 @@ { LSPBinder Binder(Handlers, *this); bindMethods(Binder, Params.capabilities); - if (Opts.Modules) - for (auto &Mod : *Opts.Modules) + if (Opts.FeatureModules) + for (auto &Mod : *Opts.FeatureModules) Mod.initializeLSP(Binder, Params.rawCapabilities, ServerCaps); } diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -13,9 +13,9 @@ #include "CodeComplete.h" #include "ConfigProvider.h" #include "DraftStore.h" +#include "FeatureModule.h" #include "GlobalCompilationDatabase.h" #include "Hover.h" -#include "Module.h" #include "Protocol.h" #include "SemanticHighlighting.h" #include "TUScheduler.h" @@ -153,7 +153,7 @@ /// Enable preview of FoldingRanges feature. bool FoldingRanges = false; - ModuleSet *Modules = nullptr; + FeatureModuleSet *FeatureModules = nullptr; explicit operator TUScheduler::Options() const; }; @@ -172,13 +172,13 @@ const Options &Opts, Callbacks *Callbacks = nullptr); ~ClangdServer(); - /// Gets the installed module of a given type, if any. - /// This exposes access the public interface of modules that have one. - template Mod *getModule() { - return Modules ? Modules->get() : nullptr; + /// Gets the installed feature module of a given type, if any. + /// This exposes access the public interface of feature modules that have one. + template Mod *featureModule() { + return FeatureModules ? FeatureModules->get() : nullptr; } - template const Mod *getModule() const { - return Modules ? Modules->get() : nullptr; + template const Mod *featureModule() const { + return FeatureModules ? FeatureModules->get() : nullptr; } /// Add a \p File to the list of tracked C++ files or update the contents if @@ -361,7 +361,7 @@ void profile(MemoryTree &MT) const; private: - ModuleSet *Modules; + FeatureModuleSet *FeatureModules; const GlobalCompilationDatabase &CDB; const ThreadsafeFS &TFS; diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -129,7 +129,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS, const Options &Opts, Callbacks *Callbacks) - : Modules(Opts.Modules), CDB(CDB), TFS(TFS), + : FeatureModules(Opts.FeatureModules), CDB(CDB), TFS(TFS), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr), ClangTidyProvider(Opts.ClangTidyProvider), WorkspaceRoot(Opts.WorkspaceRoot) { @@ -168,13 +168,13 @@ if (DynamicIdx) AddIndex(DynamicIdx.get()); - if (Opts.Modules) { - Module::Facilities F{ + if (Opts.FeatureModules) { + FeatureModule::Facilities F{ *this->WorkScheduler, this->Index, this->TFS, }; - for (auto &Mod : *Opts.Modules) + for (auto &Mod : *Opts.FeatureModules) Mod.initialize(F); } } @@ -184,11 +184,11 @@ // otherwise access members concurrently. // (Nobody can be using TUScheduler because we're on the main thread). WorkScheduler.reset(); - // Now requests have stopped, we can shut down modules. - if (Modules) { - for (auto &Mod : *Modules) + // Now requests have stopped, we can shut down feature modules. + if (FeatureModules) { + for (auto &Mod : *FeatureModules) Mod.stop(); - for (auto &Mod : *Modules) + for (auto &Mod : *FeatureModules) Mod.blockUntilIdle(Deadline::infinity()); } } @@ -920,7 +920,7 @@ return false; if (BackgroundIdx && !BackgroundIdx->blockUntilIdleForTest(Timeout)) return false; - if (Modules && llvm::any_of(*Modules, [&](Module &M) { + if (FeatureModules && llvm::any_of(*FeatureModules, [&](FeatureModule &M) { return !M.blockUntilIdle(timeoutSeconds(Timeout)); })) return false; diff --git a/clang-tools-extra/clangd/Module.h b/clang-tools-extra/clangd/FeatureModule.h rename from clang-tools-extra/clangd/Module.h rename to clang-tools-extra/clangd/FeatureModule.h --- a/clang-tools-extra/clangd/Module.h +++ b/clang-tools-extra/clangd/FeatureModule.h @@ -1,4 +1,4 @@ -//===--- Module.h - Plugging features into clangd -----------------*-C++-*-===// +//===--- FeatureModule.h - Plugging features into clangd ----------*-C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULE_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULE_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FEATUREMODULE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FEATUREMODULE_H #include "support/Function.h" #include "support/Threading.h" @@ -26,11 +26,11 @@ class ThreadsafeFS; class TUScheduler; -/// A Module contributes a vertical feature to clangd. +/// A FeatureModule contributes a vertical feature to clangd. /// /// The lifetime of a module is roughly: -/// - modules are created before the LSP server, in ClangdMain.cpp -/// - these modules are then passed to ClangdLSPServer in a ModuleSet +/// - feature modules are created before the LSP server, in ClangdMain.cpp +/// - these modules are then passed to ClangdLSPServer in a FeatureModuleSet /// - initializeLSP() is called when the editor calls initialize. // - initialize() is then called by ClangdServer as it is constructed. /// - module hooks can be called by the server at this point. @@ -39,31 +39,31 @@ /// FIXME: Block server shutdown until all the modules are idle. /// - When shutting down, ClangdServer will wait for all requests to /// finish, call stop(), and then blockUntilIdle(). -/// - modules will be destroyed after ClangdLSPServer is destroyed. +/// - feature modules will be destroyed after ClangdLSPServer is destroyed. /// -/// Modules are not threadsafe in general. A module's entrypoints are: +/// FeatureModules are not threadsafe in general. A module's entrypoints are: /// - method handlers registered in initializeLSP() -/// - public methods called directly via ClangdServer.getModule()->... -/// - specific overridable "hook" methods inherited from Module +/// - public methods called directly via ClangdServer.featureModule()->... +/// - specific overridable "hook" methods inherited from FeatureModule /// Unless otherwise specified, these are only called on the main thread. /// -/// Conventionally, standard modules live in the `clangd` namespace, and other -/// exposed details live in a sub-namespace. -class Module { +/// Conventionally, standard feature modules live in the `clangd` namespace, +/// and other exposed details live in a sub-namespace. +class FeatureModule { public: - virtual ~Module() { + virtual ~FeatureModule() { /// Perform shutdown sequence on destruction in case the ClangdServer was /// never initialized. Usually redundant, but shutdown is idempotent. stop(); blockUntilIdle(Deadline::infinity()); } - /// Called by the server to connect this module to LSP. + /// Called by the server to connect this feature module to LSP. /// The module should register the methods/notifications/commands it handles, /// and update the server capabilities to advertise them. /// /// This is only called if the module is running in ClangdLSPServer! - /// Modules with a public interface should satisfy it without LSP bindings. + /// FeatureModules with a public interface should work without LSP bindings. virtual void initializeLSP(LSPBinder &Bind, const llvm::json::Object &ClientCaps, llvm::json::Object &ServerCaps) {} @@ -87,7 +87,7 @@ /// Waits until the module is idle (no background work) or a deadline expires. /// In general all modules should eventually go idle, though it may take a /// long time (e.g. background indexing). - /// Modules should go idle quickly if stop() has been called. + /// FeatureModules should go idle quickly if stop() has been called. /// Called by the server when shutting down, and also by tests. virtual bool blockUntilIdle(Deadline) { return true; } @@ -101,7 +101,7 @@ /// The filesystem is used to read source files on disk. const ThreadsafeFS &fs() { return facilities().FS; } - /// Types of function objects that modules use for outgoing calls. + /// Types of function objects that feature modules use for outgoing calls. /// (Bound throuh LSPBinder, made available here for convenience). template using OutgoingNotification = llvm::unique_function; @@ -112,28 +112,28 @@ llvm::Optional Fac; }; -/// A ModuleSet is a collection of modules installed in clangd. +/// A FeatureModuleSet is a collection of feature modules installed in clangd. /// -/// Modules can be looked up by type, or used through the Module interface. +/// Modules can be looked up by type, or used via the FeatureModule interface. /// This allows individual modules to expose a public API. -/// For this reason, there can be only one module of each type. +/// For this reason, there can be only one feature module of each type. /// -/// ModuleSet owns the modules. It is itself owned by main, not ClangdServer. -class ModuleSet { - std::vector> Modules; - llvm::DenseMap Map; +/// The set owns the modules. It is itself owned by main, not ClangdServer. +class FeatureModuleSet { + std::vector> Modules; + llvm::DenseMap Map; template struct ID { - static_assert(std::is_base_of::value && + static_assert(std::is_base_of::value && std::is_final::value, "Modules must be final classes derived from clangd::Module"); static int Key; }; - bool addImpl(void *Key, std::unique_ptr, const char *Source); + bool addImpl(void *Key, std::unique_ptr, const char *Source); public: - ModuleSet() = default; + FeatureModuleSet() = default; using iterator = llvm::pointee_iterator; using const_iterator = @@ -150,11 +150,11 @@ return static_cast(Map.lookup(&ID::Key)); } template const Mod *get() const { - return const_cast(this)->get(); + return const_cast(this)->get(); } }; -template int ModuleSet::ID::Key; +template int FeatureModuleSet::ID::Key; } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/Module.cpp b/clang-tools-extra/clangd/FeatureModule.cpp rename from clang-tools-extra/clangd/Module.cpp rename to clang-tools-extra/clangd/FeatureModule.cpp --- a/clang-tools-extra/clangd/Module.cpp +++ b/clang-tools-extra/clangd/FeatureModule.cpp @@ -1,4 +1,4 @@ -//===--- Module.cpp - Plugging features into clangd -----------------------===// +//===--- FeatureModule.cpp - Plugging features into clangd ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,27 +6,27 @@ // //===----------------------------------------------------------------------===// -#include "Module.h" +#include "FeatureModule.h" #include "support/Logger.h" namespace clang { namespace clangd { -void Module::initialize(const Facilities &F) { +void FeatureModule::initialize(const Facilities &F) { assert(!Fac.hasValue() && "Initialized twice"); Fac.emplace(F); } -Module::Facilities &Module::facilities() { +FeatureModule::Facilities &FeatureModule::facilities() { assert(Fac.hasValue() && "Not initialized yet"); return *Fac; } -bool ModuleSet::addImpl(void *Key, std::unique_ptr M, - const char *Source) { +bool FeatureModuleSet::addImpl(void *Key, std::unique_ptr M, + const char *Source) { if (!Map.try_emplace(Key, M.get()).second) { // Source should (usually) include the name of the concrete module type. - elog("Tried to register duplicate modules via {0}", Source); + elog("Tried to register duplicate feature modules via {0}", Source); return false; } Modules.push_back(std::move(M)); diff --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp --- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp @@ -42,7 +42,7 @@ Base = ClangdServer::optsForTest(); // This is needed to we can test index-based operations like call hierarchy. Base.BuildDynamicSymbolIndex = true; - Base.Modules = &Modules; + Base.FeatureModules = &FeatureModules; } LSPClient &start() { @@ -70,7 +70,7 @@ MockFS FS; ClangdLSPServer::Options Opts; - ModuleSet Modules; + FeatureModuleSet FeatureModules; private: // Color logs so we can distinguish them from test output. @@ -227,7 +227,7 @@ } TEST_F(LSPTest, ModulesTest) { - class MathModule final : public Module { + class MathModule final : public FeatureModule { OutgoingNotification Changed; void initializeLSP(LSPBinder &Bind, const llvm::json::Object &ClientCaps, llvm::json::Object &ServerCaps) override { @@ -248,7 +248,7 @@ [Reply(std::move(Reply)), Value(Value)]() mutable { Reply(Value); }); } }; - Modules.add(std::make_unique()); + FeatureModules.add(std::make_unique()); auto &Client = start(); Client.notify("add", 2); @@ -266,10 +266,10 @@ return [&Out](llvm::Expected V) { Out.emplace(std::move(V)); }; } -TEST_F(LSPTest, ModulesThreadingTest) { - // A module that does its work on a background thread, and so exercises the - // block/shutdown protocol. - class AsyncCounter final : public Module { +TEST_F(LSPTest, FeatureModulesThreadingTest) { + // A feature module that does its work on a background thread, and so + // exercises the block/shutdown protocol. + class AsyncCounter final : public FeatureModule { bool ShouldStop = false; int State = 0; std::deque> Queue; // null = increment, non-null = read. @@ -347,19 +347,19 @@ } }; - Modules.add(std::make_unique()); + FeatureModules.add(std::make_unique()); auto &Client = start(); Client.notify("increment", nullptr); Client.notify("increment", nullptr); Client.notify("increment", nullptr); EXPECT_THAT_EXPECTED(Client.call("sync", nullptr).take(), Succeeded()); - EXPECT_EQ(3, Modules.get()->getSync()); + EXPECT_EQ(3, FeatureModules.get()->getSync()); // Throw some work on the queue to make sure shutdown blocks on it. Client.notify("increment", nullptr); Client.notify("increment", nullptr); Client.notify("increment", nullptr); - // And immediately shut down. Module destructor verifies that we blocked. + // And immediately shut down. FeatureModule destructor verifies we blocked. } } // namespace