Add command line option -index=root to index without starting language server

This commit is contained in:
Fangrui Song 2018-10-22 22:01:10 -07:00
parent ce1c7ec76a
commit 283d887271
4 changed files with 70 additions and 52 deletions

View File

@ -23,6 +23,7 @@ limitations under the License.
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/CrashRecoveryContext.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/Process.h>
#include <llvm/Support/Program.h>
#include <llvm/Support/Signals.h>
@ -49,6 +50,9 @@ opt<int> opt_verbose("v", desc("verbosity"), init(0), cat(C));
opt<std::string> opt_test_index("test-index", ValueOptional, init("!"),
desc("run index tests"), cat(C));
opt<std::string> opt_index("index",
desc("standalone mode: index a project and exit"),
value_desc("root"), cat(C));
opt<std::string> opt_init("init", desc("extra initialization options in JSON"),
cat(C));
opt<std::string> opt_log_file("log-file", desc("log"), value_desc("filename"),
@ -130,14 +134,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;

View File

@ -322,25 +322,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<int> processId;
// The rootPath of the workspace. Is null
// if no folder is open.
//
// @deprecated in favour of rootUri.
std::optional<std::string> rootPath;
// The rootUri of the workspace. Is null if no
// folder is open. If both `rootPath` and `rootUri` are set
// `rootUri` wins.
std::optional<lsDocumentUri> rootUri;
// User provided initialization options.
std::optional<Config> initializationOptions;
Config initializationOptions;
// The capabilities provided by the client (editor or tool)
lsClientCapabilities capabilities;
@ -372,33 +360,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; }
@ -438,10 +401,7 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
<< 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()) {
@ -531,3 +491,17 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
};
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);
}

View File

@ -30,6 +30,7 @@ limitations under the License.
#include <rapidjson/writer.h>
#include <llvm/Support/Process.h>
#include <llvm/Support/Threading.h>
#include <llvm/Support/Timer.h>
using namespace llvm;
@ -42,6 +43,9 @@ using namespace llvm;
#include <unistd.h>
#endif
void StandaloneInitialize(const std::string &, Project &, WorkingFiles &, VFS &,
IncludeComplete &);
void VFS::Clear() {
std::lock_guard lock(mutex);
state.clear();
@ -535,6 +539,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<const char *> &args,
IndexMode mode, lsRequestId id) {
pending_index_requests++;

View File

@ -45,6 +45,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<const char *> &args,
IndexMode mode, lsRequestId id = {});