Simplify IpcManager.

It no longer supports multi-process IPC; remove some of the extra code that was used to support that.
This commit is contained in:
Jacob Dufault 2017-12-04 00:13:35 -08:00
parent b64b8b5493
commit 6c5f1d9c88
4 changed files with 203 additions and 251 deletions

View File

@ -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<int> FindIncludeLine(const std::vector<std::string>& lines,
@ -522,11 +520,10 @@ void EmitDiagnostics(WorkingFiles* working_files,
std::string path,
NonElidedVector<lsDiagnostic> 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<std::unique_ptr<BaseIpcMessage>> 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<Ipc_CqueryCallTreeExpand>();
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<QueryLocation> 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<QueryLocation> 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<QueryLocation> 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<QueryLocation> 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<QueryLocation> 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<QueryLocation> 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<std::mutex> 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<lsCompletionItem>& 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<Ipc_TextDocumentSignatureHelp>();
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<lsLocation> 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<QueryLocation> 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<QueryLocation> 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<lsLocation> 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<Ipc_TextDocumentDocumentSymbol>();
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<Ipc_TextDocumentDocumentLink>();
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<Ipc_TextDocumentCodeLens>();
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<Ipc_WorkspaceSymbol>();
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<IpcId, Timer>* request_times,
WorkThread::StartThread("stdout", [=]() {
IpcManager* ipc = IpcManager::instance();
std::vector<std::unique_ptr<BaseIpcMessage>> messages =
ipc->GetMessages(IpcManager::Destination::Client);
std::vector<IpcManager::StdoutMessage> 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<Ipc_Cout>();
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;

View File

@ -1,5 +1,9 @@
#include "ipc_manager.h"
#include "language_server_api.h"
#include <sstream>
IpcManager* IpcManager::instance_ = nullptr;
// static
@ -12,35 +16,16 @@ void IpcManager::CreateInstance(MultiQueueWaiter* waiter) {
instance_ = new IpcManager(waiter);
}
ThreadedQueue<std::unique_ptr<BaseIpcMessage>>* 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<Ipc_Cout>();
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<BaseIpcMessage> message) {
GetThreadedQueue(destination)->Enqueue(std::move(message));
}
std::vector<std::unique_ptr<BaseIpcMessage>> IpcManager::GetMessages(
Destination destination) {
return GetThreadedQueue(destination)->DequeueAll();
}
IpcManager::IpcManager(MultiQueueWaiter* waiter) {
threaded_queue_for_client_ =
MakeUnique<ThreadedQueue<std::unique_ptr<BaseIpcMessage>>>(waiter);
threaded_queue_for_server_ =
MakeUnique<ThreadedQueue<std::unique_ptr<BaseIpcMessage>>>(waiter);
}
IpcManager::IpcManager(MultiQueueWaiter* waiter)
: for_stdout(waiter), for_querydb(waiter) {}

View File

@ -1,34 +1,28 @@
#pragma once
#include "ipc.h"
#include "language_server_api.h"
#include "threaded_queue.h"
#include <memory>
class lsBaseOutMessage;
struct IpcManager {
static IpcManager* instance_;
struct StdoutMessage {
IpcId id;
std::string content;
};
ThreadedQueue<StdoutMessage> for_stdout;
ThreadedQueue<std::unique_ptr<BaseIpcMessage>> for_querydb;
static IpcManager* instance();
static void CreateInstance(MultiQueueWaiter* waiter);
std::unique_ptr<ThreadedQueue<std::unique_ptr<BaseIpcMessage>>>
threaded_queue_for_client_;
std::unique_ptr<ThreadedQueue<std::unique_ptr<BaseIpcMessage>>>
threaded_queue_for_server_;
enum class Destination { Client, Server };
ThreadedQueue<std::unique_ptr<BaseIpcMessage>>* GetThreadedQueue(
Destination destination);
void SendOutMessageToClient(IpcId id, lsBaseOutMessage& response);
void SendMessage(Destination destination,
std::unique_ptr<BaseIpcMessage> message);
std::vector<std::unique_ptr<BaseIpcMessage>> GetMessages(
Destination destination);
static void WriteStdout(IpcId id, lsBaseOutMessage& response);
private:
IpcManager(MultiQueueWaiter* waiter);
explicit IpcManager(MultiQueueWaiter* waiter);
static IpcManager* instance_;
};

View File

@ -33,7 +33,7 @@ optional<Matcher> 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;
}
}