From f9dd6826210335d8b37455002d767d1b37c09ce4 Mon Sep 17 00:00:00 2001 From: Colin Kennedy Date: Wed, 11 Dec 2024 01:01:14 -0800 Subject: [PATCH] docs(annotations): added `---@generic` support --- runtime/doc/builtin.txt | 24 ++++++++++++------------ runtime/lua/vim/_meta/vimfn.lua | 29 +++++++++++++++++------------ scripts/gen_eval_files.lua | 4 ++++ src/nvim/eval.lua | 29 ++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 31 deletions(-) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 398947a31f..5f74080e0c 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -1305,10 +1305,10 @@ copy({expr}) *copy()* Also see |deepcopy()|. Parameters: ~ - • {expr} (`any`) + • {expr} (`T`) Return: ~ - (`any`) + (`T`) cos({expr}) *cos()* Return the cosine of {expr}, measured in radians, as a |Float|. @@ -1490,11 +1490,11 @@ deepcopy({expr} [, {noref}]) *deepcopy()* *E69 Also see |copy()|. Parameters: ~ - • {expr} (`any`) + • {expr} (`T`) • {noref} (`boolean?`) Return: ~ - (`any`) + (`T`) delete({fname} [, {flags}]) *delete()* Without {flags} or with {flags} empty: Deletes the file by the @@ -5281,7 +5281,7 @@ items({dict}) *items()* the index. Parameters: ~ - • {dict} (`any`) + • {dict} (`table`) Return: ~ (`any`) @@ -6567,7 +6567,7 @@ max({expr}) *max()* • {expr} (`any`) Return: ~ - (`any`) + (`number`) menu_get({path} [, {modes}]) *menu_get()* Returns a |List| of |Dictionaries| describing |menus| (defined @@ -7733,11 +7733,11 @@ reduce({object}, {func} [, {initial}]) *reduce()* *E99 Parameters: ~ • {object} (`any`) - • {func} (`function`) + • {func} (`fun(accumulator: T, current: any): any`) • {initial} (`any?`) Return: ~ - (`any`) + (`T`) reg_executing() *reg_executing()* Returns the single letter name of the register being executed. @@ -7951,10 +7951,10 @@ reverse({object}) *reverse()* < Parameters: ~ - • {object} (`any`) + • {object} (`T[]`) Return: ~ - (`any`) + (`T[]`) round({expr}) *round()* Round off {expr} to the nearest integral value and return it @@ -9952,12 +9952,12 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E70 < Parameters: ~ - • {list} (`any`) + • {list} (`T[]`) • {how} (`string|function?`) • {dict} (`any?`) Return: ~ - (`any`) + (`T[]`) soundfold({word}) *soundfold()* Return the sound-folded equivalent of {word}. Uses the first diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 77c78f03d4..cf1beda15f 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -1147,8 +1147,9 @@ function vim.fn.confirm(msg, choices, default, type) end --- A |Dictionary| is copied in a similar way as a |List|. --- Also see |deepcopy()|. --- ---- @param expr any ---- @return any +--- @generic T +--- @param expr T +--- @return T function vim.fn.copy(expr) end --- Return the cosine of {expr}, measured in radians, as a |Float|. @@ -1308,9 +1309,10 @@ function vim.fn.debugbreak(pid) end --- {noref} set to 1 will fail. --- Also see |copy()|. --- ---- @param expr any +--- @generic T +--- @param expr T --- @param noref? boolean ---- @return any +--- @return T function vim.fn.deepcopy(expr, noref) end --- Without {flags} or with {flags} empty: Deletes the file by the @@ -4769,7 +4771,7 @@ function vim.fn.isnan(expr) end --- cases, items() returns a List with the index and the value at --- the index. --- ---- @param dict any +--- @param dict table --- @return any function vim.fn.items(dict) end @@ -5952,7 +5954,7 @@ function vim.fn.matchstrpos(expr, pat, start, count) end --- an error. An empty |List| or |Dictionary| results in zero. --- --- @param expr any ---- @return any +--- @return number function vim.fn.max(expr) end --- Returns a |List| of |Dictionaries| describing |menus| (defined @@ -7016,10 +7018,11 @@ function vim.fn.readfile(fname, type, max) end --- echo reduce('xyz', { acc, val -> acc .. ',' .. val }) --- < --- +--- @generic T --- @param object any ---- @param func function +--- @param func fun(accumulator: T, current: any): any --- @param initial? any ---- @return any +--- @return T function vim.fn.reduce(object, func, initial) end --- Returns the single letter name of the register being executed. @@ -7215,8 +7218,9 @@ function vim.fn.resolve(filename) end --- let revlist = reverse(copy(mylist)) --- < --- ---- @param object any ---- @return any +--- @generic T +--- @param object T[] +--- @return T[] function vim.fn.reverse(object) end --- Round off {expr} to the nearest integral value and return it @@ -9079,10 +9083,11 @@ function vim.fn.sockconnect(mode, address, opts) end --- eval mylist->sort({i1, i2 -> i1 - i2}) --- < --- ---- @param list any +--- @generic T +--- @param list T[] --- @param how? string|function --- @param dict? any ---- @return any +--- @return T[] function vim.fn.sort(list, how, dict) end --- Return the sound-folded equivalent of {word}. Uses the first diff --git a/scripts/gen_eval_files.lua b/scripts/gen_eval_files.lua index de9df5054f..0970ae503a 100755 --- a/scripts/gen_eval_files.lua +++ b/scripts/gen_eval_files.lua @@ -496,6 +496,10 @@ local function render_eval_meta(f, fun, write) end end + for _, text in ipairs(vim.fn.reverse(fun.generics or {})) do + write(fmt('--- @generic %s', text)) + end + local req_args = type(fun.args) == 'table' and fun.args[1] or fun.args or 0 for i, param in ipairs(params) do diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index cf80a26e1c..9de189cc16 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -17,6 +17,7 @@ --- @field deprecated? true --- @field returns? string|false --- @field returns_desc? string +--- @field generics? string[] Used to write `---@generic` annotations over a function. --- @field signature? string --- @field desc? string --- @field params [string, string, string][] @@ -1521,9 +1522,10 @@ M.funcs = { A |Dictionary| is copied in a similar way as a |List|. Also see |deepcopy()|. ]=], + generics = { 'T' }, name = 'copy', - params = { { 'expr', 'any' } }, - returns = 'any', + params = { { 'expr', 'T' } }, + returns = 'T', signature = 'copy({expr})', }, cos = { @@ -1739,8 +1741,10 @@ M.funcs = { Also see |copy()|. ]=], + generics = { 'T' }, name = 'deepcopy', - params = { { 'expr', 'any' }, { 'noref', 'boolean' } }, + params = { { 'expr', 'T' }, { 'noref', 'boolean' } }, + returns = 'T', signature = 'deepcopy({expr} [, {noref}])', }, delete = { @@ -5894,7 +5898,7 @@ M.funcs = { the index. ]=], name = 'items', - params = { { 'dict', 'any' } }, + params = { { 'dict', 'table' } }, signature = 'items({dict})', }, jobclose = { @@ -7309,6 +7313,7 @@ M.funcs = { ]=], name = 'max', params = { { 'expr', 'any' } }, + returns = 'number', signature = 'max({expr})', }, menu_get = { @@ -8520,7 +8525,13 @@ M.funcs = { < ]=], name = 'reduce', - params = { { 'object', 'any' }, { 'func', 'function' }, { 'initial', 'any' } }, + generics = { 'T' }, + params = { + { 'object', 'any' }, + { 'func', 'fun(accumulator: T, current: any): any' }, + { 'initial', 'any' }, + }, + returns = 'T', signature = 'reduce({object}, {func} [, {initial}])', }, reg_executing = { @@ -8785,7 +8796,9 @@ M.funcs = { < ]=], name = 'reverse', - params = { { 'object', 'any' } }, + generics = { 'T' }, + params = { { 'object', 'T[]' } }, + returns = 'T[]', signature = 'reverse({object})', }, round = { @@ -10924,7 +10937,9 @@ M.funcs = { < ]=], name = 'sort', - params = { { 'list', 'any' }, { 'how', 'string|function' }, { 'dict', 'any' } }, + generics = { 'T' }, + params = { { 'list', 'T[]' }, { 'how', 'string|function' }, { 'dict', 'any' } }, + returns = 'T[]', signature = 'sort({list} [, {how} [, {dict}]])', }, soundfold = {