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 a33f4df404
commit aebf2dfaed
4 changed files with 26 additions and 2 deletions

View File

@ -191,6 +191,11 @@ struct Config {
// If not 0, a file will be indexed in each tranlation unit that includes it. // If not 0, a file will be indexed in each tranlation unit that includes it.
int multiVersion = 0; 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. // Allow indexing on textDocument/didChange.
// May be too slow for big projects, so it is off by default. // May be too slow for big projects, so it is off by default.
bool onDidChange = false; bool onDidChange = false;
@ -237,7 +242,8 @@ MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onOpen,
onType, whitelist) onType, whitelist)
MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist)
MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, multiVersion, 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::WorkspaceSymbol, caseSensitivity, maxNum, sort);
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand, MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,

View File

@ -17,6 +17,7 @@ limitations under the License.
#include "clang_tu.h" #include "clang_tu.h"
#include "log.hh" #include "log.hh"
#include "match.h"
#include "platform.h" #include "platform.h"
#include "serializer.h" #include "serializer.h"
using ccls::Intern; using ccls::Intern;
@ -44,8 +45,11 @@ namespace {
constexpr int kInitializerMaxLines = 3; constexpr int kInitializerMaxLines = 3;
GroupMatch *multiVersionMatcher;
struct IndexParam { struct IndexParam {
std::unordered_map<llvm::sys::fs::UniqueID, std::string> SeenUniqueID; 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, FileContents> file_contents;
std::unordered_map<std::string, int64_t> file2write_time; std::unordered_map<std::string, int64_t> file2write_time;
struct DeclInfo { struct DeclInfo {
@ -81,6 +85,13 @@ struct IndexParam {
SeenFile(FE); SeenFile(FE);
return file_consumer->TryConsumeFile(FE, &file_contents); 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, StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts,
@ -639,7 +650,7 @@ public:
return true; return true;
int lid = -1; int lid = -1;
IndexFile *db; IndexFile *db;
if (g_config->index.multiVersion) { if (g_config->index.multiVersion && param.UseMultiVersion(*FE)) {
db = param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID())); db = param.ConsumeFile(*SM.getFileEntryForID(SM.getMainFileID()));
if (!db) if (!db)
return true; return true;
@ -1180,6 +1191,11 @@ template <typename T> void Uniquify(std::vector<T> &a) {
} }
namespace ccls::idx { namespace ccls::idx {
void Init() {
multiVersionMatcher = new GroupMatch(g_config->index.multiVersionWhitelist,
g_config->index.multiVersionBlacklist);
}
std::vector<std::unique_ptr<IndexFile>> std::vector<std::unique_ptr<IndexFile>>
Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
const std::vector<std::string> &args, const std::vector<std::string> &args,

View File

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

View File

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