diff options
author | ZyX <kp-pav@yandex.ru> | 2016-07-16 00:48:25 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2017-03-27 00:11:27 +0300 |
commit | 7a013e93e0364f78a2bc04eadaaeeaa689d0258a (patch) | |
tree | 3f5a1b42dc9847ddc39f844f76b6c946f4ed4a05 | |
parent | 425d348f0f9f680a44af31fc3cecd20a07374bb5 (diff) | |
download | rneovim-7a013e93e0364f78a2bc04eadaaeeaa689d0258a.tar.gz rneovim-7a013e93e0364f78a2bc04eadaaeeaa689d0258a.tar.bz2 rneovim-7a013e93e0364f78a2bc04eadaaeeaa689d0258a.zip |
executor/converter: Make it possible to supply `{}` to Dictionary arg
-rw-r--r-- | src/nvim/viml/executor/converter.c | 16 | ||||
-rw-r--r-- | test/functional/lua_spec.lua | 20 |
2 files changed, 29 insertions, 7 deletions
diff --git a/src/nvim/viml/executor/converter.c b/src/nvim/viml/executor/converter.c index 6c9b42b38c..a6399500f2 100644 --- a/src/nvim/viml/executor/converter.c +++ b/src/nvim/viml/executor/converter.c @@ -33,6 +33,7 @@ typedef struct { ///< either kObjectTypeNil, kObjectTypeDictionary or ///< kObjectTypeArray, depending on other properties. lua_Number val; ///< If has_val_key and val_type == LUA_TNUMBER: value. + bool has_type_key; ///< True if type key is present. } LuaTableProps; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -48,8 +49,6 @@ typedef struct { static LuaTableProps nlua_traverse_table(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { - bool has_type_key = false; // True if type key was found, - // @see nlua_push_type_idx(). size_t tsize = 0; // Total number of keys. int val_type = 0; // If has_val_key: lua type of the value. bool has_val_key = false; // True if val key was found, @@ -96,7 +95,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) if (n == (lua_Number)kObjectTypeFloat || n == (lua_Number)kObjectTypeArray || n == (lua_Number)kObjectTypeDictionary) { - has_type_key = true; + ret.has_type_key = true; ret.type = (ObjectType)n; } else { other_keys_num++; @@ -121,7 +120,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) tsize++; lua_pop(lstate, 1); } - if (has_type_key) { + if (ret.has_type_key) { if (ret.type == kObjectTypeFloat && (!has_val_key || val_type != LUA_TNUMBER)) { ret.type = kObjectTypeNil; @@ -133,7 +132,7 @@ static LuaTableProps nlua_traverse_table(lua_State *const lstate) // should be ignored. if (ret.maxidx != 0 && ret.maxidx != (tsize - - has_type_key + - ret.has_type_key - other_keys_num - has_val_key - ret.string_keys_num)) { @@ -789,7 +788,12 @@ static inline LuaTableProps nlua_check_type(lua_State *const lstate, } return (LuaTableProps) { .type = kObjectTypeNil }; } - const LuaTableProps table_props = nlua_traverse_table(lstate); + LuaTableProps table_props = nlua_traverse_table(lstate); + + if (type == kObjectTypeDictionary && table_props.type == kObjectTypeArray + && table_props.maxidx == 0 && !table_props.has_type_key) { + table_props.type = kObjectTypeDictionary; + } if (table_props.type != type) { if (err) { diff --git a/test/functional/lua_spec.lua b/test/functional/lua_spec.lua index bd1ed51c2d..082efe4c0e 100644 --- a/test/functional/lua_spec.lua +++ b/test/functional/lua_spec.lua @@ -234,11 +234,29 @@ describe('luaeval() function', function() eq({}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array})')) - -- Presence of type_idx makes Vim ignore some keys eq({42}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) eq({{foo=2}}, funcs.luaeval('vim.api._vim_id_array({{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) eq({10}, funcs.luaeval('vim.api._vim_id_array({{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) eq({}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})')) + + eq({}, funcs.luaeval('vim.api._vim_id_array({})')) + eq(3, eval([[type(luaeval('vim.api._vim_id_array({})'))]])) + end) + + it('correctly converts dictionaries with type_idx to API objects', function() + eq(4, eval([[type(luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary})'))]])) + + eq({}, funcs.luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary})')) + + eq({v={42}}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) + eq({foo=2}, funcs.luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})')) + eq({v=10}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})')) + eq({v={}}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2}})')) + + -- If API requests dictionary, then empty table will be the one. This is not + -- the case normally because empty table is an empty arrray. + eq({}, funcs.luaeval('vim.api._vim_id_dictionary({})')) + eq(4, eval([[type(luaeval('vim.api._vim_id_dictionary({})'))]])) end) it('correctly converts self-containing containers', function() |