[clang-tools-extra] b6e52d8 - [clangd] Give modules access to filesystem, scheduler, and index.
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 16 06:39:28 PST 2021
Author: Sam McCall
Date: 2021-02-16T15:30:08+01:00
New Revision: b6e52d8fa7217db319e240854a9d8ff3133d02b6
URL: https://github.com/llvm/llvm-project/commit/b6e52d8fa7217db319e240854a9d8ff3133d02b6
DIFF: https://github.com/llvm/llvm-project/commit/b6e52d8fa7217db319e240854a9d8ff3133d02b6.diff
LOG: [clangd] Give modules access to filesystem, scheduler, and index.
This finally makes it possible to implement useful modules.
Differential Revision: https://reviews.llvm.org/D96726
Added:
Modified:
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/Module.cpp
clang-tools-extra/clangd/Module.h
clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 49f01cd0b59ae..67aba1c3d92ea 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -167,6 +167,16 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
}
if (DynamicIdx)
AddIndex(DynamicIdx.get());
+
+ if (Opts.Modules) {
+ Module::Facilities F{
+ this->WorkScheduler,
+ this->Index,
+ this->TFS,
+ };
+ for (auto &Mod : *Opts.Modules)
+ Mod.initialize(F);
+ }
}
void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
diff --git a/clang-tools-extra/clangd/Module.cpp b/clang-tools-extra/clangd/Module.cpp
index 1152ae4e7fb22..051f1b45c8375 100644
--- a/clang-tools-extra/clangd/Module.cpp
+++ b/clang-tools-extra/clangd/Module.cpp
@@ -1,8 +1,27 @@
+//===--- Module.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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
#include "Module.h"
+#include "support/Logger.h"
namespace clang {
namespace clangd {
+void Module::initialize(const Facilities &F) {
+ assert(!Fac.hasValue() && "Initialized twice");
+ Fac.emplace(F);
+}
+
+Module::Facilities &Module::facilities() {
+ assert(Fac.hasValue() && "Not initialized yet");
+ return *Fac;
+}
+
bool ModuleSet::addImpl(void *Key, std::unique_ptr<Module> M,
const char *Source) {
if (!Map.try_emplace(Key, M.get()).second) {
diff --git a/clang-tools-extra/clangd/Module.h b/clang-tools-extra/clangd/Module.h
index 1db228000a6ed..4b184b19dcb3b 100644
--- a/clang-tools-extra/clangd/Module.h
+++ b/clang-tools-extra/clangd/Module.h
@@ -1,7 +1,14 @@
+//===--- Module.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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULE_H
-#include "LSPBinder.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/JSON.h"
@@ -11,6 +18,10 @@
namespace clang {
namespace clangd {
+class LSPBinder;
+class SymbolIndex;
+class ThreadsafeFS;
+class TUScheduler;
/// A Module contributes a vertical feature to clangd.
///
@@ -18,10 +29,11 @@ namespace 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 and ClangdServer
-/// - module hooks can be called at this point.
-/// FIXME: We should make some server facilities like TUScheduler and index
-/// available to those modules after ClangdServer is initalized.
+/// - these modules are then passed to ClangdLSPServer in a ModuleSet
+/// - 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.
+/// Server facilities (scheduler etc) are available.
/// - ClangdServer will not be destroyed until all the requests are done.
/// FIXME: Block server shutdown until all the modules are idle.
/// - modules will be destroyed after ClangdLSPServer is destroyed.
@@ -41,6 +53,28 @@ class Module {
virtual void initializeLSP(LSPBinder &Bind,
const llvm::json::Object &ClientCaps,
llvm::json::Object &ServerCaps) {}
+
+ /// Shared server facilities needed by the module to get its work done.
+ struct Facilities {
+ TUScheduler &Scheduler;
+ const SymbolIndex *Index;
+ const ThreadsafeFS &FS;
+ };
+ /// Called by the server to prepare this module for use.
+ void initialize(const Facilities &F);
+
+protected:
+ /// Accessors for modules to access shared server facilities they depend on.
+ Facilities &facilities();
+ /// The scheduler is used to run tasks on worker threads and access ASTs.
+ TUScheduler &scheduler() { return facilities().Scheduler; }
+ /// The index is used to get information about the whole codebase.
+ const SymbolIndex *index() { return facilities().Index; }
+ /// The filesystem is used to read source files on disk.
+ const ThreadsafeFS &fs() { return facilities().FS; }
+
+private:
+ llvm::Optional<Facilities> Fac;
};
/// A ModuleSet is a collection of modules installed in clangd.
diff --git a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
index 0d073fad48ed5..a6a364d1a686a 100644
--- a/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
@@ -233,7 +233,11 @@ TEST_F(LSPTest, ModulesTest) {
public:
void add(const int &X) { Value += X; }
- void get(const std::nullptr_t &, Callback<int> Reply) { Reply(Value); }
+ void get(const std::nullptr_t &, Callback<int> Reply) {
+ scheduler().runQuick(
+ "get", "",
+ [Reply(std::move(Reply)), Value(Value)]() mutable { Reply(Value); });
+ }
};
ModuleSet Mods;
Mods.add(std::make_unique<MathModule>());
More information about the cfe-commits
mailing list