From c9f0b65062746b41daa24bcaecfaed78e72bab03 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 27 May 2018 17:50:02 -0700 Subject: [PATCH] Simplify pipeline --- CMakeLists.txt | 8 +- src/cache_manager.cc | 62 ------ src/cache_manager.h | 26 --- src/clang_complete.cc | 31 +-- src/clang_complete.h | 3 +- src/clang_translation_unit.cc | 155 -------------- src/clang_translation_unit.h | 30 --- src/{clang_cursor.cc => clang_tu.cc} | 154 +++++++++++++- src/{clang_cursor.h => clang_tu.h} | 25 ++- src/diagnostics_engine.cc | 5 +- src/include_complete.cc | 2 +- src/{clang_indexer.cc => indexer.cc} | 2 - src/indexer.h | 3 +- src/main.cc | 10 +- src/match.cc | 5 +- src/message_handler.cc | 9 +- src/messages/ccls_base.cc | 5 +- src/messages/ccls_call_hierarchy.cc | 6 +- src/messages/ccls_callers.cc | 5 +- src/messages/ccls_file_info.cc | 5 +- src/messages/ccls_freshen_index.cc | 7 +- src/messages/ccls_inheritance_hierarchy.cc | 13 +- src/messages/ccls_member_hierarchy.cc | 5 +- src/messages/ccls_random.cc | 5 +- src/messages/ccls_vars.cc | 5 +- src/messages/initialize.cc | 9 +- src/messages/shutdown.cc | 5 +- src/messages/text_document_code_lens.cc | 5 +- src/messages/text_document_completion.cc | 9 +- src/messages/text_document_definition.cc | 5 +- src/messages/text_document_did_change.cc | 8 +- src/messages/text_document_did_close.cc | 5 +- src/messages/text_document_did_open.cc | 17 +- src/messages/text_document_did_save.cc | 11 +- .../text_document_document_highlight.cc | 5 +- src/messages/text_document_document_symbol.cc | 5 +- src/messages/text_document_hover.cc | 5 +- src/messages/text_document_implementation.cc | 5 +- .../text_document_range_formatting.cc | 5 +- src/messages/text_document_references.cc | 5 +- src/messages/text_document_rename.cc | 5 +- src/messages/text_document_signature_help.cc | 5 +- src/messages/text_document_type_definition.cc | 5 +- .../workspace_did_change_configuration.cc | 6 +- .../workspace_did_change_watched_files.cc | 10 +- src/messages/workspace_execute_command.cc | 5 +- src/messages/workspace_symbol.cc | 5 +- src/pipeline.cc | 189 +++++++++++++----- src/pipeline.hh | 33 +-- src/port.cc | 10 - src/port.h | 34 ---- src/project.cc | 12 +- src/project.h | 6 +- src/query_utils.cc | 2 +- src/queue_manager.cc | 46 ----- src/queue_manager.h | 84 -------- src/serializer.h | 21 +- src/test.cc | 2 - src/threaded_queue.h | 20 -- src/utils.cc | 9 - src/utils.h | 2 - 61 files changed, 479 insertions(+), 722 deletions(-) delete mode 100644 src/cache_manager.cc delete mode 100644 src/cache_manager.h delete mode 100644 src/clang_translation_unit.cc delete mode 100644 src/clang_translation_unit.h rename src/{clang_cursor.cc => clang_tu.cc} (64%) rename src/{clang_cursor.h => clang_tu.h} (82%) rename src/{clang_indexer.cc => indexer.cc} (99%) delete mode 100644 src/port.cc delete mode 100644 src/port.h delete mode 100644 src/queue_manager.cc delete mode 100644 src/queue_manager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f3bdd59f..52f0f269 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,11 +189,8 @@ file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h target_sources(ccls PRIVATE third_party/siphash.cc) target_sources(ccls PRIVATE - src/cache_manager.cc src/clang_complete.cc - src/clang_cursor.cc - src/clang_indexer.cc - src/clang_translation_unit.cc + src/clang_tu.cc src/clang_utils.cc src/config.cc src/diagnostics_engine.cc @@ -202,6 +199,7 @@ target_sources(ccls PRIVATE src/fuzzy_match.cc src/main.cc src/include_complete.cc + src/indexer.cc src/method.cc src/language.cc src/lex_utils.cc @@ -212,12 +210,10 @@ target_sources(ccls PRIVATE src/pipeline.cc src/platform_posix.cc src/platform_win.cc - src/port.cc src/position.cc src/project.cc src/query_utils.cc src/query.cc - src/queue_manager.cc src/serializer.cc src/test.cc src/third_party_impl.cc diff --git a/src/cache_manager.cc b/src/cache_manager.cc deleted file mode 100644 index c3e64788..00000000 --- a/src/cache_manager.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "cache_manager.h" - -#include "config.h" -#include "indexer.h" -#include "lsp.h" -#include "platform.h" - -#include -#include - -namespace { -std::string GetCachePath(const std::string& source_file) { - assert(!g_config->cacheDirectory.empty()); - std::string cache_file; - size_t len = g_config->projectRoot.size(); - if (StartsWith(source_file, g_config->projectRoot)) { - cache_file = EscapeFileName(g_config->projectRoot) + - EscapeFileName(source_file.substr(len)); - } else { - cache_file = '@' + EscapeFileName(g_config->projectRoot) + - EscapeFileName(source_file); - } - - return g_config->cacheDirectory + cache_file; -} - -std::string AppendSerializationFormat(const std::string& base) { - switch (g_config->cacheFormat) { - case SerializeFormat::Binary: - return base + ".blob"; - case SerializeFormat::Json: - return base + ".json"; - } -} -} - -// Manages loading caches from file paths for the indexer process. -void ICacheManager::WriteToCache(IndexFile& file) { - std::string cache_path = GetCachePath(file.path); - WriteToFile(cache_path, file.file_contents); - - std::string indexed_content = Serialize(g_config->cacheFormat, file); - WriteToFile(AppendSerializationFormat(cache_path), indexed_content); -} - -std::optional ICacheManager::LoadCachedFileContents( - const std::string& path) { - return ReadContent(GetCachePath(path)); -} - -std::unique_ptr ICacheManager::RawCacheLoad( - const std::string& path) { - std::string cache_path = GetCachePath(path); - std::optional file_content = ReadContent(cache_path); - std::optional serialized_indexed_content = - ReadContent(AppendSerializationFormat(cache_path)); - if (!file_content || !serialized_indexed_content) - return nullptr; - - return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, - *file_content, IndexFile::kMajorVersion); -} diff --git a/src/cache_manager.h b/src/cache_manager.h deleted file mode 100644 index daffdd48..00000000 --- a/src/cache_manager.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -struct IndexFile; - -struct ICacheManager { - void WriteToCache(IndexFile& file); - - std::optional LoadCachedFileContents(const std::string& path); - - template - void IterateLoadedCaches(Fn fn) { - for (const auto& cache : caches_) - fn(cache.second.get()); - } - - std::unique_ptr RawCacheLoad(const std::string& path); - - std::unordered_map> caches_; -}; diff --git a/src/clang_complete.cc b/src/clang_complete.cc index e06c7647..f35c9429 100644 --- a/src/clang_complete.cc +++ b/src/clang_complete.cc @@ -21,14 +21,8 @@ unsigned Flags() { CXTranslationUnit_CacheCompletionResults | CXTranslationUnit_PrecompiledPreamble | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion | - CXTranslationUnit_DetailedPreprocessingRecord -#if !defined(_WIN32) - // For whatever reason, CreatePreambleOnFirstParse causes clang to - // become very crashy on windows. - // TODO: do more investigation, submit fixes to clang. - | CXTranslationUnit_CreatePreambleOnFirstParse -#endif - ; + CXTranslationUnit_DetailedPreprocessingRecord | + CXTranslationUnit_CreatePreambleOnFirstParse; } std::string StripFileType(const std::string& path) { @@ -57,23 +51,6 @@ unsigned GetCompletionPriority(const CXCompletionString& str, return priority; } -/* -bool IsCallKind(CXCursorKind kind) { - switch (kind) { - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_CXXMethod: - case CXCursor_FunctionTemplate: - case CXCursor_FunctionDecl: - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - return true; - default: - return false; - } -} -*/ - lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) { switch (cursor_kind) { case CXCursor_UnexposedDecl: @@ -383,8 +360,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager, std::vector args = session->file.args; // -fspell-checking enables FixIts for, ie, misspelled types. - if (!AnyStartsWith(args, "-fno-spell-checking") && - !AnyStartsWith(args, "-fspell-checking")) { + if (!std::count(args.begin(), args.end(), "-fno-spell-checking") && + !std::count(args.begin(), args.end(), "-fspell-checking")) { args.push_back("-fspell-checking"); } diff --git a/src/clang_complete.h b/src/clang_complete.h index aa471c8e..af824df1 100644 --- a/src/clang_complete.h +++ b/src/clang_complete.h @@ -1,7 +1,6 @@ #pragma once -#include "clang_cursor.h" -#include "clang_translation_unit.h" +#include "clang_tu.h" #include "lru_cache.h" #include "lsp_completion.h" #include "lsp_diagnostic.h" diff --git a/src/clang_translation_unit.cc b/src/clang_translation_unit.cc deleted file mode 100644 index f9f9aaf4..00000000 --- a/src/clang_translation_unit.cc +++ /dev/null @@ -1,155 +0,0 @@ -#include "clang_translation_unit.h" - -#include "clang_utils.h" -#include "log.hh" -#include "platform.h" -#include "utils.h" - -namespace { - -void EmitDiagnostics(std::string path, - std::vector args, - CXTranslationUnit tu) { - std::string output = "Fatal errors while trying to parse " + path + "\n"; - output += - "Args: " + - StringJoinMap(args, [](const char* arg) { return std::string(arg); }) + - "\n"; - - size_t num_diagnostics = clang_getNumDiagnostics(tu); - for (unsigned i = 0; i < num_diagnostics; ++i) { - output += " - "; - - CXDiagnostic diagnostic = clang_getDiagnostic(tu, i); - - // Location. - CXFile file; - unsigned int line, column; - clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, - &line, &column, nullptr); - std::string path = FileName(file); - output += path + ":" + std::to_string(line - 1) + ":" + - std::to_string(column) + " "; - - // Severity - switch (clang_getDiagnosticSeverity(diagnostic)) { - case CXDiagnostic_Ignored: - case CXDiagnostic_Note: - output += "[info]"; - break; - case CXDiagnostic_Warning: - output += "[warning]"; - break; - case CXDiagnostic_Error: - output += "[error]"; - break; - case CXDiagnostic_Fatal: - output += "[fatal]"; - break; - } - - // Content. - output += " " + ToString(clang_getDiagnosticSpelling(diagnostic)); - - clang_disposeDiagnostic(diagnostic); - - output += "\n"; - } - - LOG_S(WARNING) << output; -} -} // namespace - -// static -std::unique_ptr ClangTranslationUnit::Create( - ClangIndex* index, - const std::string& filepath, - const std::vector& arguments, - std::vector& unsaved_files, - unsigned flags) { - std::vector args; - for (auto& arg : arguments) - args.push_back(arg.c_str()); - - CXTranslationUnit cx_tu; - CXErrorCode error_code; - { - error_code = clang_parseTranslationUnit2FullArgv( - index->cx_index, nullptr, args.data(), (int)args.size(), - unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu); - } - - if (error_code != CXError_Success && cx_tu) - EmitDiagnostics(filepath, args, cx_tu); - - // We sometimes dump the command to logs and ask the user to run it. Include - // -fsyntax-only so they don't do a full compile. - auto make_msg = [&]() { - return "Please try running the following, identify which flag causes the " - "issue, and report a bug. ccls will then filter the flag for you " - " automatically:\n " + - StringJoin(args, " ") + " -fsyntax-only"; - }; - - switch (error_code) { - case CXError_Success: - return std::make_unique(cx_tu); - case CXError_Failure: - LOG_S(ERROR) << "libclang generic failure for " << filepath << ". " - << make_msg(); - return nullptr; - case CXError_Crashed: - LOG_S(ERROR) << "libclang crashed for " << filepath << ". " << make_msg(); - return nullptr; - case CXError_InvalidArguments: - LOG_S(ERROR) << "libclang had invalid arguments for " << filepath << ". " - << make_msg(); - return nullptr; - case CXError_ASTReadError: - LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". " - << make_msg(); - return nullptr; - } - - return nullptr; -} - -// static -std::unique_ptr ClangTranslationUnit::Reparse( - std::unique_ptr tu, - std::vector& unsaved) { - int error_code; - { - error_code = clang_reparseTranslationUnit( - tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), - clang_defaultReparseOptions(tu->cx_tu)); - } - - if (error_code != CXError_Success && tu->cx_tu) - EmitDiagnostics("", {}, tu->cx_tu); - - switch (error_code) { - case CXError_Success: - return tu; - case CXError_Failure: - LOG_S(ERROR) << "libclang reparse generic failure"; - return nullptr; - case CXError_Crashed: - LOG_S(ERROR) << "libclang reparse crashed"; - return nullptr; - case CXError_InvalidArguments: - LOG_S(ERROR) << "libclang reparse had invalid arguments"; - return nullptr; - case CXError_ASTReadError: - LOG_S(ERROR) << "libclang reparse had ast read error"; - return nullptr; - } - - return nullptr; -} - -ClangTranslationUnit::ClangTranslationUnit(CXTranslationUnit tu) : cx_tu(tu) {} - -ClangTranslationUnit::~ClangTranslationUnit() { - clang_disposeTranslationUnit(cx_tu); -} diff --git a/src/clang_translation_unit.h b/src/clang_translation_unit.h deleted file mode 100644 index 59e2f17f..00000000 --- a/src/clang_translation_unit.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "clang_cursor.h" - -#include - -#include -#include -#include - -// RAII wrapper around CXTranslationUnit which also makes it much more -// challenging to use a CXTranslationUnit instance that is not correctly -// initialized. -struct ClangTranslationUnit { - static std::unique_ptr Create( - ClangIndex* index, - const std::string& filepath, - const std::vector& arguments, - std::vector& unsaved_files, - unsigned flags); - - static std::unique_ptr Reparse( - std::unique_ptr tu, - std::vector& unsaved); - - explicit ClangTranslationUnit(CXTranslationUnit tu); - ~ClangTranslationUnit(); - - CXTranslationUnit cx_tu; -}; diff --git a/src/clang_cursor.cc b/src/clang_tu.cc similarity index 64% rename from src/clang_cursor.cc rename to src/clang_tu.cc index ab880b3d..dbb1d89d 100644 --- a/src/clang_cursor.cc +++ b/src/clang_tu.cc @@ -1,12 +1,70 @@ -#include "clang_cursor.h" +#include "clang_tu.h" #include "clang_utils.h" +#include "log.hh" +#include "platform.h" +#include "utils.h" #include #include #include #include +namespace { + +void EmitDiagnostics(std::string path, + std::vector args, + CXTranslationUnit tu) { + std::string output = "Fatal errors while trying to parse " + path + "\n"; + output += + "Args: " + + StringJoinMap(args, [](const char* arg) { return std::string(arg); }) + + "\n"; + + size_t num_diagnostics = clang_getNumDiagnostics(tu); + for (unsigned i = 0; i < num_diagnostics; ++i) { + output += " - "; + + CXDiagnostic diagnostic = clang_getDiagnostic(tu, i); + + // Location. + CXFile file; + unsigned int line, column; + clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, + &line, &column, nullptr); + std::string path = FileName(file); + output += path + ":" + std::to_string(line - 1) + ":" + + std::to_string(column) + " "; + + // Severity + switch (clang_getDiagnosticSeverity(diagnostic)) { + case CXDiagnostic_Ignored: + case CXDiagnostic_Note: + output += "[info]"; + break; + case CXDiagnostic_Warning: + output += "[warning]"; + break; + case CXDiagnostic_Error: + output += "[error]"; + break; + case CXDiagnostic_Fatal: + output += "[fatal]"; + break; + } + + // Content. + output += " " + ToString(clang_getDiagnosticSpelling(diagnostic)); + + clang_disposeDiagnostic(diagnostic); + + output += "\n"; + } + + LOG_S(WARNING) << output; +} +} // namespace + Range ResolveCXSourceRange(const CXSourceRange& range, CXFile* cx_file) { CXSourceLocation start = clang_getRangeStart(range); CXSourceLocation end = clang_getRangeEnd(range); @@ -284,3 +342,97 @@ ClangIndex::ClangIndex(int exclude_declarations_from_pch, ClangIndex::~ClangIndex() { clang_disposeIndex(cx_index); } + +// static +std::unique_ptr ClangTranslationUnit::Create( + ClangIndex* index, + const std::string& filepath, + const std::vector& arguments, + std::vector& unsaved_files, + unsigned flags) { + std::vector args; + for (auto& arg : arguments) + args.push_back(arg.c_str()); + + CXTranslationUnit cx_tu; + CXErrorCode error_code; + { + error_code = clang_parseTranslationUnit2FullArgv( + index->cx_index, nullptr, args.data(), (int)args.size(), + unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu); + } + + if (error_code != CXError_Success && cx_tu) + EmitDiagnostics(filepath, args, cx_tu); + + // We sometimes dump the command to logs and ask the user to run it. Include + // -fsyntax-only so they don't do a full compile. + auto make_msg = [&]() { + return "Please try running the following, identify which flag causes the " + "issue, and report a bug. ccls will then filter the flag for you " + " automatically:\n " + + StringJoin(args, " ") + " -fsyntax-only"; + }; + + switch (error_code) { + case CXError_Success: + return std::make_unique(cx_tu); + case CXError_Failure: + LOG_S(ERROR) << "libclang generic failure for " << filepath << ". " + << make_msg(); + return nullptr; + case CXError_Crashed: + LOG_S(ERROR) << "libclang crashed for " << filepath << ". " << make_msg(); + return nullptr; + case CXError_InvalidArguments: + LOG_S(ERROR) << "libclang had invalid arguments for " << filepath << ". " + << make_msg(); + return nullptr; + case CXError_ASTReadError: + LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". " + << make_msg(); + return nullptr; + } + + return nullptr; +} + +// static +std::unique_ptr ClangTranslationUnit::Reparse( + std::unique_ptr tu, + std::vector& unsaved) { + int error_code; + { + error_code = clang_reparseTranslationUnit( + tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), + clang_defaultReparseOptions(tu->cx_tu)); + } + + if (error_code != CXError_Success && tu->cx_tu) + EmitDiagnostics("", {}, tu->cx_tu); + + switch (error_code) { + case CXError_Success: + return tu; + case CXError_Failure: + LOG_S(ERROR) << "libclang reparse generic failure"; + return nullptr; + case CXError_Crashed: + LOG_S(ERROR) << "libclang reparse crashed"; + return nullptr; + case CXError_InvalidArguments: + LOG_S(ERROR) << "libclang reparse had invalid arguments"; + return nullptr; + case CXError_ASTReadError: + LOG_S(ERROR) << "libclang reparse had ast read error"; + return nullptr; + } + + return nullptr; +} + +ClangTranslationUnit::ClangTranslationUnit(CXTranslationUnit tu) : cx_tu(tu) {} + +ClangTranslationUnit::~ClangTranslationUnit() { + clang_disposeTranslationUnit(cx_tu); +} diff --git a/src/clang_cursor.h b/src/clang_tu.h similarity index 82% rename from src/clang_cursor.h rename to src/clang_tu.h index 67acd08b..2530b2de 100644 --- a/src/clang_cursor.h +++ b/src/clang_tu.h @@ -1,12 +1,10 @@ #pragma once - #include "nt_string.h" #include "position.h" #include -#include -#include +#include #include #include @@ -119,3 +117,24 @@ class ClangIndex { ~ClangIndex(); CXIndex cx_index; }; + +// RAII wrapper around CXTranslationUnit which also makes it much more +// challenging to use a CXTranslationUnit instance that is not correctly +// initialized. +struct ClangTranslationUnit { + static std::unique_ptr Create( + ClangIndex* index, + const std::string& filepath, + const std::vector& arguments, + std::vector& unsaved_files, + unsigned flags); + + static std::unique_ptr Reparse( + std::unique_ptr tu, + std::vector& unsaved); + + explicit ClangTranslationUnit(CXTranslationUnit tu); + ~ClangTranslationUnit(); + + CXTranslationUnit cx_tu; +}; diff --git a/src/diagnostics_engine.cc b/src/diagnostics_engine.cc index 3e7ce0f7..c714ec9b 100644 --- a/src/diagnostics_engine.cc +++ b/src/diagnostics_engine.cc @@ -1,6 +1,7 @@ #include "diagnostics_engine.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -30,6 +31,6 @@ void DiagnosticsEngine::Publish(WorkingFiles* working_files, Out_TextDocumentPublishDiagnostics out; out.params.uri = lsDocumentUri::FromPath(path); out.params.diagnostics = diagnostics; - QueueManager::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); + pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); } } diff --git a/src/include_complete.cc b/src/include_complete.cc index 1d1b74a1..5fb6c9b1 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -107,7 +107,7 @@ void IncludeComplete::Rescan() { is_scanning = true; std::thread([this]() { - set_thread_name("scan_includes"); + set_thread_name("include"); Timer timer; for (const std::string& dir : project_->quote_include_directories) diff --git a/src/clang_indexer.cc b/src/indexer.cc similarity index 99% rename from src/clang_indexer.cc rename to src/indexer.cc index a9d66986..0794a5f3 100644 --- a/src/clang_indexer.cc +++ b/src/indexer.cc @@ -1,7 +1,5 @@ #include "indexer.h" -#include "clang_cursor.h" -#include "clang_utils.h" #include "log.hh" #include "platform.h" #include "serializer.h" diff --git a/src/indexer.h b/src/indexer.h index 2c35784e..ae29f918 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -1,7 +1,6 @@ #pragma once -#include "clang_cursor.h" -#include "clang_translation_unit.h" +#include "clang_tu.h" #include "clang_utils.h" #include "file_consumer.h" #include "language.h" diff --git a/src/main.cc b/src/main.cc index fcfc66e9..03936f5c 100644 --- a/src/main.cc +++ b/src/main.cc @@ -5,6 +5,7 @@ #include "serializers/json.h" #include "test.h" #include "working_files.h" +using namespace ccls; #include #include @@ -56,8 +57,7 @@ int main(int argc, char** argv) { return 0; } - MultiQueueWaiter querydb_waiter, indexer_waiter, stdout_waiter; - QueueManager::Init(&querydb_waiter, &indexer_waiter, &stdout_waiter); + pipeline::Init(); #ifdef _WIN32 // We need to write to stdout in binary mode because in Windows, writing @@ -132,11 +132,11 @@ int main(int argc, char** argv) { std::unordered_map request_times; // The thread that reads from stdin and dispatchs commands to the main thread. - LaunchStdinLoop(&request_times); + pipeline::LaunchStdin(&request_times); // The thread that writes responses from the main thread to stdout. - LaunchStdoutThread(&request_times, &stdout_waiter); + pipeline::LaunchStdout(&request_times); // Main thread which also spawns indexer threads upon the "initialize" request. - MainLoop(&querydb_waiter, &indexer_waiter); + pipeline::MainLoop(); } return 0; diff --git a/src/match.cc b/src/match.cc index 6f6bda56..178095d6 100644 --- a/src/match.cc +++ b/src/match.cc @@ -1,7 +1,8 @@ #include "match.h" #include "lsp.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -32,7 +33,7 @@ std::optional Matcher::Create(const std::string& search) { out.params.type = lsMessageType::Error; out.params.message = "ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); return std::nullopt; } } diff --git a/src/message_handler.cc b/src/message_handler.cc index a0014c21..cd7915e5 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -4,7 +4,8 @@ #include "log.hh" #include "project.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -167,7 +168,7 @@ bool FindFileOrFail(QueryDatabase* db, out.error.code = lsErrorCodes::InternalError; out.error.message = "Unable to find file " + absolute_path; } - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); } return false; @@ -182,7 +183,7 @@ void EmitInactiveLines(WorkingFile* working_file, if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped); } - QueueManager::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); + pipeline::WriteStdout(kMethodType_CclsPublishInactiveRegions, out); } void EmitSemanticHighlighting(QueryDatabase* db, @@ -343,5 +344,5 @@ void EmitSemanticHighlighting(QueryDatabase* db, for (auto& entry : grouped_symbols) if (entry.second.ranges.size()) out.params.symbols.push_back(entry.second); - QueueManager::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); + pipeline::WriteStdout(kMethodType_CclsPublishSemanticHighlighting, out); } diff --git a/src/messages/ccls_base.cc b/src/messages/ccls_base.cc index 80413762..fa04a498 100644 --- a/src/messages/ccls_base.cc +++ b/src/messages/ccls_base.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { @@ -43,7 +44,7 @@ struct Handler_CclsBase : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsBase); diff --git a/src/messages/ccls_call_hierarchy.cc b/src/messages/ccls_call_hierarchy.cc index 08c94515..2911d75d 100644 --- a/src/messages/ccls_call_hierarchy.cc +++ b/src/messages/ccls_call_hierarchy.cc @@ -1,6 +1,8 @@ #include "message_handler.h" +#include "pipeline.hh" +using namespace ccls; #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include @@ -225,7 +227,7 @@ struct Handler_CclsCallHierarchy } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsCallHierarchy); diff --git a/src/messages/ccls_callers.cc b/src/messages/ccls_callers.cc index db781be9..4325d3b7 100644 --- a/src/messages/ccls_callers.cc +++ b/src/messages/ccls_callers.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "$ccls/callers"; @@ -39,7 +40,7 @@ struct Handler_CclsCallers : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsCallers); diff --git a/src/messages/ccls_file_info.cc b/src/messages/ccls_file_info.cc index cbd6ed78..689ef1f9 100644 --- a/src/messages/ccls_file_info.cc +++ b/src/messages/ccls_file_info.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; MAKE_REFLECT_STRUCT(QueryFile::Def, path, @@ -49,7 +50,7 @@ struct Handler_CclsFileInfo : BaseMessageHandler { out.result.language = file->def->language; out.result.includes = file->def->includes; out.result.inactive_regions = file->def->inactive_regions; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFileInfo); diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index bf36450f..6584b373 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -1,12 +1,11 @@ -#include "cache_manager.h" #include "match.h" #include "message_handler.h" -#include "pipeline.hh" #include "platform.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "timer.h" #include "working_files.h" +using namespace ccls; #include #include @@ -79,7 +78,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { } // Send index requests for every file. - project->Index(QueueManager::instance(), working_files, lsRequestId()); + project->Index(working_files, lsRequestId()); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsFreshenIndex); diff --git a/src/messages/ccls_inheritance_hierarchy.cc b/src/messages/ccls_inheritance_hierarchy.cc index bbf255a1..c6fccaff 100644 --- a/src/messages/ccls_inheritance_hierarchy.cc +++ b/src/messages/ccls_inheritance_hierarchy.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include @@ -95,7 +96,7 @@ bool ExpandHelper(MessageHandler* m, if (derived) { if (levels > 0) { for (auto usr : entity.derived) { - if (seen.insert(usr).second) + if (!seen.insert(usr).second) continue; Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = std::to_string(usr); @@ -110,7 +111,7 @@ bool ExpandHelper(MessageHandler* m, } else { if (levels > 0) { for (auto usr : def->bases) { - if (seen.insert(usr).second) + if (!seen.insert(usr).second) continue; Out_CclsInheritanceHierarchy::Entry entry1; entry1.id = std::to_string(usr); @@ -180,17 +181,15 @@ struct Handler_CclsInheritanceHierarchy WorkingFile* wfile = working_files->GetFileByFilename(file->def->path); - for (SymbolRef sym : - FindSymbolsAtLocation(wfile, file, params.position)) { + for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { out.result = BuildInitial(sym, params.derived, params.qualified, params.levels); break; } - } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); diff --git a/src/messages/ccls_member_hierarchy.cc b/src/messages/ccls_member_hierarchy.cc index dd075c39..2ac6045d 100644 --- a/src/messages/ccls_member_hierarchy.cc +++ b/src/messages/ccls_member_hierarchy.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include @@ -264,7 +265,7 @@ struct Handler_CclsMemberHierarchy } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); diff --git a/src/messages/ccls_random.cc b/src/messages/ccls_random.cc index 3a32f6ef..382bba34 100644 --- a/src/messages/ccls_random.cc +++ b/src/messages/ccls_random.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include #include @@ -126,7 +127,7 @@ struct Handler_CclsRandom : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsRandom); diff --git a/src/messages/ccls_vars.cc b/src/messages/ccls_vars.cc index 90575b90..31e0c779 100644 --- a/src/messages/ccls_vars.cc +++ b/src/messages/ccls_vars.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "$ccls/vars"; @@ -48,7 +49,7 @@ struct Handler_CclsVars : BaseMessageHandler { break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_CclsVars); diff --git a/src/messages/initialize.cc b/src/messages/initialize.cc index d15ba2e2..7a00ca81 100644 --- a/src/messages/initialize.cc +++ b/src/messages/initialize.cc @@ -1,4 +1,3 @@ -#include "cache_manager.h" #include "diagnostics_engine.h" #include "filesystem.hh" #include "include_complete.h" @@ -7,10 +6,10 @@ #include "pipeline.hh" #include "platform.h" #include "project.h" -#include "queue_manager.h" #include "serializers/json.h" #include "timer.h" #include "working_files.h" +using namespace ccls; #include #include @@ -482,7 +481,7 @@ struct Handler_Initialize : BaseMessageHandler { Out_InitializeResponse out; out.id = request->id; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); // Set project root. EnsureEndsInSlash(project_path); @@ -515,7 +514,7 @@ struct Handler_Initialize : BaseMessageHandler { g_thread_id = i + 1; std::string name = "indexer" + std::to_string(i); set_thread_name(name.c_str()); - Indexer_Main(diag_engine, vfs, project, working_files, waiter); + pipeline::Indexer_Main(diag_engine, vfs, project, working_files); }).detach(); } @@ -524,7 +523,7 @@ struct Handler_Initialize : BaseMessageHandler { include_complete->Rescan(); time.Reset(); - project->Index(QueueManager::instance(), working_files, request->id); + project->Index(working_files, request->id); // We need to support multiple concurrent index processes. time.ResetAndPrint("[perf] Dispatched initial index requests"); } diff --git a/src/messages/shutdown.cc b/src/messages/shutdown.cc index e16721d4..e06c7281 100644 --- a/src/messages/shutdown.cc +++ b/src/messages/shutdown.cc @@ -1,5 +1,6 @@ #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "shutdown"; @@ -21,7 +22,7 @@ struct Handler_Shutdown : BaseMessageHandler { void Run(In_Shutdown* request) override { Out_Shutdown out; out.id = request->id; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_Shutdown); diff --git a/src/messages/text_document_code_lens.cc b/src/messages/text_document_code_lens.cc index 2ac395c9..a5b32fb6 100644 --- a/src/messages/text_document_code_lens.cc +++ b/src/messages/text_document_code_lens.cc @@ -2,7 +2,8 @@ #include "lsp_code_action.h" #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/codeLens"; @@ -225,7 +226,7 @@ struct Handler_TextDocumentCodeLens }; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeLens); diff --git a/src/messages/text_document_completion.cc b/src/messages/text_document_completion.cc index 1f536a40..39998655 100644 --- a/src/messages/text_document_completion.cc +++ b/src/messages/text_document_completion.cc @@ -2,9 +2,10 @@ #include "fuzzy_match.h" #include "include_complete.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "timer.h" #include "working_files.h" +using namespace ccls; #include "lex_utils.h" @@ -270,7 +271,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { auto write_empty_result = [request]() { Out_TextDocumentComplete out; out.id = request->id; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); }; std::string path = request->params.textDocument.uri.GetPath(); @@ -377,7 +378,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { item.textEdit->range.end.character = (int)buffer_line.size(); } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } else { ClangCompleteManager::OnComplete callback = std::bind( [this, request, is_global_completion, existing_completion, @@ -389,7 +390,7 @@ struct Handler_TextDocumentCompletion : MessageHandler { // Emit completion results. FilterAndSortCompletionResponse(&out, existing_completion, has_open_paren); - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); // Cache completion results. if (!is_cached_result) { diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index 1d7e545a..80aaf9a1 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -1,7 +1,8 @@ #include "lex_utils.h" #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include #include @@ -173,7 +174,7 @@ struct Handler_TextDocumentDefinition } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDefinition); diff --git a/src/messages/text_document_did_change.cc b/src/messages/text_document_did_change.cc index 8072cb95..54ce8b70 100644 --- a/src/messages/text_document_did_change.cc +++ b/src/messages/text_document_did_change.cc @@ -1,9 +1,9 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" #include "working_files.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didChange"; @@ -25,9 +25,7 @@ struct Handler_TextDocumentDidChange working_files->OnChange(request->params); if (g_config->index.onDidChange) { Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/), - true); + pipeline::Index(entry.filename, entry.args, true); } clang_complete->NotifyEdit(path); clang_complete->DiagnosticsUpdate( diff --git a/src/messages/text_document_did_close.cc b/src/messages/text_document_did_close.cc index 6cf1d3fb..e13382d7 100644 --- a/src/messages/text_document_did_close.cc +++ b/src/messages/text_document_did_close.cc @@ -1,7 +1,8 @@ #include "clang_complete.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "working_files.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didClose"; @@ -27,7 +28,7 @@ struct Handler_TextDocumentDidClose // Clear any diagnostics for the file. Out_TextDocumentPublishDiagnostics out; out.params.uri = request->params.textDocument.uri; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); // Remove internal state. working_files->OnClose(request->params.textDocument); diff --git a/src/messages/text_document_did_open.cc b/src/messages/text_document_did_open.cc index 12c79bdb..0f45b506 100644 --- a/src/messages/text_document_did_open.cc +++ b/src/messages/text_document_did_open.cc @@ -1,9 +1,9 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "include_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "timer.h" #include "working_files.h" @@ -38,11 +38,9 @@ struct Handler_TextDocumentDidOpen const auto& params = request->params; std::string path = params.textDocument.uri.GetPath(); - ICacheManager cache; WorkingFile* working_file = working_files->OnOpen(params.textDocument); - std::optional cached_file_contents = - cache.LoadCachedFileContents(path); - if (cached_file_contents) + if (std::optional cached_file_contents = + pipeline::LoadCachedFileContents(path)) working_file->SetIndexContent(*cached_file_contents); QueryFile* file = nullptr; @@ -60,11 +58,8 @@ struct Handler_TextDocumentDidOpen // Submit new index request if it is not a header file. if (SourceFileLanguage(path) != LanguageId::Unknown) { Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, - params.args.size() ? params.args : entry.args, - true /*is_interactive*/), - true /* priority */); + pipeline::Index(entry.filename, + params.args.size() ? params.args : entry.args, true); clang_complete->FlushSession(entry.filename); } diff --git a/src/messages/text_document_did_save.cc b/src/messages/text_document_did_save.cc index 50835f01..d3c77f06 100644 --- a/src/messages/text_document_did_save.cc +++ b/src/messages/text_document_did_save.cc @@ -1,8 +1,8 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/didSave"; @@ -29,7 +29,8 @@ struct Handler_TextDocumentDidSave MethodType GetMethodType() const override { return kMethodType; } void Run(In_TextDocumentDidSave* request) override { - std::string path = request->params.textDocument.uri.GetPath(); + const auto& params = request->params; + std::string path = params.textDocument.uri.GetPath(); // Send out an index request, and copy the current buffer state so we // can update the cached index contents when the index is done. @@ -47,9 +48,7 @@ struct Handler_TextDocumentDidSave // TODO: send as priority request if (!g_config->index.onDidChange) { Project::Entry entry = project->FindCompilationEntryForFile(path); - QueueManager::instance()->index_request.PushBack( - Index_Request(entry.filename, entry.args, true /*is_interactive*/), - true); + pipeline::Index(entry.filename, entry.args, true); } clang_complete->NotifySave(path); diff --git a/src/messages/text_document_document_highlight.cc b/src/messages/text_document_document_highlight.cc index 643ef859..f7cfc0f1 100644 --- a/src/messages/text_document_document_highlight.cc +++ b/src/messages/text_document_document_highlight.cc @@ -1,7 +1,8 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" #include "symbol.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/documentHighlight"; @@ -61,7 +62,7 @@ struct Handler_TextDocumentDocumentHighlight break; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight); diff --git a/src/messages/text_document_document_symbol.cc b/src/messages/text_document_document_symbol.cc index 29071eb7..959328e3 100644 --- a/src/messages/text_document_document_symbol.cc +++ b/src/messages/text_document_document_symbol.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/documentSymbol"; @@ -64,7 +65,7 @@ struct Handler_TextDocumentDocumentSymbol } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol); diff --git a/src/messages/text_document_hover.cc b/src/messages/text_document_hover.cc index eacd662b..f3f28218 100644 --- a/src/messages/text_document_hover.cc +++ b/src/messages/text_document_hover.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/hover"; @@ -99,7 +100,7 @@ struct Handler_TextDocumentHover : BaseMessageHandler { } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentHover); diff --git a/src/messages/text_document_implementation.cc b/src/messages/text_document_implementation.cc index 6bb5148f..8c10fbac 100644 --- a/src/messages/text_document_implementation.cc +++ b/src/messages/text_document_implementation.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/implementation"; @@ -41,7 +42,7 @@ struct Handler_TextDocumentImplementation break; } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentImplementation); diff --git a/src/messages/text_document_range_formatting.cc b/src/messages/text_document_range_formatting.cc index bc860f67..8ffe41f8 100644 --- a/src/messages/text_document_range_formatting.cc +++ b/src/messages/text_document_range_formatting.cc @@ -1,7 +1,8 @@ #include "clang_format.h" #include "lex_utils.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "working_files.h" #include @@ -64,7 +65,7 @@ struct Handler_TextDocumentRangeFormatting response.result = {}; #endif - QueueManager::WriteStdout(kMethodType, response); + pipeline::WriteStdout(kMethodType, response); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRangeFormatting); diff --git a/src/messages/text_document_references.cc b/src/messages/text_document_references.cc index dce6e5b7..d8d60f11 100644 --- a/src/messages/text_document_references.cc +++ b/src/messages/text_document_references.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include @@ -135,7 +136,7 @@ struct Handler_TextDocumentReferences if ((int)out.result.size() >= g_config->xref.maxNum) out.result.resize(g_config->xref.maxNum); - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentReferences); diff --git a/src/messages/text_document_rename.cc b/src/messages/text_document_rename.cc index a3301998..6e2844bb 100644 --- a/src/messages/text_document_rename.cc +++ b/src/messages/text_document_rename.cc @@ -1,6 +1,7 @@ #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/rename"; @@ -102,7 +103,7 @@ struct Handler_TextDocumentRename : BaseMessageHandler { break; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentRename); diff --git a/src/messages/text_document_signature_help.cc b/src/messages/text_document_signature_help.cc index c06050ea..608c4037 100644 --- a/src/messages/text_document_signature_help.cc +++ b/src/messages/text_document_signature_help.cc @@ -1,6 +1,7 @@ #include "clang_complete.h" #include "message_handler.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "timer.h" #include @@ -142,7 +143,7 @@ struct Handler_TextDocumentSignatureHelp : MessageHandler { out.result.activeParameter = active_param; Timer timer; - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); if (!is_cached_result) { signature_cache->WithLock([&]() { diff --git a/src/messages/text_document_type_definition.cc b/src/messages/text_document_type_definition.cc index 4a31cde2..98a54312 100644 --- a/src/messages/text_document_type_definition.cc +++ b/src/messages/text_document_type_definition.cc @@ -1,6 +1,7 @@ #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; namespace { MethodType kMethodType = "textDocument/typeDefinition"; @@ -60,7 +61,7 @@ struct Handler_TextDocumentTypeDefinition } } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_TextDocumentTypeDefinition); diff --git a/src/messages/workspace_did_change_configuration.cc b/src/messages/workspace_did_change_configuration.cc index ab33009b..73775d42 100644 --- a/src/messages/workspace_did_change_configuration.cc +++ b/src/messages/workspace_did_change_configuration.cc @@ -1,8 +1,8 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; #include "timer.h" #include "working_files.h" @@ -31,7 +31,7 @@ struct Handler_WorkspaceDidChangeConfiguration std::to_string(project->entries.size()) + " files)"); time.Reset(); - project->Index(QueueManager::instance(), working_files, lsRequestId()); + project->Index(working_files, lsRequestId()); time.ResetAndPrint( "[perf] Dispatched workspace/didChangeConfiguration index requests"); diff --git a/src/messages/workspace_did_change_watched_files.cc b/src/messages/workspace_did_change_watched_files.cc index 3140a929..f5e81363 100644 --- a/src/messages/workspace_did_change_watched_files.cc +++ b/src/messages/workspace_did_change_watched_files.cc @@ -1,9 +1,9 @@ -#include "cache_manager.h" #include "clang_complete.h" #include "message_handler.h" #include "project.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "working_files.h" +using namespace ccls; namespace { MethodType kMethodType = "workspace/didChangeWatchedFiles"; @@ -52,15 +52,13 @@ struct Handler_WorkspaceDidChangeWatchedFiles switch (event.type) { case lsFileChangeType::Created: case lsFileChangeType::Changed: { - QueueManager::instance()->index_request.PushBack( - Index_Request(path, entry.args, is_interactive)); + pipeline::Index(path, entry.args, is_interactive); if (is_interactive) clang_complete->NotifySave(path); break; } case lsFileChangeType::Deleted: - QueueManager::instance()->index_request.PushBack( - Index_Request(path, entry.args, is_interactive)); + pipeline::Index(path, entry.args, is_interactive); break; } } diff --git a/src/messages/workspace_execute_command.cc b/src/messages/workspace_execute_command.cc index 8c1327c1..c2d71c75 100644 --- a/src/messages/workspace_execute_command.cc +++ b/src/messages/workspace_execute_command.cc @@ -1,7 +1,8 @@ #include "lsp_code_action.h" #include "message_handler.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" +using namespace ccls; namespace { MethodType kMethodType = "workspace/executeCommand"; @@ -34,7 +35,7 @@ struct Handler_WorkspaceExecuteCommand out.result = params.arguments.locations; } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceExecuteCommand); diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 77df7fea..d9e88dca 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -1,8 +1,9 @@ #include "fuzzy_match.h" #include "lex_utils.h" #include "message_handler.h" +#include "pipeline.hh" #include "query_utils.h" -#include "queue_manager.h" +using namespace ccls; #include #include @@ -124,7 +125,7 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler { out.result.push_back(std::get<0>(entry)); } - QueueManager::WriteStdout(kMethodType, out); + pipeline::WriteStdout(kMethodType, out); } }; REGISTER_MESSAGE_HANDLER(Handler_WorkspaceSymbol); diff --git a/src/pipeline.cc b/src/pipeline.cc index b552448f..1b06cca7 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -1,6 +1,5 @@ #include "pipeline.hh" -#include "cache_manager.h" #include "clang_complete.h" #include "config.h" #include "diagnostics_engine.h" @@ -11,18 +10,43 @@ #include "platform.h" #include "project.h" #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "timer.h" #include #include using namespace llvm; -#include #include +struct Index_Request { + std::string path; + std::vector args; + bool is_interactive; + lsRequestId id; +}; + +struct Index_OnIndexed { + IndexUpdate update; + PerformanceImportFile perf; +}; + +struct Stdout_Request { + MethodType method; + std::string content; +}; + +namespace ccls::pipeline { namespace { +MultiQueueWaiter* main_waiter; +MultiQueueWaiter* indexer_waiter; +MultiQueueWaiter* stdout_waiter; +ThreadedQueue>* on_request; +ThreadedQueue* index_request; +ThreadedQueue* on_indexed; +ThreadedQueue* for_stdout; + // Checks if |path| needs to be reparsed. This will modify cached state // such that calling this function twice with the same path may return true // the first time but will return false the second. @@ -64,24 +88,57 @@ bool FileNeedsParse(int64_t write_time, return false; }; +std::string AppendSerializationFormat(const std::string& base) { + switch (g_config->cacheFormat) { + case SerializeFormat::Binary: + return base + ".blob"; + case SerializeFormat::Json: + return base + ".json"; + } +} + +std::string GetCachePath(const std::string& source_file) { + std::string cache_file; + size_t len = g_config->projectRoot.size(); + if (StartsWith(source_file, g_config->projectRoot)) { + cache_file = EscapeFileName(g_config->projectRoot) + + EscapeFileName(source_file.substr(len)); + } else { + cache_file = '@' + EscapeFileName(g_config->projectRoot) + + EscapeFileName(source_file); + } + + return g_config->cacheDirectory + cache_file; +} + +std::unique_ptr RawCacheLoad( + const std::string& path) { + std::string cache_path = GetCachePath(path); + std::optional file_content = ReadContent(cache_path); + std::optional serialized_indexed_content = + ReadContent(AppendSerializationFormat(cache_path)); + if (!file_content || !serialized_indexed_content) + return nullptr; + + return Deserialize(g_config->cacheFormat, path, *serialized_indexed_content, + *file_content, IndexFile::kMajorVersion); +} + bool Indexer_Parse(DiagnosticsEngine* diag_engine, WorkingFiles* working_files, Project* project, VFS* vfs, ClangIndexer* indexer) { - auto* queue = QueueManager::instance(); - std::optional opt_request = queue->index_request.TryPopFront(); + std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; auto& request = *opt_request; - ICacheManager cache; // Dummy one to trigger refresh semantic highlight. if (request.path.empty()) { IndexUpdate dummy; dummy.refresh = true; - queue->on_indexed.PushBack( - Index_OnIndexed(std::move(dummy), PerformanceImportFile()), false); + on_indexed->PushBack({std::move(dummy), PerformanceImportFile()}, false); return false; } @@ -108,7 +165,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, return true; int reparse; // request.is_interactive; - prev = cache.RawCacheLoad(path_to_index); + prev = RawCacheLoad(path_to_index); if (!prev) reparse = 2; else { @@ -132,15 +189,13 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, auto dependencies = prev->dependencies; if (reparse) { IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), - request.is_interactive); + on_indexed->PushBack({std::move(update), perf}, request.is_interactive); } for (const auto& dep : dependencies) if (vfs->Mark(dep.first().str(), 0, 2)) { - prev = cache.RawCacheLoad(dep.first().str()); + prev = RawCacheLoad(dep.first().str()); IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get()); - queue->on_indexed.PushBack(Index_OnIndexed(std::move(update), perf), - request.is_interactive); + on_indexed->PushBack({std::move(update), perf}, request.is_interactive); } std::lock_guard lock(vfs->mutex); @@ -152,7 +207,6 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, LOG_S(INFO) << "parse " << path_to_index; - std::vector result; PerformanceImportFile perf; auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}, &perf); @@ -162,7 +216,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, out.id = request.id; out.error.code = lsErrorCodes::InternalError; out.error.message = "Failed to index " + path_to_index; - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); } vfs->Reset(path_to_index); return true; @@ -179,12 +233,17 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, if (!(vfs->Stamp(path, curr->last_write_time) || path == path_to_index)) continue; LOG_S(INFO) << "emit index for " << path; - prev = cache.RawCacheLoad(path); + prev = RawCacheLoad(path); // Write current index to disk if requested. LOG_S(INFO) << "store index for " << path; Timer time; - cache.WriteToCache(*curr); + { + std::string cache_path = GetCachePath(path); + WriteToFile(cache_path, curr->file_contents); + WriteToFile(AppendSerializationFormat(cache_path), + Serialize(g_config->cacheFormat, *curr)); + } perf.index_save_to_disk = time.ElapsedMicrosecondsAndReset(); vfs->Reset(path_to_index); @@ -199,8 +258,7 @@ bool Indexer_Parse(DiagnosticsEngine* diag_engine, perf.index_make_delta = time.ElapsedMicrosecondsAndReset(); LOG_S(INFO) << "built index for " << path << " (is_delta=" << !!prev << ")"; - Index_OnIndexed reply(std::move(update), perf); - queue->on_indexed.PushBack(std::move(reply), request.is_interactive); + on_indexed->PushBack({std::move(update), perf}, request.is_interactive); } return true; @@ -217,26 +275,34 @@ bool ShouldDisplayMethodTiming(MethodType type) { } // namespace +void Init() { + main_waiter = new MultiQueueWaiter; + on_request = new ThreadedQueue>(main_waiter); + on_indexed = new ThreadedQueue(main_waiter); + + indexer_waiter = new MultiQueueWaiter; + index_request = new ThreadedQueue(indexer_waiter); + + stdout_waiter = new MultiQueueWaiter; + for_stdout = new ThreadedQueue(stdout_waiter); +} + void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, Project* project, - WorkingFiles* working_files, - MultiQueueWaiter* waiter) { - auto* queue = QueueManager::instance(); + WorkingFiles* working_files) { // Build one index per-indexer, as building the index acquires a global lock. ClangIndexer indexer; while (true) if (!Indexer_Parse(diag_engine, working_files, project, vfs, &indexer)) - waiter->Wait(&queue->index_request); + indexer_waiter->Wait(index_request); } -void QueryDb_OnIndexed(QueueManager* queue, - QueryDatabase* db, - SemanticHighlightSymbolCache* semantic_cache, - WorkingFiles* working_files, - Index_OnIndexed* response) { - +void Main_OnIndexed(QueryDatabase* db, + SemanticHighlightSymbolCache* semantic_cache, + WorkingFiles* working_files, + Index_OnIndexed* response) { if (response->update.refresh) { LOG_S(INFO) << "Loaded project. Refresh semantic highlight for all working file."; std::lock_guard lock(working_files->files_mutex); @@ -257,9 +323,8 @@ void QueryDb_OnIndexed(QueueManager* queue, if (response->update.files_def_update) { auto& update = *response->update.files_def_update; time.ResetAndPrint("apply index for " + update.value.path); - WorkingFile* working_file = - working_files->GetFileByFilename(update.value.path); - if (working_file) { + if (WorkingFile* working_file = + working_files->GetFileByFilename(update.value.path)) { // Update indexed content. working_file->SetIndexContent(update.file_content); @@ -275,10 +340,9 @@ void QueryDb_OnIndexed(QueueManager* queue, } } -void LaunchStdinLoop(std::unordered_map* request_times) { +void LaunchStdin(std::unordered_map* request_times) { std::thread([request_times]() { set_thread_name("stdin"); - auto* queue = QueueManager::instance(); while (true) { std::unique_ptr message; std::optional err = @@ -295,7 +359,7 @@ void LaunchStdinLoop(std::unordered_map* request_times) { out.id = id; out.error.code = lsErrorCodes::InvalidParams; out.error.message = std::move(*err); - queue->WriteStdout(kMethodType_Unknown, out); + WriteStdout(kMethodType_Unknown, out); } } continue; @@ -305,7 +369,7 @@ void LaunchStdinLoop(std::unordered_map* request_times) { MethodType method_type = message->GetMethodType(); (*request_times)[method_type] = Timer(); - queue->for_querydb.PushBack(std::move(message)); + on_request->PushBack(std::move(message)); // If the message was to exit then querydb will take care of the actual // exit. Stop reading from stdin since it might be detached. @@ -315,16 +379,14 @@ void LaunchStdinLoop(std::unordered_map* request_times) { }).detach(); } -void LaunchStdoutThread(std::unordered_map* request_times, - MultiQueueWaiter* waiter) { +void LaunchStdout(std::unordered_map* request_times) { std::thread([=]() { set_thread_name("stdout"); - auto* queue = QueueManager::instance(); while (true) { - std::vector messages = queue->for_stdout.DequeueAll(); + std::vector messages = for_stdout->DequeueAll(); if (messages.empty()) { - waiter->Wait(&queue->for_stdout); + stdout_waiter->Wait(for_stdout); continue; } @@ -341,8 +403,7 @@ void LaunchStdoutThread(std::unordered_map* request_times, }).detach(); } -void MainLoop(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter) { +void MainLoop() { Project project; SemanticHighlightSymbolCache semantic_cache; WorkingFiles working_files; @@ -362,7 +423,7 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, out.error.message = "Dropping completion request; a newer request " "has come in that will be serviced instead."; - QueueManager::WriteStdout(kMethodType_Unknown, out); + pipeline::WriteStdout(kMethodType_Unknown, out); } }); @@ -389,11 +450,8 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, handler->signature_cache = signature_cache.get(); } - // Run query db main loop. - auto* queue = QueueManager::instance(); while (true) { - std::vector> messages = - queue->for_querydb.DequeueAll(); + std::vector> messages = on_request->DequeueAll(); bool did_work = messages.size(); for (auto& message : messages) { // TODO: Consider using std::unordered_map to lookup the handler @@ -409,19 +467,40 @@ void MainLoop(MultiQueueWaiter* querydb_waiter, } for (int i = 80; i--;) { - std::optional response = queue->on_indexed.TryPopFront(); + std::optional response = on_indexed->TryPopFront(); if (!response) break; did_work = true; - QueryDb_OnIndexed(queue, &db, &semantic_cache, &working_files, &*response); + Main_OnIndexed(&db, &semantic_cache, &working_files, &*response); } // Cleanup and free any unused memory. FreeUnusedMemory(); - if (!did_work) { - auto* queue = QueueManager::instance(); - querydb_waiter->Wait(&queue->on_indexed, &queue->for_querydb); - } + if (!did_work) + main_waiter->Wait(on_indexed, on_request); } } + +void Index(const std::string& path, + const std::vector& args, + bool interactive, + lsRequestId id) { + index_request->PushBack({path, args, interactive, id}, interactive); +} + +std::optional LoadCachedFileContents(const std::string& path) { + return ReadContent(GetCachePath(path)); +} + +void WriteStdout(MethodType method, lsBaseOutMessage& response) { + std::ostringstream sstream; + response.Write(sstream); + + Stdout_Request out; + out.content = sstream.str(); + out.method = method; + for_stdout->PushBack(std::move(out)); +} + +} diff --git a/src/pipeline.hh b/src/pipeline.hh index 87076be9..760ac190 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -1,28 +1,35 @@ #pragma once -#include "queue_manager.h" +#include "method.h" +#include "query.h" #include "timer.h" -#include +#include #include +#include -struct ClangTranslationUnit; class DiagnosticsEngine; struct VFS; -struct ICacheManager; struct Project; -struct QueryDatabase; -struct SemanticHighlightSymbolCache; struct WorkingFiles; +struct lsBaseOutMessage; +namespace ccls::pipeline { + +void Init(); +void LaunchStdin(std::unordered_map* request_times); +void LaunchStdout(std::unordered_map* request_times); void Indexer_Main(DiagnosticsEngine* diag_engine, VFS* vfs, Project* project, - WorkingFiles* working_files, - MultiQueueWaiter* waiter); + WorkingFiles* working_files); +void MainLoop(); -void LaunchStdinLoop(std::unordered_map* request_times); -void LaunchStdoutThread(std::unordered_map* request_times, - MultiQueueWaiter* waiter); -void MainLoop(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter); +void Index(const std::string& path, + const std::vector& args, + bool is_interactive, + lsRequestId id = {}); + +std::optional LoadCachedFileContents(const std::string& path); +void WriteStdout(MethodType method, lsBaseOutMessage& response); +} diff --git a/src/port.cc b/src/port.cc deleted file mode 100644 index d48df06a..00000000 --- a/src/port.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "port.h" - -#include -#include - -void ccls_unreachable_internal(const char* msg, const char* file, int line) { - fprintf(stderr, "unreachable %s:%d %s\n", file, line, msg); - CCLS_BUILTIN_UNREACHABLE; - abort(); -} diff --git a/src/port.h b/src/port.h deleted file mode 100644 index da3da313..00000000 --- a/src/port.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#ifndef __has_builtin -#define __has_builtin(x) 0 -#endif - -#if defined(__GNUC__) -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#else -#define ATTRIBUTE_UNUSED -#endif - -#ifdef __clang__ -#define GUARDED_BY(x) __attribute__((guarded_by(x))) -#else -#define GUARDED_BY(x) -#endif - -// TODO GCC -#if __has_builtin(__builtin_unreachable) -#define CCLS_BUILTIN_UNREACHABLE __builtin_unreachable() -#elif defined(_MSC_VER) -#define CCLS_BUILTIN_UNREACHABLE __assume(false) -#else -#define CCLS_BUILTIN_UNREACHABLE -#endif - -void ccls_unreachable_internal(const char* msg, const char* file, int line); -#ifndef NDEBUG -#define CCLS_UNREACHABLE(msg) \ - ccls_unreachable_internal(msg, __FILE__, __LINE__) -#else -#define CCLS_UNREACHABLE(msg) -#endif diff --git a/src/project.cc b/src/project.cc index 44682d98..90abbb8e 100644 --- a/src/project.cc +++ b/src/project.cc @@ -1,17 +1,17 @@ #include "project.h" -#include "cache_manager.h" #include "clang_utils.h" #include "filesystem.hh" #include "language.h" #include "log.hh" #include "match.h" #include "platform.h" -#include "queue_manager.h" +#include "pipeline.hh" #include "serializers/json.h" #include "timer.h" #include "utils.h" #include "working_files.h" +using namespace ccls; #include #include @@ -454,17 +454,15 @@ void Project::ForAllFilteredFiles( } } -void Project::Index(QueueManager* queue, - WorkingFiles* wfiles, +void Project::Index(WorkingFiles* wfiles, lsRequestId id) { ForAllFilteredFiles([&](int i, const Project::Entry& entry) { bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; - queue->index_request.PushBack( - Index_Request(entry.filename, entry.args, is_interactive, id)); + pipeline::Index(entry.filename, entry.args, is_interactive, id); }); // Dummy request to indicate that project is loaded and // trigger refreshing semantic highlight for all working files. - queue->index_request.PushBack(Index_Request("", {}, false)); + pipeline::Index("", {}, false); } TEST_SUITE("Project") { diff --git a/src/project.h b/src/project.h index 4b5220b9..d6d3f396 100644 --- a/src/project.h +++ b/src/project.h @@ -5,12 +5,10 @@ #include #include -#include #include #include #include -class QueueManager; struct WorkingFiles; struct Project { @@ -29,7 +27,7 @@ struct Project { std::vector entries; std::mutex mutex_; - std::unordered_map absolute_path_to_entry_index_ GUARDED_BY(mutex_); + std::unordered_map absolute_path_to_entry_index_; // Loads a project for the given |directory|. // @@ -58,5 +56,5 @@ struct Project { void ForAllFilteredFiles( std::function action); - void Index(QueueManager* queue, WorkingFiles* wfiles, lsRequestId id); + void Index(WorkingFiles* wfiles, lsRequestId id); }; diff --git a/src/query_utils.cc b/src/query_utils.cc index 9f801ced..04031ded 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -1,6 +1,6 @@ #include "query_utils.h" -#include "queue_manager.h" +#include "pipeline.hh" #include #include diff --git a/src/queue_manager.cc b/src/queue_manager.cc deleted file mode 100644 index 623c72df..00000000 --- a/src/queue_manager.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "queue_manager.h" - -#include "cache_manager.h" -#include "lsp.h" -#include "query.h" - -#include - -Index_Request::Index_Request(const std::string& path, - const std::vector& args, - bool is_interactive, - lsRequestId id) - : path(path), args(args), is_interactive(is_interactive), id(id) {} - -Index_OnIndexed::Index_OnIndexed(IndexUpdate&& update, - PerformanceImportFile perf) - : update(std::move(update)), perf(perf) {} - -std::unique_ptr QueueManager::instance_; - -// static -void QueueManager::Init(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter) { - instance_ = std::unique_ptr( - new QueueManager(querydb_waiter, indexer_waiter, stdout_waiter)); -} - -// static -void QueueManager::WriteStdout(MethodType method, lsBaseOutMessage& response) { - std::ostringstream sstream; - response.Write(sstream); - - Stdout_Request out; - out.content = sstream.str(); - out.method = method; - instance()->for_stdout.PushBack(std::move(out)); -} - -QueueManager::QueueManager(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter) - : for_stdout(stdout_waiter), - for_querydb(querydb_waiter), - on_indexed(querydb_waiter), - index_request(indexer_waiter) {} diff --git a/src/queue_manager.h b/src/queue_manager.h deleted file mode 100644 index 13ee57b4..00000000 --- a/src/queue_manager.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "method.h" -#include "query.h" -#include "threaded_queue.h" - -#include - -struct ICacheManager; -struct lsBaseOutMessage; - -struct Stdout_Request { - MethodType method; - std::string content; -}; - -struct Index_Request { - std::string path; - // TODO: make |args| a string that is parsed lazily. - std::vector args; - bool is_interactive; - lsRequestId id; - - Index_Request(const std::string& path, - const std::vector& args, - bool is_interactive, - lsRequestId id = {}); -}; - -struct Index_OnIdMapped { - std::shared_ptr cache_manager; - std::unique_ptr previous; - std::unique_ptr current; - - PerformanceImportFile perf; - bool is_interactive; - bool write_to_disk; - - Index_OnIdMapped(const std::shared_ptr& cache_manager, - std::unique_ptr previous, - std::unique_ptr current, - PerformanceImportFile perf, - bool is_interactive, - bool write_to_disk) - : cache_manager(cache_manager), - previous(std::move(previous)), - current(std::move(current)), - perf(perf), - is_interactive(is_interactive), - write_to_disk(write_to_disk) {} -}; - -struct Index_OnIndexed { - IndexUpdate update; - PerformanceImportFile perf; - - Index_OnIndexed(IndexUpdate&& update, PerformanceImportFile perf); -}; - -class QueueManager { - static std::unique_ptr instance_; - - public: - static QueueManager* instance() { return instance_.get(); } - static void Init(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter); - static void WriteStdout(MethodType method, lsBaseOutMessage& response); - - // Messages received by "stdout" thread. - ThreadedQueue for_stdout; - - // Runs on querydb thread. - ThreadedQueue> for_querydb; - ThreadedQueue on_indexed; - - // Runs on indexer threads. - ThreadedQueue index_request; - - private: - explicit QueueManager(MultiQueueWaiter* querydb_waiter, - MultiQueueWaiter* indexer_waiter, - MultiQueueWaiter* stdout_waiter); -}; diff --git a/src/serializer.h b/src/serializer.h index cc296c79..28f28481 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -2,7 +2,8 @@ #include "maybe.h" #include "nt_string.h" -#include "port.h" + +#include #include @@ -83,15 +84,15 @@ struct IndexFile; #define MAKE_REFLECT_TYPE_PROXY(type_name) \ MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t) -#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ - ATTRIBUTE_UNUSED inline void Reflect(Reader& visitor, type& value) { \ - as_type value0; \ - ::Reflect(visitor, value0); \ - value = static_cast(value0); \ - } \ - ATTRIBUTE_UNUSED inline void Reflect(Writer& visitor, type& value) { \ - auto value0 = static_cast(value); \ - ::Reflect(visitor, value0); \ +#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader& visitor, type& value) { \ + as_type value0; \ + ::Reflect(visitor, value0); \ + value = static_cast(value0); \ + } \ + LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer& visitor, type& value) { \ + auto value0 = static_cast(value); \ + ::Reflect(visitor, value0); \ } #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); diff --git a/src/test.cc b/src/test.cc index 00dec826..e9b5d8b3 100644 --- a/src/test.cc +++ b/src/test.cc @@ -284,8 +284,6 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { &all_expected_output); // Build flags. - if (!AnyStartsWith(flags, "-x")) - flags.push_back("-xc++"); flags.push_back("-resource-dir=" + GetDefaultResourceDirectory()); flags.push_back(path); diff --git a/src/threaded_queue.h b/src/threaded_queue.h index 93f1ccf1..6e3bc9d7 100644 --- a/src/threaded_queue.h +++ b/src/threaded_queue.h @@ -94,26 +94,6 @@ struct ThreadedQueue : public BaseThreadQueue { Push<&std::deque::push_back>(std::move(t), priority); } - // Add a set of elements to the queue. - void EnqueueAll(std::vector&& elements, bool priority = false) { - if (elements.empty()) - return; - - std::lock_guard lock(mutex_); - - total_count_ += elements.size(); - - for (T& element : elements) { - if (priority) - priority_.push_back(std::move(element)); - else - queue_.push_back(std::move(element)); - } - elements.clear(); - - waiter_->cv.notify_all(); - } - // Return all elements in the queue. std::vector DequeueAll() { std::lock_guard lock(mutex_); diff --git a/src/utils.cc b/src/utils.cc index cc448476..68de5189 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -48,15 +48,6 @@ bool StartsWith(std::string_view s, std::string_view prefix) { std::equal(prefix.begin(), prefix.end(), s.begin()); } -bool AnyStartsWith(const std::vector& xs, - std::string_view prefix) { - return std::any_of(xs.begin(), xs.end(), std::bind(StartsWith, _1, prefix)); -} - -bool StartsWithAny(std::string_view s, const std::vector& ps) { - return std::any_of(ps.begin(), ps.end(), std::bind(StartsWith, s, _1)); -} - bool EndsWithAny(std::string_view s, const std::vector& ss) { return std::any_of(ss.begin(), ss.end(), std::bind(EndsWith, s, _1)); } diff --git a/src/utils.h b/src/utils.h index 4258ae49..b1febec3 100644 --- a/src/utils.h +++ b/src/utils.h @@ -17,8 +17,6 @@ uint64_t HashUsr(std::string_view s); // Returns true if |value| starts/ends with |start| or |ending|. bool StartsWith(std::string_view value, std::string_view start); bool EndsWith(std::string_view value, std::string_view ending); -bool AnyStartsWith(const std::vector& xs, std::string_view prefix); -bool StartsWithAny(std::string_view s, const std::vector& ps); bool EndsWithAny(std::string_view s, const std::vector& ss); bool FindAnyPartial(const std::string& value, const std::vector& values);