From aebf2dfaed4f0e7e92b21312d87ae1cbcb3fafff Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 3 Sep 2018 12:21:32 -0700 Subject: [PATCH] Add index.multiVersion{Black,White}list They allow files matching specified patterns to be indexed only once even if index.multiVersion > 0. An example is to exclude system headers with index.multiVersionBlacklist: ["^/usr/include"] --- src/config.h | 8 +++++++- src/indexer.cc | 18 +++++++++++++++++- src/indexer.h | 1 + src/messages/initialize.cc | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/config.h b/src/config.h index 67cf0972..c22a99f8 100644 --- a/src/config.h +++ b/src/config.h @@ -191,6 +191,11 @@ struct Config { // If not 0, a file will be indexed in each tranlation unit that includes it. int multiVersion = 0; + // If multiVersion != 0, files that match blacklist but not whitelist will + // still only be indexed for one version. + std::vector multiVersionBlacklist; + std::vector multiVersionWhitelist; + // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. bool onDidChange = false; @@ -237,7 +242,8 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onOpen, onType, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, - onDidChange, reparseForDependency, threads, whitelist); + multiVersionBlacklist, multiVersionWhitelist, onDidChange, + reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, diff --git a/src/indexer.cc b/src/indexer.cc index 4f3849e2..ff711a0c 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -17,6 +17,7 @@ limitations under the License. #include "clang_tu.h" #include "log.hh" +#include "match.h" #include "platform.h" #include "serializer.h" using ccls::Intern; @@ -44,8 +45,11 @@ namespace { constexpr int kInitializerMaxLines = 3; +GroupMatch *multiVersionMatcher; + struct IndexParam { std::unordered_map SeenUniqueID; + std::unordered_map UID2multi; std::unordered_map file_contents; std::unordered_map file2write_time; struct DeclInfo { @@ -81,6 +85,13 @@ struct IndexParam { SeenFile(FE); return file_consumer->TryConsumeFile(FE, &file_contents); } + + bool UseMultiVersion(const FileEntry &FE) { + auto it = UID2multi.try_emplace(FE.getUniqueID()); + if (it.second) + it.first->second = multiVersionMatcher->IsMatch(FileName(FE)); + return it.first->second; + } }; StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts, @@ -639,7 +650,7 @@ public: return true; int lid = -1; IndexFile *db; - if (g_config->index.multiVersion) { + if (g_config->index.multiVersion && param.UseMultiVersion(*FE)) { db = param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID())); if (!db) return true; @@ -1180,6 +1191,11 @@ template void Uniquify(std::vector &a) { } namespace ccls::idx { +void Init() { + multiVersionMatcher = new GroupMatch(g_config->index.multiVersionWhitelist, + g_config->index.multiVersionBlacklist); +} + std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, diff --git a/src/indexer.h b/src/indexer.h index d1b1e712..355b5a98 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -277,6 +277,7 @@ struct IndexFile { }; namespace ccls::idx { +void Init(); std::vector> Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, const std::vector &args, diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index b687b6a9..cfbca19e 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -478,6 +478,7 @@ struct Handler_Initialize : BaseMessageHandler { EscapeFileName(g_config->projectRoot)); diag_pub->Init(); + idx::Init(); semantic_cache->Init(); // Open up / load the project.