mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-03 22:04:24 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									7b1ff448b9
								
							
						
					
					
						commit
						0decb01a0f
					
				
							
								
								
									
										11
									
								
								src/config.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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);
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -57,4 +57,6 @@ struct Project {
 | 
			
		||||
      std::function<void(int i, const Entry& entry)> action);
 | 
			
		||||
 | 
			
		||||
  void Index(WorkingFiles* wfiles, lsRequestId id);
 | 
			
		||||
 | 
			
		||||
  static bool loaded;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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");
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user