Skip to content

Commit

Permalink
lua: fix completion retrieval for cdata objects
Browse files Browse the repository at this point in the history
Cdata objects cannot have an `__autocomplete` metamethod (it's our custom
metamethod). To work this around, we should also lookup the
`__autocomplete` method using an object's `__index` metamethod.

Part of tarantool#9107

NO_CHANGELOG=<not a reported bug>
NO_DOC=<bugfix>
  • Loading branch information
CuriousGeorgiy committed Mar 4, 2024
1 parent f267af2 commit 69216e2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/box/lua/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,30 @@ lua_rl_dmadd(dmlist *ml, const char *p, size_t pn, const char *s, int suf)
return 0;
}

/*
* Try to retrieve object's `__autocomplete` method.
*
* @param L Lua state
* @param obj_idx object's index on Lua stack
* @param mt_idx object metatable's index on Lua stack
*/
static void
lua_rl_get_autocomplete_metamethod(lua_State *L, int obj_idx, int mt_idx)
{
lua_pushstring(L, "__autocomplete");
lua_rawget(L, mt_idx);
if (!lua_isnil(L, -1))
return;
lua_pop(L, 1);
/*
* __autocomplete may not always be part of the metatable (e.g., in case
* of cdata), so we also want to trigger the __index metamethod instead
* of simply doing a raw lookup in the metatable.
*/
lua_pushstring(L, "__autocomplete");
lua_gettable(L, obj_idx);
}

/*
* Get table from __autocomplete function if it's present
* Use __index field of metatable of object as a fallback
Expand All @@ -1105,9 +1129,9 @@ lua_rl_getcompletion(lua_State *L)
lua_pop(L, 1);
return 0;
}
/* use __autocomplete metamethod if it's present */
lua_pushstring(L, "__autocomplete");
lua_rawget(L, -2);
/* use __autocomplete method if it's present */
int top = lua_gettop(L);
lua_rl_get_autocomplete_metamethod(L, top - 1, top);
if (lua_isfunction(L, -1)) {
lua_replace(L, -2);
lua_insert(L, -2);
Expand Down
8 changes: 8 additions & 0 deletions test/app-luatest/gh_6305_autocomplete_metamethod_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ g.test__autocomplete = function()
})
-- the right way - should add 'auto' comletion
setmetatable(tab, {__autocomplete = function() return {auto = true} end})
t.assert_items_equals(tabcomplete('table11.'), {'table11.',
'table11.first',
'table11.second',
'table11.auto',
})
-- __autocomplete should also be looked up in __index
local autocompletion = function() return {auto = true} end
setmetatable(tab, {__index = {__autocomplete = autocompletion}})
t.assert_items_equals(tabcomplete('table11.'), {'table11.',
'table11.first',
'table11.second',
Expand Down

0 comments on commit 69216e2

Please sign in to comment.