mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +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