# HG changeset patch # User Bram Moolenaar # Date 1641915003 -3600 # Node ID 6a4fc2e6e6eb92aab56e6096639476068fceb496 # Parent 89bc175b25a575ae81fffbe0304285dab738144a patch 8.2.4063: Vim9: exported function in autoload script not found Commit: https://github.com/vim/vim/commit/b8822442d716df0230c79531132e530e95cc17e3 Author: Bram Moolenaar 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. diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim --- 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) diff --git a/src/userfunc.c b/src/userfunc.c --- 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 "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); } /* diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4063, +/**/ 4062, /**/ 4061,