mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
fix(lua): use rawget() to get __call in vim.is_callable() (#29536)
Lua 5.1 uses a "raw get" to retrieve `__call` from a metatable to determine if a table is callable. Mirror this behavior in `vim.is_callable()`.
This commit is contained in:
@ -997,7 +997,7 @@ function vim.is_callable(f)
|
|||||||
if m == nil then
|
if m == nil then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
return type(m.__call) == 'function'
|
return type(rawget(m, '__call')) == 'function'
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Creates a table whose missing keys are provided by {createfn} (like Python's "defaultdict").
|
--- Creates a table whose missing keys are provided by {createfn} (like Python's "defaultdict").
|
||||||
|
@ -1495,6 +1495,60 @@ describe('lua stdlib', function()
|
|||||||
]])
|
]])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{ false, false },
|
||||||
|
exec_lua([[
|
||||||
|
local meta = { __call = {} }
|
||||||
|
assert(meta.__call)
|
||||||
|
local function new()
|
||||||
|
return setmetatable({}, meta)
|
||||||
|
end
|
||||||
|
local not_callable = new()
|
||||||
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
eq(
|
||||||
|
{ false, false },
|
||||||
|
exec_lua([[
|
||||||
|
local function new()
|
||||||
|
return { __call = function()end }
|
||||||
|
end
|
||||||
|
local not_callable = new()
|
||||||
|
assert(not_callable.__call)
|
||||||
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
eq(
|
||||||
|
{ false, false },
|
||||||
|
exec_lua([[
|
||||||
|
local meta = setmetatable(
|
||||||
|
{ __index = { __call = function() end } },
|
||||||
|
{ __index = { __call = function() end } }
|
||||||
|
)
|
||||||
|
assert(meta.__call)
|
||||||
|
local not_callable = setmetatable({}, meta)
|
||||||
|
assert(not_callable.__call)
|
||||||
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
||||||
|
]])
|
||||||
|
)
|
||||||
|
eq(
|
||||||
|
{ false, false },
|
||||||
|
exec_lua([[
|
||||||
|
local meta = setmetatable({
|
||||||
|
__index = function()
|
||||||
|
return function() end
|
||||||
|
end,
|
||||||
|
}, {
|
||||||
|
__index = function()
|
||||||
|
return function() end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
assert(meta.__call)
|
||||||
|
local not_callable = setmetatable({}, meta)
|
||||||
|
assert(not_callable.__call)
|
||||||
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
||||||
|
]])
|
||||||
|
)
|
||||||
eq(false, exec_lua('return vim.is_callable(1)'))
|
eq(false, exec_lua('return vim.is_callable(1)'))
|
||||||
eq(false, exec_lua("return vim.is_callable('foo')"))
|
eq(false, exec_lua("return vim.is_callable('foo')"))
|
||||||
eq(false, exec_lua('return vim.is_callable({})'))
|
eq(false, exec_lua('return vim.is_callable({})'))
|
||||||
|
Reference in New Issue
Block a user