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.
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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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<std::mutex> lock(vfs->mutex);
vfs->state[dep.first().str()].stage = 0;
}
} else
reparse = 2;
std::lock_guard<std::mutex> 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<std::mutex> lock(working_files->files_mutex);
for (auto& f : working_files->files) {
std::string filename = LowerPathIfInsensitive(f->filename);

View File

@ -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;
}
}
}

View File

@ -57,4 +57,6 @@ struct Project {
std::function<void(int i, const Entry& entry)> action);
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) {
LOG_S(INFO) << "read " << filename;
char buf[4096];
std::string ret;
FILE* f = fopen(filename.c_str(), "rb");