diff --git a/src/command_line.cc b/src/command_line.cc index 25b433d0..d9fdd1b6 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -126,7 +126,7 @@ bool FindFileOrFail(QueryDatabase* db, out.id = *id; out.error.code = lsErrorCodes::InternalError; out.error.message = "Unable to find file " + absolute_path; - IpcManager::instance()->SendOutMessageToClient(IpcId::Cout, out); + IpcManager::WriteStdout(IpcId::Cout, out); } return false; @@ -141,8 +141,7 @@ void EmitInactiveLines(WorkingFile* working_file, if (ls_skipped) out.params.inactiveRegions.push_back(*ls_skipped); } - IpcManager::instance()->SendOutMessageToClient( - IpcId::CqueryPublishInactiveRegions, out); + IpcManager::WriteStdout(IpcId::CqueryPublishInactiveRegions, out); } // Caches symbols for a single file for semantic highlighting to provide @@ -276,8 +275,7 @@ void EmitSemanticHighlighting(QueryDatabase* db, out.params.uri = lsDocumentUri::FromPath(working_file->filename); for (auto& entry : grouped_symbols) out.params.symbols.push_back(entry.second); - IpcManager::instance()->SendOutMessageToClient( - IpcId::CqueryPublishSemanticHighlighting, out); + IpcManager::WriteStdout(IpcId::CqueryPublishSemanticHighlighting, out); } optional FindIncludeLine(const std::vector& lines, @@ -522,11 +520,10 @@ void EmitDiagnostics(WorkingFiles* working_files, std::string path, NonElidedVector diagnostics) { // Emit diagnostics. - Out_TextDocumentPublishDiagnostics diagnostic_response; - diagnostic_response.params.uri = lsDocumentUri::FromPath(path); - diagnostic_response.params.diagnostics = diagnostics; - IpcManager::instance()->SendOutMessageToClient( - IpcId::TextDocumentPublishDiagnostics, diagnostic_response); + Out_TextDocumentPublishDiagnostics out; + out.params.uri = lsDocumentUri::FromPath(path); + out.params.diagnostics = diagnostics; + IpcManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out); // Cache diagnostics so we can show fixits. working_files->DoActionOnFile(path, [&](WorkingFile* working_file) { @@ -879,7 +876,7 @@ void EmitProgress(Config* config, QueueManager* queue) { out.params.onIdMappedCount = queue->on_id_mapped.Size(); out.params.onIndexedCount = queue->on_indexed.Size(); - IpcManager::instance()->SendOutMessageToClient(IpcId::Cout, out); + IpcManager::WriteStdout(IpcId::Cout, out); } } @@ -1486,7 +1483,7 @@ bool QueryDbMainLoop(Config* config, bool did_work = false; std::vector> messages = - ipc->GetMessages(IpcManager::Destination::Server); + ipc->for_querydb.DequeueAll(); for (auto& message : messages) { did_work = true; @@ -1560,67 +1557,63 @@ bool QueryDbMainLoop(Config* config, // TODO: query request->params.capabilities.textDocument and support // only things the client supports. - auto response = Out_InitializeResponse(); - response.id = request->id; + Out_InitializeResponse out; + out.id = request->id; - // response.result.capabilities.textDocumentSync = + // out.result.capabilities.textDocumentSync = // lsTextDocumentSyncOptions(); - // response.result.capabilities.textDocumentSync->openClose = true; - // response.result.capabilities.textDocumentSync->change = + // out.result.capabilities.textDocumentSync->openClose = true; + // out.result.capabilities.textDocumentSync->change = // lsTextDocumentSyncKind::Full; - // response.result.capabilities.textDocumentSync->willSave = true; - // response.result.capabilities.textDocumentSync->willSaveWaitUntil = + // out.result.capabilities.textDocumentSync->willSave = true; + // out.result.capabilities.textDocumentSync->willSaveWaitUntil = // true; - response.result.capabilities.textDocumentSync = + out.result.capabilities.textDocumentSync = lsTextDocumentSyncKind::Incremental; - response.result.capabilities.renameProvider = true; + out.result.capabilities.renameProvider = true; - response.result.capabilities.completionProvider = - lsCompletionOptions(); - response.result.capabilities.completionProvider->resolveProvider = - false; + out.result.capabilities.completionProvider = lsCompletionOptions(); + out.result.capabilities.completionProvider->resolveProvider = false; // vscode doesn't support trigger character sequences, so we use ':' // for // '::' and '>' for '->'. See // https://github.com/Microsoft/language-server-protocol/issues/138. - response.result.capabilities.completionProvider->triggerCharacters = { + out.result.capabilities.completionProvider->triggerCharacters = { ".", ":", ">", "#"}; - response.result.capabilities.signatureHelpProvider = + out.result.capabilities.signatureHelpProvider = lsSignatureHelpOptions(); // NOTE: If updating signature help tokens make sure to also update // WorkingFile::FindClosestCallNameInBuffer. - response.result.capabilities.signatureHelpProvider - ->triggerCharacters = {"(", ","}; + out.result.capabilities.signatureHelpProvider->triggerCharacters = { + "(", ","}; - response.result.capabilities.codeLensProvider = lsCodeLensOptions(); - response.result.capabilities.codeLensProvider->resolveProvider = - false; + out.result.capabilities.codeLensProvider = lsCodeLensOptions(); + out.result.capabilities.codeLensProvider->resolveProvider = false; - response.result.capabilities.definitionProvider = true; - response.result.capabilities.documentHighlightProvider = true; - response.result.capabilities.hoverProvider = true; - response.result.capabilities.referencesProvider = true; + out.result.capabilities.definitionProvider = true; + out.result.capabilities.documentHighlightProvider = true; + out.result.capabilities.hoverProvider = true; + out.result.capabilities.referencesProvider = true; - response.result.capabilities.codeActionProvider = true; + out.result.capabilities.codeActionProvider = true; - response.result.capabilities.documentSymbolProvider = true; - response.result.capabilities.workspaceSymbolProvider = true; + out.result.capabilities.documentSymbolProvider = true; + out.result.capabilities.workspaceSymbolProvider = true; - response.result.capabilities.documentLinkProvider = + out.result.capabilities.documentLinkProvider = lsDocumentLinkOptions(); - response.result.capabilities.documentLinkProvider->resolveProvider = - false; + out.result.capabilities.documentLinkProvider->resolveProvider = false; - ipc->SendOutMessageToClient(IpcId::Initialize, response); + IpcManager::WriteStdout(IpcId::Initialize, out); // Set project root. config->projectRoot = NormalizePath(request->params.rootUri->GetPath()); EnsureEndsInSlash(config->projectRoot); - MakeDirectoryRecursive( - config->cacheDirectory + EscapeFileName(config->projectRoot)); + MakeDirectoryRecursive(config->cacheDirectory + + EscapeFileName(config->projectRoot)); // Start indexer threads. if (config->indexerCount == 0) { @@ -1725,24 +1718,24 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_CqueryTypeHierarchyTree response; - response.id = msg->id; + Out_CqueryTypeHierarchyTree out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Type) { - response.result = BuildInheritanceHierarchyForType( + out.result = BuildInheritanceHierarchyForType( db, working_files, QueryTypeId(ref.idx.idx)); break; } if (ref.idx.kind == SymbolKind::Func) { - response.result = BuildInheritanceHierarchyForFunc( + out.result = BuildInheritanceHierarchyForFunc( db, working_files, QueryFuncId(ref.idx.idx)); break; } } - ipc->SendOutMessageToClient(IpcId::CqueryTypeHierarchyTree, response); + IpcManager::WriteStdout(IpcId::CqueryTypeHierarchyTree, out); break; } @@ -1757,34 +1750,33 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_CqueryCallTree response; - response.id = msg->id; + Out_CqueryCallTree out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Func) { - response.result = BuildInitialCallTree(db, working_files, - QueryFuncId(ref.idx.idx)); + out.result = BuildInitialCallTree(db, working_files, + QueryFuncId(ref.idx.idx)); break; } } - ipc->SendOutMessageToClient(IpcId::CqueryCallTreeInitial, response); + IpcManager::WriteStdout(IpcId::CqueryCallTreeInitial, out); break; } case IpcId::CqueryCallTreeExpand: { auto msg = message->As(); - Out_CqueryCallTree response; - response.id = msg->id; + Out_CqueryCallTree out; + out.id = msg->id; auto func_id = db->usr_to_func.find(msg->params.usr); if (func_id != db->usr_to_func.end()) - response.result = - BuildExpandCallTree(db, working_files, func_id->second); + out.result = BuildExpandCallTree(db, working_files, func_id->second); - ipc->SendOutMessageToClient(IpcId::CqueryCallTreeExpand, response); + IpcManager::WriteStdout(IpcId::CqueryCallTreeExpand, out); break; } @@ -1799,18 +1791,18 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_LocationList response; - response.id = msg->id; + Out_LocationList out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Type) { QueryType& type = db->types[ref.idx.idx]; std::vector locations = ToQueryLocation(db, type.instances); - response.result = GetLsLocations(db, working_files, locations); + out.result = GetLsLocations(db, working_files, locations); } } - ipc->SendOutMessageToClient(IpcId::CqueryVars, response); + IpcManager::WriteStdout(IpcId::CqueryVars, out); break; } @@ -1825,8 +1817,8 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_LocationList response; - response.id = msg->id; + Out_LocationList out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Func) { @@ -1840,10 +1832,10 @@ bool QueryDbMainLoop(Config* config, GetCallersForAllDerivedFunctions(db, func)) locations.push_back(func_ref.loc); - response.result = GetLsLocations(db, working_files, locations); + out.result = GetLsLocations(db, working_files, locations); } } - ipc->SendOutMessageToClient(IpcId::CqueryCallers, response); + IpcManager::WriteStdout(IpcId::CqueryCallers, out); break; } @@ -1858,8 +1850,8 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_LocationList response; - response.id = msg->id; + Out_LocationList out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Type) { @@ -1868,7 +1860,7 @@ bool QueryDbMainLoop(Config* config, continue; std::vector locations = ToQueryLocation(db, type.def->parents); - response.result = GetLsLocations(db, working_files, locations); + out.result = GetLsLocations(db, working_files, locations); } else if (ref.idx.kind == SymbolKind::Func) { QueryFunc& func = db->funcs[ref.idx.idx]; optional location = @@ -1879,10 +1871,10 @@ bool QueryDbMainLoop(Config* config, GetLsLocation(db, working_files, *location); if (!ls_loc) continue; - response.result.push_back(*ls_loc); + out.result.push_back(*ls_loc); } } - ipc->SendOutMessageToClient(IpcId::CqueryBase, response); + IpcManager::WriteStdout(IpcId::CqueryBase, out); break; } @@ -1897,23 +1889,23 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_LocationList response; - response.id = msg->id; + Out_LocationList out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { if (ref.idx.kind == SymbolKind::Type) { QueryType& type = db->types[ref.idx.idx]; std::vector locations = ToQueryLocation(db, type.derived); - response.result = GetLsLocations(db, working_files, locations); + out.result = GetLsLocations(db, working_files, locations); } else if (ref.idx.kind == SymbolKind::Func) { QueryFunc& func = db->funcs[ref.idx.idx]; std::vector locations = ToQueryLocation(db, func.derived); - response.result = GetLsLocations(db, working_files, locations); + out.result = GetLsLocations(db, working_files, locations); } } - ipc->SendOutMessageToClient(IpcId::CqueryDerived, response); + IpcManager::WriteStdout(IpcId::CqueryDerived, out); break; } @@ -1989,10 +1981,9 @@ bool QueryDbMainLoop(Config* config, std::string path = msg->params.textDocument.uri.GetPath(); // Clear any diagnostics for the file. - Out_TextDocumentPublishDiagnostics diag; - diag.params.uri = msg->params.textDocument.uri; - IpcManager::instance()->SendOutMessageToClient( - IpcId::TextDocumentPublishDiagnostics, diag); + Out_TextDocumentPublishDiagnostics out; + out.params.uri = msg->params.textDocument.uri; + IpcManager::WriteStdout(IpcId::TextDocumentPublishDiagnostics, out); // Remove internal state. working_files->OnClose(msg->params); @@ -2039,19 +2030,19 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentRename response; - response.id = msg->id; + Out_TextDocumentRename out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { // Found symbol. Return references to rename. std::vector uses = GetUsesOfSymbol(db, ref.idx); - response.result = + out.result = BuildWorkspaceEdit(db, working_files, uses, msg->params.newName); break; } - ipc->SendOutMessageToClient(IpcId::TextDocumentRename, response); + IpcManager::WriteStdout(IpcId::TextDocumentRename, out); break; } @@ -2070,22 +2061,21 @@ bool QueryDbMainLoop(Config* config, buffer_line = file->all_buffer_lines[msg->params.position.line]; if (ShouldRunIncludeCompletion(buffer_line)) { - Out_TextDocumentComplete complete_response; - complete_response.id = msg->id; + Out_TextDocumentComplete out; + out.id = msg->id; { std::unique_lock lock( include_complete->completion_items_mutex, std::defer_lock); if (include_complete->is_scanning) lock.lock(); - complete_response.result.items.assign( - include_complete->completion_items.begin(), - include_complete->completion_items.end()); + out.result.items.assign(include_complete->completion_items.begin(), + include_complete->completion_items.end()); if (lock) lock.unlock(); // Update textEdit params. - for (lsCompletionItem& item : complete_response.result.items) { + for (lsCompletionItem& item : out.result.items) { item.textEdit->range.start.line = msg->params.position.line; item.textEdit->range.start.character = 0; item.textEdit->range.end.line = msg->params.position.line; @@ -2093,9 +2083,8 @@ bool QueryDbMainLoop(Config* config, } } - FilterCompletionResponse(&complete_response, buffer_line); - ipc->SendOutMessageToClient(IpcId::TextDocumentCompletion, - complete_response); + FilterCompletionResponse(&out, buffer_line); + IpcManager::WriteStdout(IpcId::TextDocumentCompletion, out); } else { bool is_global_completion = false; std::string existing_completion; @@ -2110,15 +2099,13 @@ bool QueryDbMainLoop(Config* config, is_global_completion, existing_completion, msg](const NonElidedVector& results, bool is_cached_result) { - Out_TextDocumentComplete complete_response; - complete_response.id = msg->id; - complete_response.result.items = results; + Out_TextDocumentComplete out; + out.id = msg->id; + out.result.items = results; // Emit completion results. - FilterCompletionResponse(&complete_response, - existing_completion); - IpcManager::instance()->SendOutMessageToClient( - IpcId::TextDocumentCompletion, complete_response); + FilterCompletionResponse(&out, existing_completion); + IpcManager::WriteStdout(IpcId::TextDocumentCompletion, out); // Cache completion results. if (!is_cached_result) { @@ -2203,8 +2190,8 @@ bool QueryDbMainLoop(Config* config, auto msg = message->As(); auto ipc = IpcManager::instance(); - Out_TextDocumentSignatureHelp response; - response.id = msg->id; + Out_TextDocumentSignatureHelp out; + out.id = msg->id; for (auto& result : results) { if (result.label != search) @@ -2217,25 +2204,24 @@ bool QueryDbMainLoop(Config* config, ls_param.label = parameter; signature.parameters.push_back(ls_param); } - response.result.signatures.push_back(signature); + out.result.signatures.push_back(signature); } // Guess the signature the user wants based on available parameter // count. - response.result.activeSignature = 0; - for (size_t i = 0; i < response.result.signatures.size(); ++i) { - if (active_param < response.result.signatures.size()) { - response.result.activeSignature = (int)i; + out.result.activeSignature = 0; + for (size_t i = 0; i < out.result.signatures.size(); ++i) { + if (active_param < out.result.signatures.size()) { + out.result.activeSignature = (int)i; break; } } // Set signature to what we parsed from the working file. - response.result.activeParameter = active_param; + out.result.activeParameter = active_param; Timer timer; - ipc->SendOutMessageToClient(IpcId::TextDocumentSignatureHelp, - response); + IpcManager::WriteStdout(IpcId::TextDocumentSignatureHelp, out); if (!is_cached_result) { signature_cache->WithLock([&]() { @@ -2276,8 +2262,8 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentDefinition response; - response.id = msg->id; + Out_TextDocumentDefinition out; + out.id = msg->id; int target_line = msg->params.position.line + 1; int target_column = msg->params.position.character + 1; @@ -2317,36 +2303,35 @@ bool QueryDbMainLoop(Config* config, optional ls_declaration = GetLsLocation(db, working_files, declaration); if (ls_declaration) - response.result.push_back(*ls_declaration); + out.result.push_back(*ls_declaration); } // We found some declarations. Break so we don't add the definition // location. - if (!response.result.empty()) + if (!out.result.empty()) break; } if (def_loc) { - PushBack(&response.result, - GetLsLocation(db, working_files, *def_loc)); + PushBack(&out.result, GetLsLocation(db, working_files, *def_loc)); } - if (!response.result.empty()) + if (!out.result.empty()) break; } // No symbols - check for includes. - if (response.result.empty()) { + if (out.result.empty()) { for (const IndexInclude& include : file->def->includes) { if (include.line == target_line) { lsLocation result; result.uri = lsDocumentUri::FromPath(include.resolved_path); - response.result.push_back(result); + out.result.push_back(result); break; } } } - ipc->SendOutMessageToClient(IpcId::TextDocumentDefinition, response); + IpcManager::WriteStdout(IpcId::TextDocumentDefinition, out); break; } @@ -2362,14 +2347,14 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentDocumentHighlight response; - response.id = msg->id; + Out_TextDocumentDocumentHighlight out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { // Found symbol. Return references to highlight. std::vector uses = GetUsesOfSymbol(db, ref.idx); - response.result.reserve(uses.size()); + out.result.reserve(uses.size()); for (const QueryLocation& use : uses) { if (use.path != file_id) continue; @@ -2382,13 +2367,12 @@ bool QueryDbMainLoop(Config* config, lsDocumentHighlight highlight; highlight.kind = lsDocumentHighlightKind::Text; highlight.range = ls_location->range; - response.result.push_back(highlight); + out.result.push_back(highlight); } break; } - ipc->SendOutMessageToClient(IpcId::TextDocumentDocumentHighlight, - response); + IpcManager::WriteStdout(IpcId::TextDocumentDocumentHighlight, out); break; } @@ -2403,8 +2387,8 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentHover response; - response.id = msg->id; + Out_TextDocumentHover out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { @@ -2414,14 +2398,14 @@ bool QueryDbMainLoop(Config* config, if (!ls_range) continue; - response.result.contents.value = GetHoverForSymbol(db, ref.idx); - response.result.contents.language = file->def->language; + out.result.contents.value = GetHoverForSymbol(db, ref.idx); + out.result.contents.language = file->def->language; - response.result.range = *ls_range; + out.result.range = *ls_range; break; } - ipc->SendOutMessageToClient(IpcId::TextDocumentHover, response); + IpcManager::WriteStdout(IpcId::TextDocumentHover, out); break; } @@ -2436,8 +2420,8 @@ bool QueryDbMainLoop(Config* config, WorkingFile* working_file = working_files->GetFileByFilename(file->def->path); - Out_TextDocumentReferences response; - response.id = msg->id; + Out_TextDocumentReferences out; + out.id = msg->id; for (const SymbolRef& ref : FindSymbolsAtLocation(working_file, file, msg->params.position)) { @@ -2449,7 +2433,7 @@ bool QueryDbMainLoop(Config* config, // Found symbol. Return references. std::vector uses = GetUsesOfSymbol(db, ref.idx); - response.result.reserve(uses.size()); + out.result.reserve(uses.size()); for (const QueryLocation& use : uses) { if (excluded_declaration.has_value() && use == *excluded_declaration) @@ -2458,20 +2442,20 @@ bool QueryDbMainLoop(Config* config, optional ls_location = GetLsLocation(db, working_files, use); if (ls_location) - response.result.push_back(*ls_location); + out.result.push_back(*ls_location); } break; } - ipc->SendOutMessageToClient(IpcId::TextDocumentReferences, response); + IpcManager::WriteStdout(IpcId::TextDocumentReferences, out); break; } case IpcId::TextDocumentDocumentSymbol: { auto msg = message->As(); - Out_TextDocumentDocumentSymbol response; - response.id = msg->id; + Out_TextDocumentDocumentSymbol out; + out.id = msg->id; QueryFile* file; if (!FindFileOrFail(db, msg->id, msg->params.textDocument.uri.GetPath(), @@ -2489,19 +2473,18 @@ bool QueryDbMainLoop(Config* config, if (!location) continue; info->location = *location; - response.result.push_back(*info); + out.result.push_back(*info); } - ipc->SendOutMessageToClient(IpcId::TextDocumentDocumentSymbol, - response); + IpcManager::WriteStdout(IpcId::TextDocumentDocumentSymbol, out); break; } case IpcId::TextDocumentDocumentLink: { auto msg = message->As(); - Out_TextDocumentDocumentLink response; - response.id = msg->id; + Out_TextDocumentDocumentLink out; + out.id = msg->id; if (config->showDocumentLinksOnIncludes) { QueryFile* file; @@ -2534,11 +2517,11 @@ bool QueryDbMainLoop(Config* config, lsDocumentLink link; link.target = lsDocumentUri::FromPath(include.resolved_path); link.range = *between_quotes; - response.result.push_back(link); + out.result.push_back(link); } } - ipc->SendOutMessageToClient(IpcId::TextDocumentDocumentLink, response); + IpcManager::WriteStdout(IpcId::TextDocumentDocumentLink, out); break; } @@ -2570,8 +2553,8 @@ bool QueryDbMainLoop(Config* config, break; } - Out_TextDocumentCodeAction response; - response.id = msg->id; + Out_TextDocumentCodeAction out; + out.id = msg->id; // TODO: auto-insert namespace? @@ -2637,7 +2620,7 @@ bool QueryDbMainLoop(Config* config, command.title = "Auto-Implement " + std::to_string(num_edits) + " methods on " + type.def->short_name; command.command = "cquery._autoImplement"; - response.result.push_back(command); + out.result.push_back(command); break; } @@ -2665,7 +2648,7 @@ bool QueryDbMainLoop(Config* config, if (edit->range.start.line >= default_line) edit->newText.insert(0, "\n"); command.arguments.edits.push_back(*edit); - response.result.push_back(command); + out.result.push_back(command); break; } default: @@ -2673,7 +2656,7 @@ bool QueryDbMainLoop(Config* config, } // Only show one auto-impl section. - if (!response.result.empty()) + if (!out.result.empty()) break; } @@ -2762,7 +2745,7 @@ bool QueryDbMainLoop(Config* config, " includes to insert"; command.command = "cquery._insertInclude"; command.arguments.textDocumentUri = msg->params.textDocument.uri; - response.result.push_back(command); + out.result.push_back(command); } } @@ -2775,19 +2758,19 @@ bool QueryDbMainLoop(Config* config, command.command = "cquery._applyFixIt"; command.arguments.textDocumentUri = msg->params.textDocument.uri; command.arguments.edits = diag.fixits_; - response.result.push_back(command); + out.result.push_back(command); } } - ipc->SendOutMessageToClient(IpcId::TextDocumentCodeAction, response); + IpcManager::WriteStdout(IpcId::TextDocumentCodeAction, out); break; } case IpcId::TextDocumentCodeLens: { auto msg = message->As(); - Out_TextDocumentCodeLens response; - response.id = msg->id; + Out_TextDocumentCodeLens out; + out.id = msg->id; lsDocumentUri file_as_uri = msg->params.textDocument.uri; std::string path = file_as_uri.GetPath(); @@ -2800,7 +2783,7 @@ bool QueryDbMainLoop(Config* config, break; CommonCodeLensParams common; - common.result = &response.result; + common.result = &out.result; common.db = db; common.working_files = working_files; common.working_file = working_files->GetFileByFilename(file->def->path); @@ -2884,7 +2867,7 @@ bool QueryDbMainLoop(Config* config, code_lens.command->arguments.uri = ls_base->uri; code_lens.command->arguments.position = ls_base->range.start; - response.result.push_back(code_lens); + out.result.push_back(code_lens); } } } @@ -2918,7 +2901,7 @@ bool QueryDbMainLoop(Config* config, }; } - ipc->SendOutMessageToClient(IpcId::TextDocumentCodeLens, response); + IpcManager::WriteStdout(IpcId::TextDocumentCodeLens, out); break; } @@ -2929,8 +2912,8 @@ bool QueryDbMainLoop(Config* config, // inspiration auto msg = message->As(); - Out_WorkspaceSymbol response; - response.id = msg->id; + Out_WorkspaceSymbol out; + out.id = msg->id; LOG_S(INFO) << "[querydb] Considering " << db->detailed_names.size() << " candidates for query " << msg->params.query; @@ -2947,13 +2930,13 @@ bool QueryDbMainLoop(Config* config, continue; InsertSymbolIntoResult(db, working_files, db->symbols[i], - &response.result); - if (response.result.size() >= config->maxWorkspaceSearchResults) + &out.result); + if (out.result.size() >= config->maxWorkspaceSearchResults) break; } } - if (response.result.size() < config->maxWorkspaceSearchResults) { + if (out.result.size() < config->maxWorkspaceSearchResults) { for (int i = 0; i < db->detailed_names.size(); ++i) { if (SubstringMatch(query, db->detailed_names[i])) { // Do not show the same entry twice. @@ -2961,16 +2944,16 @@ bool QueryDbMainLoop(Config* config, continue; InsertSymbolIntoResult(db, working_files, db->symbols[i], - &response.result); - if (response.result.size() >= config->maxWorkspaceSearchResults) + &out.result); + if (out.result.size() >= config->maxWorkspaceSearchResults) break; } } } - LOG_S(INFO) << "[querydb] Found " << response.result.size() + LOG_S(INFO) << "[querydb] Found " << out.result.size() << " results for query " << query; - ipc->SendOutMessageToClient(IpcId::WorkspaceSymbol, response); + IpcManager::WriteStdout(IpcId::WorkspaceSymbol, out); break; } @@ -3076,8 +3059,8 @@ void RunQueryDbThread(const std::string& bin_name, FreeUnusedMemory(); if (!did_work) { - waiter->Wait({IpcManager::instance()->threaded_queue_for_server_.get(), - &queue->do_id_map, &queue->on_indexed}); + waiter->Wait({&IpcManager::instance()->for_querydb, &queue->do_id_map, + &queue->on_indexed}); } } } @@ -3142,7 +3125,7 @@ void LaunchStdinLoop(Config* config, // loop to exit the thread. If we keep parsing input stdin is likely // closed so cquery will exit. LOG_S(INFO) << "cquery will exit when all threads are idle"; - ipc->SendMessage(IpcManager::Destination::Server, std::move(message)); + ipc->for_querydb.Enqueue(std::move(message)); return WorkThread::Result::ExitThread; } @@ -3174,7 +3157,7 @@ void LaunchStdinLoop(Config* config, case IpcId::CqueryDerived: case IpcId::CqueryIndexFile: case IpcId::CqueryQueryDbWaitForIdleIndexer: { - ipc->SendMessage(IpcManager::Destination::Server, std::move(message)); + ipc->for_querydb.Enqueue(std::move(message)); break; } @@ -3195,42 +3178,32 @@ void LaunchStdoutThread(std::unordered_map* request_times, WorkThread::StartThread("stdout", [=]() { IpcManager* ipc = IpcManager::instance(); - std::vector> messages = - ipc->GetMessages(IpcManager::Destination::Client); + std::vector messages = + ipc->for_stdout.DequeueAll(); if (messages.empty()) { - waiter->Wait({ipc->threaded_queue_for_client_.get()}); + waiter->Wait({&ipc->for_stdout}); return queue->HasWork() ? WorkThread::Result::MoreWork : WorkThread::Result::NoWork; } for (auto& message : messages) { - switch (message->method_id) { - case IpcId::Cout: { - auto msg = message->As(); - - if (ShouldDisplayIpcTiming(msg->original_ipc_id)) { - Timer time = (*request_times)[msg->original_ipc_id]; - time.ResetAndPrint("[e2e] Running " + std::string(IpcIdToString( - msg->original_ipc_id))); - } - - if (g_log_stdin_stdout_to_stderr) { - std::string printed = "[COUT] |" + msg->content + "|\n"; - std::cerr << printed; - std::cerr.flush(); - } - - std::cout << msg->content; - std::cout.flush(); - break; - } - - default: { - LOG_S(FATAL) << "Exiting; unhandled IPC message " - << IpcIdToString(message->method_id); - exit(1); - } + if (ShouldDisplayIpcTiming(message.id)) { + Timer time = (*request_times)[message.id]; + time.ResetAndPrint("[e2e] Running " + + std::string(IpcIdToString(message.id))); } + + if (g_log_stdin_stdout_to_stderr) { + std::ostringstream sstream; + sstream << "[COUT] |"; + sstream << message.content; + sstream << "|\n"; + std::cerr << sstream.str(); + std::cerr.flush(); + } + + std::cout << message.content; + std::cout.flush(); } return WorkThread::Result::MoreWork; diff --git a/src/ipc_manager.cc b/src/ipc_manager.cc index af43e1bb..adfbc01a 100644 --- a/src/ipc_manager.cc +++ b/src/ipc_manager.cc @@ -1,5 +1,9 @@ #include "ipc_manager.h" +#include "language_server_api.h" + +#include + IpcManager* IpcManager::instance_ = nullptr; // static @@ -12,35 +16,16 @@ void IpcManager::CreateInstance(MultiQueueWaiter* waiter) { instance_ = new IpcManager(waiter); } -ThreadedQueue>* IpcManager::GetThreadedQueue( - Destination destination) { - return destination == Destination::Client ? threaded_queue_for_client_.get() - : threaded_queue_for_server_.get(); -} - -void IpcManager::SendOutMessageToClient(IpcId id, lsBaseOutMessage& response) { +// static +void IpcManager::WriteStdout(IpcId id, lsBaseOutMessage& response) { std::ostringstream sstream; response.Write(sstream); - auto out = MakeUnique(); - out->content = sstream.str(); - out->original_ipc_id = id; - GetThreadedQueue(Destination::Client)->Enqueue(std::move(out)); + StdoutMessage out; + out.content = sstream.str(); + out.id = id; + instance()->for_stdout.Enqueue(std::move(out)); } -void IpcManager::SendMessage(Destination destination, - std::unique_ptr message) { - GetThreadedQueue(destination)->Enqueue(std::move(message)); -} - -std::vector> IpcManager::GetMessages( - Destination destination) { - return GetThreadedQueue(destination)->DequeueAll(); -} - -IpcManager::IpcManager(MultiQueueWaiter* waiter) { - threaded_queue_for_client_ = - MakeUnique>>(waiter); - threaded_queue_for_server_ = - MakeUnique>>(waiter); -} \ No newline at end of file +IpcManager::IpcManager(MultiQueueWaiter* waiter) + : for_stdout(waiter), for_querydb(waiter) {} \ No newline at end of file diff --git a/src/ipc_manager.h b/src/ipc_manager.h index 34be8b5d..7a719886 100644 --- a/src/ipc_manager.h +++ b/src/ipc_manager.h @@ -1,34 +1,28 @@ #pragma once #include "ipc.h" -#include "language_server_api.h" #include "threaded_queue.h" #include +class lsBaseOutMessage; + struct IpcManager { - static IpcManager* instance_; + struct StdoutMessage { + IpcId id; + std::string content; + }; + + ThreadedQueue for_stdout; + ThreadedQueue> for_querydb; + static IpcManager* instance(); static void CreateInstance(MultiQueueWaiter* waiter); - std::unique_ptr>> - threaded_queue_for_client_; - std::unique_ptr>> - threaded_queue_for_server_; - - enum class Destination { Client, Server }; - - ThreadedQueue>* GetThreadedQueue( - Destination destination); - - void SendOutMessageToClient(IpcId id, lsBaseOutMessage& response); - - void SendMessage(Destination destination, - std::unique_ptr message); - - std::vector> GetMessages( - Destination destination); + static void WriteStdout(IpcId id, lsBaseOutMessage& response); private: - IpcManager(MultiQueueWaiter* waiter); + explicit IpcManager(MultiQueueWaiter* waiter); + + static IpcManager* instance_; }; diff --git a/src/match.cc b/src/match.cc index 74593ab5..773c7cde 100644 --- a/src/match.cc +++ b/src/match.cc @@ -33,7 +33,7 @@ optional Matcher::Create(const std::string& search) { out.params.type = lsMessageType::Error; out.params.message = "cquery: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what(); - IpcManager::instance()->SendOutMessageToClient(IpcId::Cout, out); + IpcManager::WriteStdout(IpcId::Cout, out); return nullopt; } }