From 66bf514b5f5b1b6349e1f483e11628836f98cf7c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 22 Oct 2018 22:01:10 -0700 Subject: [PATCH] Add command line option -index=root to index without starting language server --- src/main.cc | 26 +++++++++++----- src/messages/initialize.cc | 62 +++++++++++--------------------------- src/pipeline.cc | 33 ++++++++++++++++++++ src/pipeline.hh | 1 + 4 files changed, 70 insertions(+), 52 deletions(-) diff --git a/src/main.cc b/src/main.cc index 4da4cb0f..4af74f40 100644 --- a/src/main.cc +++ b/src/main.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,9 @@ opt opt_verbose("v", desc("verbosity"), init(0), cat(C)); opt opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests"), cat(C)); +opt opt_index("index", + desc("standalone mode: index a project and exit"), + value_desc("root"), cat(C)); opt opt_init("init", desc("extra initialization options in JSON"), cat(C)); opt opt_log_file("log-file", desc("log"), value_desc("filename"), @@ -118,14 +122,20 @@ int main(int argc, char **argv) { sys::ChangeStdinToBinary(); sys::ChangeStdoutToBinary(); - // The thread that reads from stdin and dispatchs commands to the main - // thread. - pipeline::LaunchStdin(); - // The thread that writes responses from the main thread to stdout. - pipeline::LaunchStdout(); - // Main thread which also spawns indexer threads upon the "initialize" - // request. - pipeline::MainLoop(); + if (opt_index.size()) { + SmallString<256> Root(opt_index); + sys::fs::make_absolute(Root); + pipeline::Standalone(Root.str()); + } else { + // The thread that reads from stdin and dispatchs commands to the main + // thread. + pipeline::LaunchStdin(); + // The thread that writes responses from the main thread to stdout. + pipeline::LaunchStdout(); + // Main thread which also spawns indexer threads upon the "initialize" + // request. + pipeline::MainLoop(); + } } return 0; diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index 72418faa..c9aa4ce2 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -310,25 +310,13 @@ struct lsClientCapabilities { MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument); struct lsInitializeParams { - // The process Id of the parent process that started - // the server. Is null if the process has not been started by another process. - // If the parent process is not alive then the server should exit (see exit - // notification) its process. - std::optional processId; - - // The rootPath of the workspace. Is null - // if no folder is open. - // - // @deprecated in favour of rootUri. - std::optional rootPath; - // The rootUri of the workspace. Is null if no // folder is open. If both `rootPath` and `rootUri` are set // `rootUri` wins. std::optional rootUri; // User provided initialization options. - std::optional initializationOptions; + Config initializationOptions; // The capabilities provided by the client (editor or tool) lsClientCapabilities capabilities; @@ -360,33 +348,8 @@ void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) { value = lsInitializeParams::lsTrace::Verbose; } -#if 0 // unused -void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) { - switch (value) { - case lsInitializeParams::lsTrace::Off: - writer.String("off"); - break; - case lsInitializeParams::lsTrace::Messages: - writer.String("messages"); - break; - case lsInitializeParams::lsTrace::Verbose: - writer.String("verbose"); - break; - } -} -#endif - -MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, - initializationOptions, capabilities, trace, - workspaceFolders); - -struct lsInitializeError { - // Indicates whether the client should retry to send the - // initilize request after showing the message provided - // in the ResponseError. - bool retry; -}; -MAKE_REFLECT_STRUCT(lsInitializeError, retry); +MAKE_REFLECT_STRUCT(lsInitializeParams, rootUri, initializationOptions, + capabilities, trace, workspaceFolders); struct In_InitializeRequest : public RequestMessage { MethodType GetMethodType() const override { return kMethodType; } @@ -426,10 +389,7 @@ struct Handler_Initialize : BaseMessageHandler { << params.rootUri->raw_uri; { - if (params.initializationOptions) - g_config = new Config(*params.initializationOptions); - else - g_config = new Config; + g_config = new Config(params.initializationOptions); rapidjson::Document reader; reader.Parse(g_init_options.c_str()); if (!reader.HasParseError()) { @@ -519,3 +479,17 @@ struct Handler_Initialize : BaseMessageHandler { }; REGISTER_MESSAGE_HANDLER(Handler_Initialize); } // namespace + +void StandaloneInitialize(const std::string &root, Project &project, + WorkingFiles &wfiles, VFS &vfs, + IncludeComplete &complete) { + Handler_Initialize handler; + handler.project = &project; + handler.working_files = &wfiles; + handler.vfs = &vfs; + handler.include_complete = &complete; + + In_InitializeRequest request; + request.params.rootUri = lsDocumentUri::FromPath(root); + handler.Run(&request); +} diff --git a/src/pipeline.cc b/src/pipeline.cc index 1a20a0bf..fa714665 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -18,6 +18,7 @@ #include +#include #include #include using namespace llvm; @@ -30,6 +31,9 @@ using namespace llvm; #include #endif +void StandaloneInitialize(const std::string &, Project &, WorkingFiles &, VFS &, + IncludeComplete &); + void VFS::Clear() { std::lock_guard lock(mutex); state.clear(); @@ -523,6 +527,35 @@ void MainLoop() { } } +void Standalone(const std::string &root) { + Project project; + WorkingFiles wfiles; + VFS vfs; + IncludeComplete complete(&project); + StandaloneInitialize(root, project, wfiles, vfs, complete); + bool tty = sys::Process::StandardOutIsDisplayed(); + + if (tty) { + int entries = 0; + for (auto &[_, folder] : project.root2folder) + entries += folder.entries.size(); + printf("entries: %5d\n", entries); + } + while (1) { + (void)on_indexed->DequeueAll(); + int pending = pending_index_requests; + if (tty) { + printf("\rpending: %5d", pending); + fflush(stdout); + } + if (!pending) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + if (tty) + puts(""); +} + void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id) { pending_index_requests++; diff --git a/src/pipeline.hh b/src/pipeline.hh index be46ea62..a52bc1d6 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -48,6 +48,7 @@ void LaunchStdout(); void Indexer_Main(CompletionManager *completion, VFS *vfs, Project *project, WorkingFiles *wfiles); void MainLoop(); +void Standalone(const std::string &root); void Index(const std::string &path, const std::vector &args, IndexMode mode, lsRequestId id = {});