diff options
author | bfredl <bjorn.linse@gmail.com> | 2023-08-01 14:01:19 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2023-08-07 13:11:15 +0200 |
commit | 7bc93e0e2f246dd78026a3472d929a0fe450f70d (patch) | |
tree | 9e5b99830c3f08e0ffd75c7a0533b39033490a5b /src/nvim/generators/gen_api_dispatch.lua | |
parent | c01e624b0762b24a4988bf9474a57d5b6278d180 (diff) | |
download | rneovim-7bc93e0e2f246dd78026a3472d929a0fe450f70d.tar.gz rneovim-7bc93e0e2f246dd78026a3472d929a0fe450f70d.tar.bz2 rneovim-7bc93e0e2f246dd78026a3472d929a0fe450f70d.zip |
refactor(api): use typed keysets
Initially this is just for geting rid of boilerplate,
but eventually the types could get exposed as metadata
Diffstat (limited to 'src/nvim/generators/gen_api_dispatch.lua')
-rw-r--r-- | src/nvim/generators/gen_api_dispatch.lua | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index fe63cb883e..9c15597fcc 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -67,13 +67,27 @@ local keysets = {} local function add_keyset(val) local keys = {} - for _,field in ipairs(val.fields) do + local types = {} + local is_set_name = 'is_set__' .. val.keyset_name .. '_' + local has_optional = false + for i,field in ipairs(val.fields) do if field.type ~= 'Object' then - error 'not yet implemented: types other than Object' + types[field.name] = field.type + end + if field.name ~= is_set_name and field.type ~= 'OptionalKeys' then + table.insert(keys, field.name) + else + if i > 1 then + error("'is_set__{type}_' must be first if present") + elseif field.name ~= is_set_name then + error(val.keyset_name..": name of first key should be "..is_set_name) + elseif field.type ~= 'OptionalKeys' then + error("'"..is_set_name.."' must have type 'OptionalKeys'") + end + has_optional = true end - table.insert(keys, {field.name, field.type}) end - table.insert(keysets, {val.keyset_name, keys}) + table.insert(keysets, {name=val.keyset_name, keys=keys, types=types, has_optional=has_optional}) end -- read each input file, parse and append to the api metadata @@ -232,53 +246,60 @@ output:write([[ ]]) -for _,keyset in ipairs(keysets) do - local name, keys = unpack(keyset) - local special = {} - local function sanitize(key) - if special[key] then - return key .. "_" - end - return key - end +for _,k in ipairs(keysets) do + local c_name = {} - local key_names = {} - for i = 1,#keys do - local kname = keys[i][1] - if vim.endswith(kname, "_") then - kname = string.sub(kname,1, #kname - 1) - special[kname] = true + for i = 1,#k.keys do + -- some keys, like "register" are c keywords and get + -- escaped with a trailing _ in the struct. + if vim.endswith(k.keys[i], "_") then + local orig = k.keys[i] + k.keys[i] = string.sub(k.keys[i],1, #(k.keys[i]) - 1) + c_name[k.keys[i]] = orig + k.types[k.keys[i]] = k.types[orig] end - key_names[i] = kname end - local neworder, hashfun = hashy.hashy_hash(name, key_names, function (idx) - return name.."_table["..idx.."].str" + + local neworder, hashfun = hashy.hashy_hash(k.name, k.keys, function (idx) + return k.name.."_table["..idx.."].str" end) - keysets_defs:write("extern KeySetLink "..name.."_table[];\n") + keysets_defs:write("extern KeySetLink "..k.name.."_table[];\n") - output:write("KeySetLink "..name.."_table[] = {\n") - for _, key in ipairs(neworder) do - output:write(' {"'..key..'", offsetof(KeyDict_'..name..", "..sanitize(key)..")},\n") + local function typename(type) + if type ~= nil then + return "kObjectType"..type + else + return "kObjectTypeNil" + end + end + + output:write("KeySetLink "..k.name.."_table[] = {\n") + for i, key in ipairs(neworder) do + local ind = -1 + if k.has_optional then + ind = i + keysets_defs:write("#define KEYSET_OPTIDX_"..k.name.."__"..key.." "..ind.."\n") + end + output:write(' {"'..key..'", offsetof(KeyDict_'..k.name..", "..(c_name[key] or key).."), "..typename(k.types[key])..", "..ind.."},\n") end - output:write(' {NULL, 0},\n') + output:write(' {NULL, 0, kObjectTypeNil, -1},\n') output:write("};\n\n") output:write(hashfun) output:write([[ -Object *KeyDict_]]..name..[[_get_field(void *retval, const char *str, size_t len) +KeySetLink *KeyDict_]]..k.name..[[_get_field(const char *str, size_t len) { - int hash = ]]..name..[[_hash(str, len); + int hash = ]]..k.name..[[_hash(str, len); if (hash == -1) { return NULL; } - - return (Object *)((char *)retval + ]]..name..[[_table[hash].ptr_off); + return &]]..k.name..[[_table[hash]; } ]]) - keysets_defs:write("#define api_free_keydict_"..name.."(x) api_free_keydict(x, "..name.."_table)\n") + keysets_defs:write("#define api_free_keydict_"..k.name.."(x) api_free_keydict(x, "..k.name.."_table)\n") end local function real_type(type) @@ -666,7 +687,7 @@ local function process_function(fn) if (ERROR_SET(&err)) { luaL_where(lstate, 1); if (err_param) { - lua_pushstring(lstate, "param '"); + lua_pushstring(lstate, "Invalid '"); lua_pushstring(lstate, err_param); lua_pushstring(lstate, "': "); } |