Add Config->reparseForDependency

Specify 1 if for large projects you don't want to reparse dependents at load time when a common .h changes.
This commit is contained in:
Fangrui Song 2018-06-02 00:33:12 -07:00
parent d165a0b0ea
commit 18fa5efa2a
7 changed files with 30 additions and 24 deletions

View File

@ -177,14 +177,15 @@ struct Config {
// If false, the indexer will be disabled. // If false, the indexer will be disabled.
bool enabled = true; bool enabled = true;
// If true, project paths that were skipped by the whitelist/blacklist will
// be logged.
bool logSkippedPaths = false;
// 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;
// Whether to reparse a file if write times of its dependencies have
// changed. The file will always be reparsed if its own write time changes.
// 0: no, 1: only after initial load of project, 2: yes
int reparseForDependency = 2;
// Number of indexer threads. If 0, 80% of cores are used. // Number of indexer threads. If 0, 80% of cores are used.
int threads = 0; int threads = 0;
@ -235,8 +236,8 @@ MAKE_REFLECT_STRUCT(Config::Index,
blacklist, blacklist,
comments, comments,
enabled, enabled,
logSkippedPaths,
onDidChange, onDidChange,
reparseForDependency,
threads, threads,
whitelist); whitelist);
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);

View File

@ -37,4 +37,4 @@ struct Message {
#define LOG_IF_S(v, cond) \ #define LOG_IF_S(v, cond) \
LOG_IF(ccls::log::Verbosity_##v, \ LOG_IF(ccls::log::Verbosity_##v, \
(cond) && ccls::log::Verbosity_##v <= ccls::log::verbosity) (cond) && ccls::log::Verbosity_##v <= ccls::log::verbosity)
#define CHECK_S(cond) LOG_IF(FATAL, !(cond)) << "check failed: " #cond " " #define LOG_V(v) LOG_IF(ccls::log::Verbosity(v), v <= ccls::log::verbosity)

View File

@ -49,11 +49,7 @@ struct Handler_TextDocumentDocumentSymbol
if (sym.kind == SymbolKind::Var) { if (sym.kind == SymbolKind::Var) {
QueryVar& var = db->GetVar(sym); QueryVar& var = db->GetVar(sym);
auto* def = var.AnyDef(); auto* def = var.AnyDef();
if (!def || !def->spell) if (!def || !def->spell || def->is_local())
continue;
// Ignore local variables.
if (def->spell->kind == SymbolKind::Func && def->storage != SC_Static &&
def->storage != SC_Extern)
continue; continue;
} }

View File

@ -168,18 +168,22 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine,
if (FileNeedsParse(*write_time, vfs, request.is_interactive, &*prev, if (FileNeedsParse(*write_time, vfs, request.is_interactive, &*prev,
path_to_index, entry.args, std::nullopt)) path_to_index, entry.args, std::nullopt))
reparse = 2; reparse = 2;
for (const auto& dep : prev->dependencies) int reparseForDep = g_config->index.reparseForDependency;
if (auto write_time1 = LastWriteTime(dep.first().str())) { if (reparseForDep > 1 || (reparseForDep == 1 && !Project::loaded))
if (dep.second < *write_time1) { for (const auto& dep : prev->dependencies) {
if (auto write_time1 = LastWriteTime(dep.first().str())) {
if (dep.second < *write_time1) {
reparse = 2;
std::lock_guard<std::mutex> lock(vfs->mutex);
vfs->state[dep.first().str()].stage = 0;
}
} else
reparse = 2; reparse = 2;
std::lock_guard<std::mutex> lock(vfs->mutex); }
vfs->state[dep.first().str()].stage = 0;
}
} else
reparse = 2;
} }
if (reparse < 2) { if (reparse < 2) {
LOG_S(INFO) << "load cache for " << path_to_index;
auto dependencies = prev->dependencies; auto dependencies = prev->dependencies;
if (reparse) { if (reparse) {
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
@ -288,7 +292,8 @@ void Main_OnIndexed(DB* db,
WorkingFiles* working_files, WorkingFiles* working_files,
IndexUpdate* update) { IndexUpdate* update) {
if (update->refresh) { if (update->refresh) {
LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; Project::loaded = true;
LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file.";
std::lock_guard<std::mutex> lock(working_files->files_mutex); std::lock_guard<std::mutex> lock(working_files->files_mutex);
for (auto& f : working_files->files) { for (auto& f : working_files->files) {
std::string filename = LowerPathIfInsensitive(f->filename); std::string filename = LowerPathIfInsensitive(f->filename);

View File

@ -325,7 +325,10 @@ int ComputeGuessScore(std::string_view a, std::string_view b) {
} // namespace } // namespace
bool Project::loaded = false;
void Project::Load(const std::string& root_directory) { void Project::Load(const std::string& root_directory) {
Project::loaded = false;
// Load data. // Load data.
ProjectConfig project; ProjectConfig project;
project.extra_flags = g_config->clang.extraArgs; project.extra_flags = g_config->clang.extraArgs;
@ -428,9 +431,9 @@ void Project::ForAllFilteredFiles(
std::string failure_reason; std::string failure_reason;
if (matcher.IsMatch(entry.filename, &failure_reason)) if (matcher.IsMatch(entry.filename, &failure_reason))
action(i, entries[i]); action(i, entries[i]);
else if (g_config->index.logSkippedPaths) { else {
LOG_S(INFO) << "[" << i + 1 << "/" << entries.size() << "]: Failed " LOG_V(1) << "[" << i + 1 << "/" << entries.size() << "]: Failed "
<< failure_reason << "; skipping " << entry.filename; << failure_reason << "; skipping " << entry.filename;
} }
} }
} }

View File

@ -57,4 +57,6 @@ struct Project {
std::function<void(int i, const Entry& entry)> action); std::function<void(int i, const Entry& entry)> action);
void Index(WorkingFiles* wfiles, lsRequestId id); void Index(WorkingFiles* wfiles, lsRequestId id);
static bool loaded;
}; };

View File

@ -105,7 +105,6 @@ std::string EscapeFileName(std::string path) {
} }
std::optional<std::string> ReadContent(const std::string& filename) { std::optional<std::string> ReadContent(const std::string& filename) {
LOG_S(INFO) << "read " << filename;
char buf[4096]; char buf[4096];
std::string ret; std::string ret;
FILE* f = fopen(filename.c_str(), "rb"); FILE* f = fopen(filename.c_str(), "rb");