Browse Source

Cleanup of language client json parsing code

pipelines/235045657
eidheim 5 years ago
parent
commit
161b26aefa
  1. 97
      src/source_language_protocol.cpp

97
src/source_language_protocol.cpp

@ -171,31 +171,30 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang
}, },
"trace": "off")", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { "trace": "off")", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
if(!error) { if(!error) {
auto capabilities_pt = result.find("capabilities"); if(auto capabilities_pt = result.get_child_optional("capabilities")) {
if(capabilities_pt != result.not_found()) {
try { try {
capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->second.get<int>("textDocumentSync")); capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->get<int>("textDocumentSync"));
} }
catch(...) { catch(...) {
capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->second.get<int>("textDocumentSync.change", 0)); capabilities.text_document_sync = static_cast<LanguageProtocol::Capabilities::TextDocumentSync>(capabilities_pt->get<int>("textDocumentSync.change", 0));
} }
capabilities.hover = capabilities_pt->second.get<bool>("hoverProvider", false); capabilities.hover = capabilities_pt->get<bool>("hoverProvider", false);
capabilities.completion = capabilities_pt->second.find("completionProvider") != capabilities_pt->second.not_found() ? true : false; capabilities.completion = static_cast<bool>(capabilities_pt->get_child_optional("completionProvider"));
capabilities.signature_help = capabilities_pt->second.find("signatureHelpProvider") != capabilities_pt->second.not_found() ? true : false; capabilities.signature_help = static_cast<bool>(capabilities_pt->get_child_optional("signatureHelpProvider"));
capabilities.definition = capabilities_pt->second.get<bool>("definitionProvider", false); capabilities.definition = capabilities_pt->get<bool>("definitionProvider", false);
capabilities.references = capabilities_pt->second.get<bool>("referencesProvider", false); capabilities.references = capabilities_pt->get<bool>("referencesProvider", false);
capabilities.document_highlight = capabilities_pt->second.get<bool>("documentHighlightProvider", false); capabilities.document_highlight = capabilities_pt->get<bool>("documentHighlightProvider", false);
capabilities.workspace_symbol = capabilities_pt->second.get<bool>("workspaceSymbolProvider", false); capabilities.workspace_symbol = capabilities_pt->get<bool>("workspaceSymbolProvider", false);
capabilities.document_symbol = capabilities_pt->second.get<bool>("documentSymbolProvider", false); capabilities.document_symbol = capabilities_pt->get<bool>("documentSymbolProvider", false);
capabilities.document_formatting = capabilities_pt->second.get<bool>("documentFormattingProvider", false); capabilities.document_formatting = capabilities_pt->get<bool>("documentFormattingProvider", false);
capabilities.document_range_formatting = capabilities_pt->second.get<bool>("documentRangeFormattingProvider", false); capabilities.document_range_formatting = capabilities_pt->get<bool>("documentRangeFormattingProvider", false);
capabilities.rename = capabilities_pt->second.get<bool>("renameProvider", false); capabilities.rename = capabilities_pt->get<bool>("renameProvider", false);
if(!capabilities.rename) if(!capabilities.rename)
capabilities.rename = capabilities_pt->second.get<bool>("renameProvider.prepareProvider", false); capabilities.rename = capabilities_pt->get<bool>("renameProvider.prepareProvider", false);
capabilities.code_action = capabilities_pt->second.get<bool>("codeActionProvider", false); capabilities.code_action = capabilities_pt->get<bool>("codeActionProvider", false);
if(!capabilities.code_action) if(!capabilities.code_action)
capabilities.code_action = static_cast<bool>(capabilities_pt->second.get_child_optional("codeActionProvider.codeActionKinds")); capabilities.code_action = static_cast<bool>(capabilities_pt->get_child_optional("codeActionProvider.codeActionKinds"));
capabilities.type_coverage = capabilities_pt->second.get<bool>("typeCoverageProvider", false); capabilities.type_coverage = capabilities_pt->get<bool>("typeCoverageProvider", false);
} }
write_notification("initialized", ""); write_notification("initialized", "");
@ -274,23 +273,21 @@ void LanguageProtocol::Client::parse_server_message() {
} }
auto message_id = pt.get_optional<size_t>("id"); auto message_id = pt.get_optional<size_t>("id");
auto result_it = pt.find("result");
auto error_it = pt.find("error");
{ {
LockGuard lock(read_write_mutex); LockGuard lock(read_write_mutex);
if(result_it != pt.not_found()) { if(auto result = pt.get_child_optional("result")) {
if(message_id) { if(message_id) {
auto id_it = handlers.find(*message_id); auto id_it = handlers.find(*message_id);
if(id_it != handlers.end()) { if(id_it != handlers.end()) {
auto function = std::move(id_it->second.second); auto function = std::move(id_it->second.second);
handlers.erase(id_it); handlers.erase(id_it);
lock.unlock(); lock.unlock();
function(result_it->second, false); function(*result, false);
lock.lock(); lock.lock();
} }
} }
} }
else if(error_it != pt.not_found()) { else if(auto error = pt.get_child_optional("error")) {
if(!Config::get().log.language_server) if(!Config::get().log.language_server)
boost::property_tree::write_json(std::cerr, pt); boost::property_tree::write_json(std::cerr, pt);
if(message_id) { if(message_id) {
@ -299,23 +296,19 @@ void LanguageProtocol::Client::parse_server_message() {
auto function = std::move(id_it->second.second); auto function = std::move(id_it->second.second);
handlers.erase(id_it); handlers.erase(id_it);
lock.unlock(); lock.unlock();
function(error_it->second, true); function(*error, true);
lock.lock(); lock.lock();
} }
} }
} }
else { else if(auto method = pt.get_optional<std::string>("method")) {
auto method_it = pt.find("method"); if(auto params = pt.get_child_optional("params")) {
if(method_it != pt.not_found()) { lock.unlock();
auto params_it = pt.find("params"); if(message_id)
if(params_it != pt.not_found()) { handle_server_request(*message_id, *method, *params);
lock.unlock(); else
if(message_id) handle_server_notification(*method, *params);
handle_server_request(*message_id, method_it->second.get_value<std::string>(""), params_it->second); lock.lock();
else
handle_server_notification(method_it->second.get_value<std::string>(""), params_it->second);
lock.lock();
}
} }
} }
} }
@ -754,9 +747,8 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
else else
project_path = file_path.parent_path(); project_path = file_path.parent_path();
try { try {
auto changes_it = result.find("changes"); if(auto changes_pt = result.get_child_optional("changes")) {
if(changes_it != result.not_found()) { for(auto file_it = changes_pt->begin(); file_it != changes_pt->end(); ++file_it) {
for(auto file_it = changes_it->second.begin(); file_it != changes_it->second.end(); ++file_it) {
auto file = file_it->first; auto file = file_it->first;
file.erase(0, 7); file.erase(0, 7);
if(filesystem::file_in_path(file, project_path)) { if(filesystem::file_in_path(file, project_path)) {
@ -767,12 +759,10 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
} }
} }
} }
else { else if(auto changes_pt = result.get_child_optional("documentChanges")) {
auto changes_pt = result.get_child("documentChanges", boost::property_tree::ptree()); for(auto change_it = changes_pt->begin(); change_it != changes_pt->end(); ++change_it) {
for(auto change_it = changes_pt.begin(); change_it != changes_pt.end(); ++change_it) { if(auto document = change_it->second.get_child_optional("textDocument")) {
auto document_it = change_it->second.find("textDocument"); auto file = filesystem::get_path_from_uri(document->get<std::string>("uri", ""));
if(document_it != change_it->second.not_found()) {
auto file = filesystem::get_path_from_uri(document_it->second.get<std::string>("uri", ""));
if(filesystem::file_in_path(file, project_path)) { if(filesystem::file_in_path(file, project_path)) {
std::vector<LanguageProtocol::TextEdit> edits; std::vector<LanguageProtocol::TextEdit> edits;
auto edits_pt = change_it->second.get_child("edits", boost::property_tree::ptree()); auto edits_pt = change_it->second.get_child("edits", boost::property_tree::ptree());
@ -916,8 +906,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
if(kind == 6 || kind == 9 || kind == 12) { if(kind == 6 || kind == 9 || kind == 12) {
std::unique_ptr<LanguageProtocol::Range> range; std::unique_ptr<LanguageProtocol::Range> range;
std::string prefix; std::string prefix;
auto location_pt = it->second.get_child_optional("location"); if(auto location_pt = it->second.get_child_optional("location")) {
if(location_pt) {
LanguageProtocol::Location location(*location_pt); LanguageProtocol::Location location(*location_pt);
range = std::make_unique<LanguageProtocol::Range>(location.range); range = std::make_unique<LanguageProtocol::Range>(location.range);
std::string container = it->second.get<std::string>("containerName", ""); std::string container = it->second.get<std::string>("containerName", "");
@ -933,8 +922,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() {
} }
methods.emplace_back(Offset(range->start.line, range->start.character), (!prefix.empty() ? Glib::Markup::escape_text(prefix) + ':' : "") + std::to_string(range->start.line + 1) + ": " + "<b>" + Glib::Markup::escape_text(it->second.get<std::string>("name")) + "</b>"); methods.emplace_back(Offset(range->start.line, range->start.character), (!prefix.empty() ? Glib::Markup::escape_text(prefix) + ':' : "") + std::to_string(range->start.line + 1) + ": " + "<b>" + Glib::Markup::escape_text(it->second.get<std::string>("name")) + "</b>");
} }
auto children = it->second.get_child_optional("children"); if(auto children = it->second.get_child_optional("children"))
if(children)
parse_result(*children, (!container.empty() ? container + "::" : "") + it->second.get<std::string>("name")); parse_result(*children, (!container.empty() ? container + "::" : "") + it->second.get<std::string>("name"));
} }
catch(...) { catch(...) {
@ -1024,8 +1012,7 @@ void Source::LanguageProtocolView::update_diagnostics_async(std::vector<Language
if(it->second.get<std::string>("kind") == "quickfix") { if(it->second.get<std::string>("kind") == "quickfix") {
auto title = it->second.get<std::string>("title"); auto title = it->second.get<std::string>("title");
std::vector<LanguageProtocol::Diagnostic> quickfix_diagnostics; std::vector<LanguageProtocol::Diagnostic> quickfix_diagnostics;
auto diagnostics_pt = it->second.get_child_optional("diagnostics"); if(auto diagnostics_pt = it->second.get_child_optional("diagnostics")) {
if(diagnostics_pt) {
for(auto it = diagnostics_pt->begin(); it != diagnostics_pt->end(); ++it) for(auto it = diagnostics_pt->begin(); it != diagnostics_pt->end(); ++it)
quickfix_diagnostics.emplace_back(it->second); quickfix_diagnostics.emplace_back(it->second);
} }
@ -1681,8 +1668,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
client->write_request(this, "textDocument/completion", R"("textDocument":{"uri":")" + uri + R"("}, "position": {"line": )" + std::to_string(line_number - 1) + ", \"character\": " + std::to_string(column - 1) + "}", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { client->write_request(this, "textDocument/completion", R"("textDocument":{"uri":")" + uri + R"("}, "position": {"line": )" + std::to_string(line_number - 1) + ", \"character\": " + std::to_string(column - 1) + "}", [this, &result_processed](const boost::property_tree::ptree &result, bool error) {
if(!error) { if(!error) {
boost::property_tree::ptree::const_iterator begin, end; boost::property_tree::ptree::const_iterator begin, end;
auto items = result.get_child_optional("items"); if(auto items = result.get_child_optional("items")) {
if(items) {
begin = items->begin(); begin = items->begin();
end = items->end(); end = items->end();
} }
@ -1702,8 +1688,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
auto documentation = it->second.get<std::string>("documentation", ""); auto documentation = it->second.get<std::string>("documentation", "");
std::string documentation_kind; std::string documentation_kind;
if(documentation.empty()) { if(documentation.empty()) {
auto documentation_pt = it->second.get_child_optional("documentation"); if(auto documentation_pt = it->second.get_child_optional("documentation")) {
if(documentation_pt) {
documentation = documentation_pt->get<std::string>("value", ""); documentation = documentation_pt->get<std::string>("value", "");
documentation_kind = documentation_pt->get<std::string>("kind", ""); documentation_kind = documentation_pt->get<std::string>("kind", "");
} }

Loading…
Cancel
Save