Skip to content

Commit eef2513

Browse files
committed
refactor(lsp): create class for outgoing messages
Encapsulate a raw std::vector, giving it a nicer name.
1 parent bf74d23 commit eef2513

File tree

2 files changed

+40
-28
lines changed

2 files changed

+40
-28
lines changed

src/quick-lint-js/lsp/lsp-server.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ void lsp_overlay_configuration_filesystem::close_document(
149149
QLJS_ASSERT(erased > 0);
150150
}
151151

152+
byte_buffer& outgoing_lsp_message_queue::new_message() {
153+
return this->messages_.emplace_back();
154+
}
155+
156+
void outgoing_lsp_message_queue::send(lsp_endpoint_remote& remote) {
157+
for (byte_buffer& notification_json : this->messages_) {
158+
if (notification_json.empty()) {
159+
// TODO(strager): Fix our tests so they don't make empty
160+
// byte_buffer-s.
161+
continue;
162+
}
163+
remote.send_message(std::move(notification_json));
164+
}
165+
this->messages_.clear();
166+
}
167+
152168
linting_lsp_server_handler::linting_lsp_server_handler(
153169
configuration_filesystem* fs, lsp_linter* linter)
154170
: config_fs_(fs), config_loader_(&this->config_fs_), linter_(*linter) {
@@ -253,7 +269,7 @@ void linting_lsp_server_handler::filesystem_changed() {
253269
void linting_lsp_server_handler::add_watch_io_errors(
254270
const std::vector<watch_io_error>& errors) {
255271
if (!errors.empty() && !this->did_report_watch_io_error_) {
256-
byte_buffer& out_json = this->pending_notification_jsons_.emplace_back();
272+
byte_buffer& out_json = this->outgoing_messages_.new_message();
257273
// clang-format off
258274
out_json.append_copy(u8R"--({)--"
259275
u8R"--("jsonrpc":"2.0",)--"
@@ -309,7 +325,7 @@ void linting_lsp_server_handler::handle_workspace_configuration_response(
309325
}
310326

311327
void linting_lsp_server_handler::handle_initialized_notification() {
312-
byte_buffer& request_json = this->pending_notification_jsons_.emplace_back();
328+
byte_buffer& request_json = this->outgoing_messages_.new_message();
313329
this->workspace_configuration_.build_request(initial_configuration_request_id,
314330
request_json);
315331
}
@@ -366,8 +382,7 @@ void linting_lsp_server_handler::config_document::on_text_changed(
366382

367383
void linting_lsp_server_handler::lintable_document::on_text_changed(
368384
linting_lsp_server_handler& handler, string8_view document_uri_json) {
369-
byte_buffer& notification_json =
370-
handler.pending_notification_jsons_.emplace_back();
385+
byte_buffer& notification_json = handler.outgoing_messages_.new_message();
371386
handler.linter_.lint_and_get_diagnostics_notification(
372387
*this, document_uri_json, notification_json);
373388
}
@@ -455,8 +470,7 @@ void linting_lsp_server_handler::handle_text_document_did_open_notification(
455470
if (*config_file) {
456471
doc->config = &(*config_file)->config;
457472
if (!(*config_file)->errors.empty()) {
458-
byte_buffer& message_json =
459-
this->pending_notification_jsons_.emplace_back();
473+
byte_buffer& message_json = this->outgoing_messages_.new_message();
460474
this->write_configuration_errors_notification(
461475
document_path, *config_file, message_json);
462476
}
@@ -465,13 +479,11 @@ void linting_lsp_server_handler::handle_text_document_did_open_notification(
465479
}
466480
} else {
467481
doc->config = &this->default_config_;
468-
byte_buffer& message_json =
469-
this->pending_notification_jsons_.emplace_back();
482+
byte_buffer& message_json = this->outgoing_messages_.new_message();
470483
this->write_configuration_loader_error_notification(
471484
document_path, config_file.error_to_string(), message_json);
472485
}
473-
byte_buffer& notification_json =
474-
this->pending_notification_jsons_.emplace_back();
486+
byte_buffer& notification_json = this->outgoing_messages_.new_message();
475487
this->linter_.lint_and_get_diagnostics_notification(*doc, uri->json,
476488
notification_json);
477489

@@ -485,7 +497,7 @@ void linting_lsp_server_handler::handle_text_document_did_open_notification(
485497
/*token=*/doc.get());
486498
QLJS_ASSERT(config_file.ok());
487499
byte_buffer& config_diagnostics_json =
488-
this->pending_notification_jsons_.emplace_back();
500+
this->outgoing_messages_.new_message();
489501
this->get_config_file_diagnostics_notification(
490502
*config_file, uri->json, doc->version_json, config_diagnostics_json);
491503

@@ -546,7 +558,7 @@ void linting_lsp_server_handler::config_document::on_config_file_changed(
546558
QLJS_ASSERT(change.config_file);
547559
if (change.config_file) {
548560
byte_buffer& config_diagnostics_json =
549-
handler.pending_notification_jsons_.emplace_back();
561+
handler.outgoing_messages_.new_message();
550562
handler.get_config_file_diagnostics_notification(
551563
change.config_file, to_json_escaped_string_with_quotes(document_uri),
552564
this->version_json, config_diagnostics_json);
@@ -562,16 +574,14 @@ void linting_lsp_server_handler::lintable_document::on_config_file_changed(
562574
QLJS_UNIMPLEMENTED();
563575
}
564576
if (change.error) {
565-
byte_buffer& message_json =
566-
handler.pending_notification_jsons_.emplace_back();
577+
byte_buffer& message_json = handler.outgoing_messages_.new_message();
567578
handler.write_configuration_loader_error_notification(
568579
document_path, change.error->error_to_string(), message_json);
569580
}
570581
configuration* config = change.config_file ? &change.config_file->config
571582
: &handler.default_config_;
572583
this->config = config;
573-
byte_buffer& notification_json =
574-
handler.pending_notification_jsons_.emplace_back();
584+
byte_buffer& notification_json = handler.outgoing_messages_.new_message();
575585
// TODO(strager): Don't copy document_uri if it contains only non-special
576586
// characters.
577587
// TODO(strager): Cache the result of to_json_escaped_string?

src/quick-lint-js/lsp/lsp-server.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ struct linting_lsp_server_config {
5858
std::string tracing_directory;
5959
};
6060

61+
// List of asynchronous LSP messages (requests and notifications) to send to the
62+
// client.
63+
class outgoing_lsp_message_queue {
64+
public:
65+
byte_buffer& new_message();
66+
67+
void send(lsp_endpoint_remote&);
68+
69+
private:
70+
std::vector<byte_buffer> messages_;
71+
};
72+
6173
// A linting_lsp_server_handler listens for JavaScript code changes and notifies
6274
// the client of diagnostics.
6375
class linting_lsp_server_handler final : public lsp_endpoint_handler {
@@ -86,15 +98,7 @@ class linting_lsp_server_handler final : public lsp_endpoint_handler {
8698
// Sends notifications and requests to the client.
8799
// TODO(strager): Rename.
88100
void flush_pending_notifications(lsp_endpoint_remote& remote) {
89-
for (byte_buffer& notification_json : this->pending_notification_jsons_) {
90-
if (notification_json.empty()) {
91-
// TODO(strager): Fix our tests so they don't make empty
92-
// byte_buffer-s.
93-
continue;
94-
}
95-
remote.send_message(std::move(notification_json));
96-
}
97-
this->pending_notification_jsons_.clear();
101+
this->outgoing_messages_.send(remote);
98102
}
99103

100104
void add_watch_io_errors(const std::vector<watch_io_error>&);
@@ -189,9 +193,7 @@ class linting_lsp_server_handler final : public lsp_endpoint_handler {
189193
configuration default_config_;
190194
lsp_linter& linter_;
191195
hash_map<string8, std::unique_ptr<document_base> > documents_;
192-
// Stores notifications and requests destined for the client.
193-
// TODO(strager): Rename.
194-
std::vector<byte_buffer> pending_notification_jsons_;
196+
outgoing_lsp_message_queue outgoing_messages_;
195197
linting_lsp_server_config server_config_;
196198
lsp_workspace_configuration workspace_configuration_;
197199
std::unique_ptr<trace_flusher_directory_backend> tracer_backend_;

0 commit comments

Comments
 (0)