Skip to content

Commit c500adf

Browse files
committed
feat(docs): write down ideas for improving lsp_endpoint's design
1 parent 247a86c commit c500adf

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,58 @@ class lsp_endpoint : private lsp_message_parser<lsp_endpoint> {
6060
using message_parser = lsp_message_parser<lsp_endpoint>;
6161

6262
public:
63+
// TODO(strager): It would be nice if we didn't have to pass an
64+
// lsp_endpoint_remote* here. It makes tests uglier and control flow
65+
// non-obvious. Some options I considered:
66+
//
67+
// * lsp_endpoint stores an outgoing_lsp_message_queue and exposes a function:
68+
// void lsp_endpoint::flush_outgoing_messages(lsp_endpoint_remote*);
69+
// * This means that both lsp_endpoint and linting_lsp_server_handler have
70+
// flush functions which need to be called, which is probably confusing.
71+
//
72+
// * The above option, and additionally a reference to the
73+
// outgoing_lsp_message_queue object is given to lsp_endpoint_handler.
74+
// * Asynchronous events (e.g. filesystem notifications) can cause
75+
// asynchronous messages from linting_lsp_server_handler, so
76+
// linting_lsp_server_handler still needs its own
77+
// outgoing_lsp_message_queue. Therefore, the two-flush-function issue
78+
// isn't solved.
79+
// * Tests are even harder to write than they already are.
80+
//
81+
// * lsp_endpoint accepts an outgoing_lsp_message_queue* instead of an
82+
// lsp_endpoint_remote*.
83+
// * This runs the risk of someone else using the outgoing_lsp_message_queue
84+
// while we're working with it. Perhaps this can be solved by making
85+
// outgoing_lsp_message_queue safer to use.
86+
// * Tests are slightly harder to write because outgoing_lsp_message_queue
87+
// isn't polymorphic. However, we could add test utilities directly to
88+
// outgoing_lsp_message_queue to paper over this, because
89+
// outgoing_lsp_message_queue now buffers messages like
90+
// spy_lsp_endpoint_remote does.
91+
//
92+
// * lsp_endpoint sends responses by calling a new function:
93+
// void lsp_endpoint_handler::send_message_to_client_later(byte_buffer&);
94+
// * From this class' perspective, this new design effectively merges
95+
// lsp_endpoint_remote and lsp_endpoint_handler.
96+
// * This centralizes the outgoing_lsp_message_queue inside each
97+
// lsp_endpoint_handler. This means flushing is more consistent.
98+
// * From a design perspective, it's weird that lsp_endpoint_handler is
99+
// responsible for publicly holding the outgoing_lsp_message_queue. But
100+
// this design quirk already exists.
101+
// * I don't know whether tests would change for the worse or for the
102+
// better.
103+
//
104+
// * Drop support for batched requests and responses, and remove the
105+
// reply parameter from lsp_endpoint_handler::handle_request.
106+
// * In practice, no LSP client sends batched requests anyway.
107+
// * TODO(strager): Codify this in the LSP spec.
108+
// https://github.com/microsoft/language-server-protocol/pull/1651
109+
// * This gives lsp_endpoint_handler full responsibility in sending
110+
// responses.
111+
// * This means flushing is more consistent.
112+
// * This means lsp_endpoint_handler implementations need more code.
113+
// * I don't know whether tests would change for the worse or for the
114+
// better.
63115
explicit lsp_endpoint(lsp_endpoint_handler* handler,
64116
lsp_endpoint_remote* remote);
65117

0 commit comments

Comments
 (0)