aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/generators/gen_api_dispatch.lua
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-08-01 14:01:19 +0200
committerbfredl <bjorn.linse@gmail.com>2023-08-07 13:11:15 +0200
commit7bc93e0e2f246dd78026a3472d929a0fe450f70d (patch)
tree9e5b99830c3f08e0ffd75c7a0533b39033490a5b /src/nvim/generators/gen_api_dispatch.lua
parentc01e624b0762b24a4988bf9474a57d5b6278d180 (diff)
downloadrneovim-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.lua87
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, "': ");
}