diff --git a/src/command_line.cc b/src/command_line.cc index b57210e0..e38c52f1 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -187,6 +187,7 @@ struct IpcManager { RegisterId(ipc.get()); RegisterId(ipc.get()); RegisterId(ipc.get()); + RegisterId(ipc.get()); return ipc; } }; @@ -784,6 +785,7 @@ struct Index_DoIndex { ImportAndUpdate, ImportOnly, Parse, + Freshen, }; Index_DoIndex(Type type, const std::string& path, const optional>& args) @@ -839,6 +841,7 @@ void RegisterMessageTypes() { MessageRegistry::instance()->Register(); MessageRegistry::instance()->Register(); MessageRegistry::instance()->Register(); + MessageRegistry::instance()->Register(); } @@ -870,7 +873,16 @@ void RegisterMessageTypes() { +void DispatchDependencyImports(Index_DoIndexQueue* queue_do_index, + Index_DoIndex::Type request_type, + const std::vector& dependencies) { + // Import all dependencies. + for (auto& dependency_path : dependencies) { + std::cerr << "- Dispatching dependency import " << dependency_path << std::endl; + queue_do_index->PriorityEnqueue(Index_DoIndex(request_type, dependency_path, nullopt)); + } +} void ImportCachedIndex(IndexerConfig* config, Index_DoIndexQueue* queue_do_index, @@ -886,11 +898,7 @@ void ImportCachedIndex(IndexerConfig* config, if (!cache) return; - // Import all dependencies. - for (auto& dependency_path : cache->dependencies) { - std::cerr << "- Dispatching dependency import " << dependency_path << std::endl; - queue_do_index->PriorityEnqueue(Index_DoIndex(Index_DoIndex::Type::ImportOnly, dependency_path, nullopt)); - } + DispatchDependencyImports(queue_do_index, Index_DoIndex::Type::ImportOnly, cache->dependencies); *last_modification_time = cache->last_modification_time; Index_DoIdMap response(nullptr, std::move(cache)); @@ -901,16 +909,27 @@ void ParseFile(IndexerConfig* config, FileConsumer::SharedState* file_consumer_shared, Index_DoIdMapQueue* queue_do_id_map, const std::string& path, - const optional>& args) { + const optional>& args, + std::vector* opt_out_dependencies) { Timer time; // Parse request and send a response. std::unique_ptr cached_path_index = LoadCachedFile(config, path); - // Skip index if file modification time didn't change. - if (cached_path_index && GetLastModificationTime(path) == cached_path_index->last_modification_time) { - time.ResetAndPrint("Skipping index update on " + path + " since file modification time has not changed"); - return; + if (cached_path_index) { + // Give the user dependencies if requested. + if (opt_out_dependencies) + *opt_out_dependencies = cached_path_index->dependencies; + + // Skip index if file modification time didn't change. + int64_t modification_time = GetLastModificationTime(path); + if (modification_time == cached_path_index->last_modification_time) { + time.ResetAndPrint("Skipping index update on " + path + " since file modification time has not changed"); + return; + } + else { + time.ResetAndPrint("Modification time on " + path + " has changed from " + std::to_string(cached_path_index->last_modification_time) + " to " + std::to_string(modification_time)); + } } std::vector> indexes = Parse( @@ -982,7 +1001,14 @@ bool IndexMain_DoIndex(IndexerConfig* config, } case Index_DoIndex::Type::Parse: { - ParseFile(config, file_consumer_shared, queue_do_id_map, index_request->path, index_request->args); + ParseFile(config, file_consumer_shared, queue_do_id_map, index_request->path, index_request->args, nullptr); + break; + } + + case Index_DoIndex::Type::Freshen: { + std::vector dependencies; + ParseFile(config, file_consumer_shared, queue_do_id_map, index_request->path, index_request->args, &dependencies); + DispatchDependencyImports(queue_do_index, Index_DoIndex::Type::Freshen, dependencies); break; } } @@ -1145,60 +1171,28 @@ void QueryDbMainLoop( Ipc_OpenProject* msg = static_cast(message.get()); std::string path = msg->project_path; - std::vector whitelist; - std::cerr << "Using whitelist" << std::endl; - for (const std::string& entry : config->whitelist) { - std::cerr << " - " << entry << std::endl; - whitelist.push_back(Matcher(entry)); - } - - std::vector blacklist; - std::cerr << "Using blacklist" << std::endl; - for (const std::string& entry : config->blacklist) { - std::cerr << " - " << entry << std::endl; - blacklist.push_back(Matcher(entry)); - } - - project->Load(path); std::cerr << "Loaded compilation entries (" << project->entries.size() << " files)" << std::endl; - //for (int i = 0; i < 10; ++i) - //std::cerr << project->entries[i].filename << std::endl; - for (int i = 0; i < project->entries.size(); ++i) { - const Project::Entry& entry = project->entries[i]; - std::string filepath = entry.filename; - - - const Matcher* is_bad = nullptr; - for (const Matcher& m : whitelist) { - if (!m.IsMatch(filepath)) { - is_bad = &m; - break; - } - } - if (is_bad) { - std::cerr << "[" << i << "/" << (project->entries.size() - 1) << "] Failed whitelist check \"" << is_bad->regex_string << "\"; skipping " << filepath << std::endl; - continue; - } - - for (const Matcher& m : blacklist) { - if (m.IsMatch(filepath)) { - is_bad = &m; - break; - } - } - if (is_bad) { - std::cerr << "[" << i << "/" << (project->entries.size() - 1) << "] Failed blacklist check \"" << is_bad->regex_string << "\"; skipping " << filepath << std::endl; - continue; - } - + project->ForAllFilteredFiles(config, [&](int i, const Project::Entry& entry) { std::cerr << "[" << i << "/" << (project->entries.size() - 1) - << "] Dispatching index request for file " << filepath + << "] Dispatching index request for file " << entry.filename << std::endl; - queue_do_index->Enqueue(Index_DoIndex(Index_DoIndex::Type::ImportAndUpdate, filepath, entry.args)); - } + queue_do_index->Enqueue(Index_DoIndex(Index_DoIndex::Type::ImportAndUpdate, entry.filename, entry.args)); + }); + + break; + } + + case IpcId::CqueryFreshenIndex: { + std::cerr << "Freshening " << project->entries.size() << " files" << std::endl; + project->ForAllFilteredFiles(config, [&](int i, const Project::Entry& entry) { + std::cerr << "[" << i << "/" << (project->entries.size() - 1) + << "] Dispatching index request for file " << entry.filename + << std::endl; + queue_do_index->Enqueue(Index_DoIndex(Index_DoIndex::Type::Freshen, entry.filename, entry.args)); + }); break; } @@ -1876,7 +1870,8 @@ void LanguageServerStdinLoop(IndexerConfig* config) { case IpcId::TextDocumentReferences: case IpcId::TextDocumentDocumentSymbol: case IpcId::TextDocumentCodeLens: - case IpcId::WorkspaceSymbol: { + case IpcId::WorkspaceSymbol: + case IpcId::CqueryFreshenIndex: { ipc->SendMessage(IpcManager::Destination::Server, std::move(message)); break; } diff --git a/src/indexer.h b/src/indexer.h index 235b606b..03d0ca44 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -465,7 +465,7 @@ struct IdCache { struct IndexedFile { IdCache id_cache; - static constexpr int kCurrentVersion = 1; + static constexpr int kCurrentVersion = 2; int version = 0; std::string path; diff --git a/src/ipc.cc b/src/ipc.cc index 5d455490..339da10c 100644 --- a/src/ipc.cc +++ b/src/ipc.cc @@ -39,6 +39,9 @@ const char* IpcIdToString(IpcId id) { case IpcId::WorkspaceSymbol: return "workspace/symbol"; + case IpcId::CqueryFreshenIndex: { + return "$cquery/freshenIndex"; + } case IpcId::Quit: return "$quit"; diff --git a/src/ipc.h b/src/ipc.h index be38e647..2f01d63c 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -25,6 +25,9 @@ enum class IpcId : int { CodeLensResolve, WorkspaceSymbol, + // Custom messages + CqueryFreshenIndex, + // Internal implementation detail. Quit, IsAlive, diff --git a/src/language_server_api.h b/src/language_server_api.h index d9da01c6..d204c102 100644 --- a/src/language_server_api.h +++ b/src/language_server_api.h @@ -1340,7 +1340,7 @@ struct lsWorkspaceSymbolParams { std::string query; }; MAKE_REFLECT_STRUCT(lsWorkspaceSymbolParams, query); -struct Ipc_WorkspaceSymbol : public IpcMessage { +struct Ipc_WorkspaceSymbol : public IpcMessage { const static IpcId kIpcId = IpcId::WorkspaceSymbol; lsRequestId id; lsWorkspaceSymbolParams params; @@ -1381,4 +1381,11 @@ void Reflect(TVisitor& visitor, Out_ShowLogMessage& value) { REFLECT_MEMBER2("method", value.method()); REFLECT_MEMBER(params); REFLECT_MEMBER_END(); -} \ No newline at end of file +} + + +struct Ipc_CqueryFreshenIndex : public IpcMessage { + const static IpcId kIpcId = IpcId::CqueryFreshenIndex; + lsRequestId id; +}; +MAKE_REFLECT_STRUCT(Ipc_CqueryFreshenIndex, id); \ No newline at end of file diff --git a/src/project.cc b/src/project.cc index ed7d353f..4980fb22 100644 --- a/src/project.cc +++ b/src/project.cc @@ -1,5 +1,6 @@ #include "project.h" +#include "fuzzy.h" #include "libclangmm/Utility.h" #include "platform.h" #include "serializer.h" @@ -261,4 +262,51 @@ optional> Project::FindArgsForFile(const std::string& f if (!entry) return nullopt; return entry->args; -} \ No newline at end of file +} + +void Project::ForAllFilteredFiles(IndexerConfig* config, std::function action) { + std::vector whitelist; + std::cerr << "Using whitelist" << std::endl; + for (const std::string& entry : config->whitelist) { + std::cerr << " - " << entry << std::endl; + whitelist.push_back(Matcher(entry)); + } + + std::vector blacklist; + std::cerr << "Using blacklist" << std::endl; + for (const std::string& entry : config->blacklist) { + std::cerr << " - " << entry << std::endl; + blacklist.push_back(Matcher(entry)); + } + + + for (int i = 0; i < entries.size(); ++i) { + const Project::Entry& entry = entries[i]; + std::string filepath = entry.filename; + + const Matcher* is_bad = nullptr; + for (const Matcher& m : whitelist) { + if (!m.IsMatch(filepath)) { + is_bad = &m; + break; + } + } + if (is_bad) { + std::cerr << "[" << i << "/" << (entries.size() - 1) << "] Failed whitelist check \"" << is_bad->regex_string << "\"; skipping " << filepath << std::endl; + continue; + } + + for (const Matcher& m : blacklist) { + if (m.IsMatch(filepath)) { + is_bad = &m; + break; + } + } + if (is_bad) { + std::cerr << "[" << i << "/" << (entries.size() - 1) << "] Failed blacklist check \"" << is_bad->regex_string << "\"; skipping " << filepath << std::endl; + continue; + } + + action(i, entries[i]); + } +} diff --git a/src/project.h b/src/project.h index b64021a9..d2553740 100644 --- a/src/project.h +++ b/src/project.h @@ -1,8 +1,11 @@ #pragma once +#include "language_server_api.h" + #include #include +#include #include #include #include @@ -32,5 +35,7 @@ struct Project { // Helper that uses FindCompilationEntryForFile. optional> FindArgsForFile(const std::string& filename); + + void ForAllFilteredFiles(IndexerConfig* config, std::function action); };