#5062 Purge all deeply nested invalid Lua keys

This commit is contained in:
w0rp
2026-05-31 17:55:04 +01:00
parent 399c0ffd64
commit 7a7fc85e51
3 changed files with 117 additions and 9 deletions
+33 -9
View File
@@ -1,12 +1,34 @@
local module = {}
local function remove_invalid_lsp_table_keys(value, seen)
if type(value) ~= "table" then
return value
end
seen = seen or {}
if seen[value] then
return value
end
seen[value] = true
for key, child in pairs(value) do
local key_type = type(key)
if key_type ~= "number" and key_type ~= "string" then
value[key] = nil
else
remove_invalid_lsp_table_keys(child, seen)
end
end
return value
end
module.start = function(config)
-- Neovim's luaeval sometimes adds a Boolean key to table we need to remove.
if type(config.init_options) == "table"
and config.init_options[true] ~= nil
then
config.init_options[true] = nil
end
remove_invalid_lsp_table_keys(config.init_options)
-- ensure init_options uses empty_dict if empty
if type(config.init_options) == "table"
@@ -138,17 +160,19 @@ module.send_message = function(args)
return 0
end
local params = remove_invalid_lsp_table_keys(args.params)
if args.is_notification then
local success
if vim.version().minor >= 11 then
-- Supporting Neovim 0.11+
---@diagnostic disable-next-line
success = client.notify(client, args.method, args.params)
success = client.notify(client, args.method, params)
else
-- Supporting Neovim 0.10 and below
---@diagnostic disable-next-line
success = client.notify(args.method, args.params)
success = client.notify(args.method, params)
end
-- For notifications we send a request and expect no direct response.
@@ -175,11 +199,11 @@ module.send_message = function(args)
-- We set the bufnr to -1 to prevent Neovim from flushing anything, as ALE
-- already flushes changes to files before sending requests.
---@diagnostic disable-next-line
success, request_id = client.request(client, args.method, args.params, handle_func, -1)
success, request_id = client.request(client, args.method, params, handle_func, -1)
else
-- Supporting Neovim 0.10 and below
---@diagnostic disable-next-line
success, request_id = client.request(args.method, args.params, handle_func, -1)
success, request_id = client.request(args.method, params, handle_func, -1)
end
if success then
+47
View File
@@ -76,6 +76,53 @@ describe("ale.lsp.send_message", function()
eq({}, vim_fn_calls)
end)
it("should remove Boolean table keys before sending notifications", function()
local notify_calls = {}
clients[1] = {
notify = function(...)
table.insert(notify_calls, {...})
return true
end,
}
eq(-1, lsp.send_message({
client_id = 1,
is_notification = true,
method = "workspace/didChangeConfiguration",
params = {
settings = {
[true] = "invalid",
python = {
analysis = true,
typeCheckingMode = "basic",
[false] = "invalid",
},
array = {
{
enabled = false,
[true] = "invalid",
},
},
},
},
}))
eq(1, #notify_calls)
eq({
settings = {
python = {
analysis = true,
typeCheckingMode = "basic",
},
array = {
{
enabled = false,
},
},
},
}, notify_calls[1][3])
end)
it("should return 0 if a notification fails for Neovim 0.11+", function()
local notify_calls = {}
+37
View File
@@ -153,6 +153,43 @@ describe("ale.lsp.start", function()
eq({foo = "bar", nested = {baz = 123}}, start_calls[1][1].init_options)
end)
it("should remove nested Boolean keys from init_options", function()
lsp.start({
name = "gopls:/code",
cmd = "gopls",
root_dir = "/code",
init_options = {
settings = {
[true] = "invalid",
gopls = {
analyses = {
unusedparams = true,
[false] = "invalid",
},
},
},
},
})
-- Remove functions we can't compare
for _, args in pairs(start_calls) do
args[1].handlers = nil
args[1].on_init = nil
args[1].get_language_id = nil
end
eq(1, #start_calls)
eq({
settings = {
gopls = {
analyses = {
unusedparams = true,
},
},
},
}, start_calls[1][1].init_options)
end)
it("should start lsp socket connections with the correct arguments", function()
lsp.start({
name = "localhost:1234:/code",