From 18fa5efa2ab6644c203388370e62521a081bf359 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 2 Jun 2018 00:33:12 -0700 Subject: [PATCH] Add Config->reparseForDependency Specify 1 if for large projects you don't want to reparse dependents at load time when a common .h changes. --- src/config.h | 11 +++++---- src/log.hh | 2 +- src/messages/text_document_document_symbol.cc | 6 +---- src/pipeline.cc | 23 +++++++++++-------- src/project.cc | 9 +++++--- src/project.h | 2 ++ src/utils.cc | 1 - 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/config.h b/src/config.h index 114f0c66..1ba2f1c6 100644 --- a/src/config.h +++ b/src/config.h @@ -177,14 +177,15 @@ struct Config { // If false, the indexer will be disabled. 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. // May be too slow for big projects, so it is off by default. 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. int threads = 0; @@ -235,8 +236,8 @@ MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled, - logSkippedPaths, onDidChange, + reparseForDependency, threads, whitelist); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); diff --git a/src/log.hh b/src/log.hh index caab8151..64fc63d6 100644 --- a/src/log.hh +++ b/src/log.hh @@ -37,4 +37,4 @@ struct Message { #define LOG_IF_S(v, cond) \ LOG_IF(ccls::log::Verbosity_##v, \ (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) diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 212994cd..6aec71ff 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -49,11 +49,7 @@ struct Handler_TextDocumentDocumentSymbol if (sym.kind == SymbolKind::Var) { QueryVar& var = db->GetVar(sym); auto* def = var.AnyDef(); - if (!def || !def->spell) - continue; - // Ignore local variables. - if (def->spell->kind == SymbolKind::Func && def->storage != SC_Static && - def->storage != SC_Extern) + if (!def || !def->spell || def->is_local()) continue; } diff --git a/src/pipeline.cc b/src/pipeline.cc index e5c1ce14..cece67d3 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -168,18 +168,22 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, if (FileNeedsParse(*write_time, vfs, request.is_interactive, &*prev, path_to_index, entry.args, std::nullopt)) reparse = 2; - for (const auto& dep : prev->dependencies) - if (auto write_time1 = LastWriteTime(dep.first().str())) { - if (dep.second < *write_time1) { + int reparseForDep = g_config->index.reparseForDependency; + if (reparseForDep > 1 || (reparseForDep == 1 && !Project::loaded)) + for (const auto& dep : prev->dependencies) { + if (auto write_time1 = LastWriteTime(dep.first().str())) { + if (dep.second < *write_time1) { + reparse = 2; + std::lock_guard lock(vfs->mutex); + vfs->state[dep.first().str()].stage = 0; + } + } else reparse = 2; - std::lock_guard lock(vfs->mutex); - vfs->state[dep.first().str()].stage = 0; - } - } else - reparse = 2; + } } if (reparse < 2) { + LOG_S(INFO) << "load cache for " << path_to_index; auto dependencies = prev->dependencies; if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); @@ -288,7 +292,8 @@ void Main_OnIndexed(DB* db, WorkingFiles* working_files, IndexUpdate* update) { 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 lock(working_files->files_mutex); for (auto& f : working_files->files) { std::string filename = LowerPathIfInsensitive(f->filename); diff --git a/src/project.cc b/src/project.cc index 0ff3193a..1310efc1 100644 --- a/src/project.cc +++ b/src/project.cc @@ -325,7 +325,10 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace +bool Project::loaded = false; + void Project::Load(const std::string& root_directory) { + Project::loaded = false; // Load data. ProjectConfig project; project.extra_flags = g_config->clang.extraArgs; @@ -428,9 +431,9 @@ void Project::ForAllFilteredFiles( std::string failure_reason; if (matcher.IsMatch(entry.filename, &failure_reason)) action(i, entries[i]); - else if (g_config->index.logSkippedPaths) { - LOG_S(INFO) << "[" << i + 1 << "/" << entries.size() << "]: Failed " - << failure_reason << "; skipping " << entry.filename; + else { + LOG_V(1) << "[" << i + 1 << "/" << entries.size() << "]: Failed " + << failure_reason << "; skipping " << entry.filename; } } } diff --git a/src/project.h b/src/project.h index d6d3f396..f56f4b55 100644 --- a/src/project.h +++ b/src/project.h @@ -57,4 +57,6 @@ struct Project { std::function action); void Index(WorkingFiles* wfiles, lsRequestId id); + + static bool loaded; }; diff --git a/src/utils.cc b/src/utils.cc index 9c17c129..c10b9246 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -105,7 +105,6 @@ std::string EscapeFileName(std::string path) { } std::optional ReadContent(const std::string& filename) { - LOG_S(INFO) << "read " << filename; char buf[4096]; std::string ret; FILE* f = fopen(filename.c_str(), "rb");