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"]
This commit is contained in:
Fangrui Song 2018-09-03 12:21:32 -07:00
parent 4f67bd03d5
commit d3e0a4c4fd
4 changed files with 26 additions and 2 deletions

View File

@ -179,6 +179,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<std::string> multiVersionBlacklist;
std::vector<std::string> multiVersionWhitelist;
// Allow indexing on textDocument/didChange.
// May be too slow for big projects, so it is off by default.
bool onDidChange = false;
@ -225,7 +230,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,

View File

@ -5,6 +5,7 @@
#include "clang_tu.h"
#include "log.hh"
#include "match.h"
#include "platform.h"
#include "serializer.h"
using ccls::Intern;
@ -32,8 +33,11 @@ namespace {
constexpr int kInitializerMaxLines = 3;
GroupMatch *multiVersionMatcher;
struct IndexParam {
std::unordered_map<llvm::sys::fs::UniqueID, std::string> SeenUniqueID;
std::unordered_map<llvm::sys::fs::UniqueID, bool> UID2multi;
std::unordered_map<std::string, FileContents> file_contents;
std::unordered_map<std::string, int64_t> file2write_time;
struct DeclInfo {
@ -69,6 +73,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,
@ -624,7 +635,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;
@ -1165,6 +1176,11 @@ template <typename T> void Uniquify(std::vector<T> &a) {
}
namespace ccls::idx {
void Init() {
multiVersionMatcher = new GroupMatch(g_config->index.multiVersionWhitelist,
g_config->index.multiVersionBlacklist);
}
std::vector<std::unique_ptr<IndexFile>>
Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
const std::vector<std::string> &args,

View File

@ -265,6 +265,7 @@ struct IndexFile {
};
namespace ccls::idx {
void Init();
std::vector<std::unique_ptr<IndexFile>>
Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
const std::vector<std::string> &args,

View File

@ -466,6 +466,7 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
EscapeFileName(g_config->projectRoot));
diag_pub->Init();
idx::Init();
semantic_cache->Init();
// Open up / load the project.