Mercurial > vim
changeset 27068:6a4fc2e6e6eb v8.2.4063
patch 8.2.4063: Vim9: exported function in autoload script not found
Commit: https://github.com/vim/vim/commit/b8822442d716df0230c79531132e530e95cc17e3
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 11 15:24:05 2022 +0000
patch 8.2.4063: Vim9: exported function in autoload script not found
Problem: Vim9: exported function in autoload script not found. (Yegappan
Lakshmanan)
Solution: Use the autoload prefix to search for the function.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 11 Jan 2022 16:30:03 +0100 |
parents | 89bc175b25a5 |
children | 940d27b64e91 |
files | src/testdir/test_vim9_import.vim src/userfunc.c src/version.c |
diffstat | 3 files changed, 56 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -1146,8 +1146,8 @@ def Test_vim9script_autoload() return 'test' enddef - export func GetSome() - return 'some' + export func GetMore() + return Gettest() .. 'more' endfunc export var name = 'name' @@ -1163,7 +1163,7 @@ def Test_vim9script_autoload() assert_equal('test', prefixed.Gettest()) assert_equal('yes', g:prefixed_loaded) - assert_equal('some', prefixed.GetSome()) + assert_equal('testmore', prefixed.GetMore()) assert_equal('name', prefixed.name) assert_equal('final', prefixed.fname) assert_equal('const', prefixed.cname) @@ -1173,7 +1173,7 @@ def Test_vim9script_autoload() # can also get the items by autoload name lines =<< trim END call assert_equal('test', prefixed#Gettest()) - call assert_equal('some', prefixed#GetSome()) + call assert_equal('testmore', prefixed#GetMore()) call assert_equal('name', prefixed#name) call assert_equal('final', prefixed#fname) call assert_equal('const', prefixed#cname)
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -1871,9 +1871,13 @@ fname_trans_sid(char_u *name, char_u *fn static ufunc_T * find_func_with_sid(char_u *name, int sid) { - hashitem_T *hi; - char_u buffer[200]; - + hashitem_T *hi; + char_u buffer[200]; + + if (!SCRIPT_ID_VALID(sid)) + return NULL; // not in a script + + // A script-local function is stored as "<SNR>99_name". buffer[0] = K_SPECIAL; buffer[1] = KS_EXTRA; buffer[2] = (int)KE_SNR; @@ -1882,6 +1886,46 @@ find_func_with_sid(char_u *name, int sid hi = hash_find(&func_hashtab, buffer); if (!HASHITEM_EMPTY(hi)) return HI2UF(hi); + return NULL; +} + +/* + * Find a function "name" in script "sid" prefixing the autoload prefix. + */ + static ufunc_T * +find_func_with_prefix(char_u *name, int sid) +{ + hashitem_T *hi; + char_u buffer[200]; + scriptitem_T *si; + + if (vim_strchr(name, AUTOLOAD_CHAR) != 0) + return NULL; // already has the prefix + if (!SCRIPT_ID_VALID(sid)) + return NULL; // not in a script + si = SCRIPT_ITEM(sid); + if (si->sn_autoload_prefix != NULL) + { + size_t len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1; + char_u *auto_name; + + // An exported function in an autoload script is stored as + // "dir#path#name". + if (len < sizeof(buffer)) + auto_name = buffer; + else + auto_name = alloc(len); + if (auto_name != NULL) + { + vim_snprintf((char *)auto_name, len, "%s%s", + si->sn_autoload_prefix, name); + hi = hash_find(&func_hashtab, auto_name); + if (auto_name != buffer) + vim_free(auto_name); + if (!HASHITEM_EMPTY(hi)) + return HI2UF(hi); + } + } return NULL; } @@ -1917,7 +1961,9 @@ find_func_even_dead(char_u *name, int is if (!HASHITEM_EMPTY(hi)) return HI2UF(hi); - return NULL; + // Find autoload function if this is an autoload script. + return find_func_with_prefix(name[0] == 's' && name[1] == ':' + ? name + 2 : name, current_sctx.sc_sid); } /*