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
|
||||
return false
|
||||
end
|
||||
return type(m.__call) == 'function'
|
||||
return type(rawget(m, '__call')) == 'function'
|
||||
end
|
||||
|
||||
--- 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('foo')"))
|
||||
eq(false, exec_lua('return vim.is_callable({})'))
|
||||
|
Reference in New Issue
Block a user