diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json new file mode 100644 index 00000000..cc968209 --- /dev/null +++ b/src/.vscode/settings.json @@ -0,0 +1,9 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "cquery.blacklist": [ + // ".*libclangmm/.*" + ], + "cquery.whitelist": [ + // ".*platform.*.cc" + ] +} \ No newline at end of file diff --git a/src/command_line.cc b/src/command_line.cc index 02ef1ab6..6488e655 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -34,7 +34,7 @@ namespace { const int kNumIndexers = 8 - 1; const int kMaxWorkspaceSearchResults = 1000; -const bool kUseMultipleProcesses = false; +const bool kUseMultipleProcesses = false; // TODO: initialization options not passed properly when set to true. @@ -1046,6 +1046,21 @@ void QueryDbMainLoop( Ipc_OpenProject* msg = static_cast(message.get()); std::string path = msg->project_path; + std::vector whitelist; + std::cerr << "Using whitelist" << std::endl; + for (const std::string& entry : msg->whitelist) { + std::cerr << " - " << entry << std::endl; + whitelist.push_back(Matcher(entry)); + } + + std::vector blacklist; + std::cerr << "Using blacklist" << std::endl; + for (const std::string& entry : msg->blacklist) { + std::cerr << " - " << entry << std::endl; + blacklist.push_back(Matcher(entry)); + } + + project->Load(path); std::cerr << "Loaded compilation entries (" << project->entries.size() << " files)" << std::endl; //for (int i = 0; i < 10; ++i) @@ -1054,6 +1069,31 @@ void QueryDbMainLoop( const CompilationEntry& entry = project->entries[i]; std::string filepath = entry.filename; + + const Matcher* is_bad = nullptr; + for (const Matcher& m : whitelist) { + if (!m.IsMatch(filepath)) { + is_bad = &m; + break; + } + } + if (is_bad) { + std::cerr << "[" << i << "/" << (project->entries.size() - 1) << "] Failed whitelist check \"" << is_bad->regex_string << "\"; skipping " << filepath << std::endl; + continue; + } + + for (const Matcher& m : blacklist) { + if (m.IsMatch(filepath)) { + is_bad = &m; + break; + } + } + if (is_bad) { + std::cerr << "[" << i << "/" << (project->entries.size() - 1) << "] Failed blacklist check \"" << is_bad->regex_string << "\"; skipping " << filepath << std::endl; + continue; + } + + std::cerr << "[" << i << "/" << (project->entries.size() - 1) << "] Dispatching index request for file " << filepath << std::endl; @@ -1619,7 +1659,7 @@ void LanguageServerStdinLoop() { if (!message) continue; - std::cerr << "[stdin]: Got message \"" << IpcIdToString(message->method_id) << '"' << std::endl; + std::cerr << "[stdin] Got message \"" << IpcIdToString(message->method_id) << '"' << std::endl; switch (message->method_id) { // TODO: For simplicitly lets just proxy the initialize request like // all other requests so that stdin loop thread becomes super simple. @@ -1627,11 +1667,15 @@ void LanguageServerStdinLoop() { auto request = static_cast(message.get()); if (request->params.rootUri) { std::string project_path = request->params.rootUri->GetPath(); - std::cerr << "Initialize in directory " << project_path + std::cerr << "[stdin] Initialize in directory " << project_path << " with uri " << request->params.rootUri->raw_uri << std::endl; auto open_project = MakeUnique(); open_project->project_path = project_path; + if (request->params.initializationOptions) { + open_project->whitelist = request->params.initializationOptions->whitelist; + open_project->blacklist = request->params.initializationOptions->blacklist; + } ipc->SendMessage(IpcManager::Destination::Server, std::move(open_project)); } diff --git a/src/fuzzy.cc b/src/fuzzy.cc index 9cd0ed1d..1592457e 100644 --- a/src/fuzzy.cc +++ b/src/fuzzy.cc @@ -3,6 +3,7 @@ #include Matcher::Matcher(const std::string& search) { + /* std::string real_search; real_search.reserve(search.size() * 3 + 2); for (auto c : search) { @@ -10,8 +11,10 @@ Matcher::Matcher(const std::string& search) { real_search += c; } real_search += ".*"; + */ - regex = std::regex(real_search, + regex_string = search; + regex = std::regex(regex_string, std::regex_constants::ECMAScript | std::regex_constants::icase | std::regex_constants::optimize @@ -19,7 +22,7 @@ Matcher::Matcher(const std::string& search) { ); } -bool Matcher::IsMatch(const std::string& value) { +bool Matcher::IsMatch(const std::string& value) const { //std::smatch match; //return std::regex_match(value, match, regex); return std::regex_match(value, regex, std::regex_constants::match_any); diff --git a/src/fuzzy.h b/src/fuzzy.h index dae20e5f..8d1d1870 100644 --- a/src/fuzzy.h +++ b/src/fuzzy.h @@ -5,6 +5,8 @@ struct Matcher { Matcher(const std::string& search); - bool IsMatch(const std::string& value); + bool IsMatch(const std::string& value) const; + + std::string regex_string; std::regex regex; }; diff --git a/src/ipc.h b/src/ipc.h index be38e647..dffbb84e 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -58,6 +58,8 @@ MAKE_REFLECT_EMPTY_STRUCT(Ipc_IsAlive); struct Ipc_OpenProject : public IpcMessage { static constexpr IpcId kIpcId = IpcId::OpenProject; std::string project_path; + std::vector whitelist; + std::vector blacklist; }; MAKE_REFLECT_STRUCT(Ipc_OpenProject, project_path); diff --git a/src/language_server_api.cc b/src/language_server_api.cc index 804e117b..70497a86 100644 --- a/src/language_server_api.cc +++ b/src/language_server_api.cc @@ -60,6 +60,8 @@ std::unique_ptr MessageRegistry::ReadMessageFromStdin() { content += c; } + //std::cerr << content.c_str() << std::endl; + rapidjson::Document document; document.Parse(content.c_str(), content_length); assert(!document.HasParseError()); diff --git a/src/language_server_api.h b/src/language_server_api.h index 1b89f8a8..3cad0b0e 100644 --- a/src/language_server_api.h +++ b/src/language_server_api.h @@ -800,6 +800,11 @@ struct lsClientCapabilities { MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument); struct lsInitializeParams { + struct lsCustomInitializationOptions { + NonElidedVector whitelist; + NonElidedVector blacklist; + }; + // 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. @@ -817,7 +822,7 @@ struct lsInitializeParams { optional rootUri; // User provided initialization options. - // initializationOptions?: any; // TODO + optional initializationOptions; // The capabilities provided by the client (editor or tool) lsClientCapabilities capabilities; @@ -834,7 +839,8 @@ struct lsInitializeParams { }; void Reflect(Reader& reader, lsInitializeParams::lsTrace& value); void Reflect(Writer& writer, lsInitializeParams::lsTrace& value); -MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, capabilities, trace); +MAKE_REFLECT_STRUCT(lsInitializeParams::lsCustomInitializationOptions, whitelist, blacklist); +MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri, initializationOptions, capabilities, trace); struct lsInitializeError {