From 6312792d8a6a7d293661d33d440343d4cc6e0e6e Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Sun, 25 Oct 2020 00:28:15 -0400 Subject: lsp: only send buf requests to servers that support the request (#12764) Refactors how required capabilities are detected and validated, and make sure requests are only sent to clients that support it (and only fail if no clients support the provided method). The validation happens at the buf_request level, because we assume that if someone is sending the request directly through the client, they know what they're doing. Also, let unknown methods go through. This is extracted from #12518 and closes #12755. Co-authored-by: francisco souza --- test/functional/plugin/lsp_spec.lua | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index f07a2d18a2..067a13ce68 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -270,6 +270,70 @@ describe('LSP', function() test_name = "basic_check_capabilities"; on_init = function(client) client.stop() + local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") + eq(full_kind, client.resolved_capabilities().text_document_did_change) + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + end; + on_callback = function(...) + eq(table.remove(expected_callbacks), {...}, "expected callback") + end; + } + end) + + it('client.supports_methods() should validate capabilities', function() + local expected_callbacks = { + {NIL, "shutdown", {}, 1}; + } + test_rpc_server { + test_name = "capabilities_for_client_supports_method"; + on_init = function(client) + client.stop() + local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") + eq(full_kind, client.resolved_capabilities().text_document_did_change) + eq(true, client.resolved_capabilities().completion) + eq(true, client.resolved_capabilities().hover) + eq(false, client.resolved_capabilities().goto_definition) + eq(false, client.resolved_capabilities().rename) + + -- known methods for resolved capabilities + eq(true, client.supports_method("textDocument/hover")) + eq(false, client.supports_method("textDocument/definition")) + + -- unknown methods are assumed to be supported. + eq(true, client.supports_method("unknown-method")) + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + end; + on_callback = function(...) + eq(table.remove(expected_callbacks), {...}, "expected callback") + end; + } + end) + + it('should call unsupported_method when trying to call an unsupported method', function() + local expected_callbacks = { + {NIL, "shutdown", {}, 1}; + } + test_rpc_server { + test_name = "capabilities_for_client_supports_method"; + on_setup = function() + exec_lua([=[ + vim.lsp._unsupported_method = function(method) + vim.lsp._last_unsupported_method = method + return 'fake-error' + end + vim.lsp.buf.hover() + ]=]) + end; + on_init = function(client) + client.stop() + local method = exec_lua("return vim.lsp._last_unsupported_method") + eq("textDocument/hover", method) end; on_exit = function(code, signal) eq(0, code, "exit code", fake_lsp_logfile) -- cgit From 1f0f92f8ec0ca94c47707cfebc9eeff561715368 Mon Sep 17 00:00:00 2001 From: francisco souza Date: Sun, 25 Oct 2020 08:17:34 -0400 Subject: lsp: fix fallback for callback in method_unsupported Missed this #12764. My bad :(( --- test/functional/plugin/lsp_spec.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test/functional/plugin') diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 067a13ce68..73f3fe5d0c 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -323,6 +323,9 @@ describe('LSP', function() test_name = "capabilities_for_client_supports_method"; on_setup = function() exec_lua([=[ + vim.lsp.callbacks['textDocument/hover'] = function(err, method) + vim.lsp._last_lsp_callback = { err = err; method = method } + end vim.lsp._unsupported_method = function(method) vim.lsp._last_unsupported_method = method return 'fake-error' @@ -334,6 +337,9 @@ describe('LSP', function() client.stop() local method = exec_lua("return vim.lsp._last_unsupported_method") eq("textDocument/hover", method) + local lsp_cb_call = exec_lua("return vim.lsp._last_lsp_callback") + eq("fake-error", lsp_cb_call.err) + eq("textDocument/hover", lsp_cb_call.method) end; on_exit = function(code, signal) eq(0, code, "exit code", fake_lsp_logfile) -- cgit