diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-10-22 22:17:53 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-10-22 22:17:53 +0100 |
commit | 5fe07d2e08f05c6f3905fecdf07f4cfad4d6ed17 (patch) | |
tree | b722c70abe176a3daf37579d983efd95627f477b | |
parent | 841c225b9ef8c5bdf5e02968a0bd62521fff6ca8 (diff) | |
download | vim-git-5fe07d2e08f05c6f3905fecdf07f4cfad4d6ed17.tar.gz |
patch 8.2.3557: Vim9: cannot call imported funcref at script levelv8.2.3557
Problem: Vim9: cannot call imported funcref at script level.
Solution: Check for an imported function. (closes #9007)
-rw-r--r-- | src/testdir/test_vim9_script.vim | 27 | ||||
-rw-r--r-- | src/userfunc.c | 55 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 77 insertions, 7 deletions
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index b71978a3c..ae58a0bfe 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -1477,6 +1477,33 @@ def Test_vim9_import_export() delete('Xvim9_script') enddef +def Test_import_funcref() + var lines =<< trim END + vim9script + export def F(): number + return 42 + enddef + export const G = F + END + writefile(lines, 'Xlib.vim') + + lines =<< trim END + vim9script + import {G} from './Xlib.vim' + const Foo = G() + assert_equal(42, Foo) + + def DoTest() + const Goo = G() + assert_equal(42, Foo) + enddef + DoTest() + END + CheckScriptSuccess(lines) + + delete('Xlib.vim') +enddef + def Test_import_star_fails() writefile([], 'Xfoo.vim') var lines =<< trim END diff --git a/src/userfunc.c b/src/userfunc.c index ab441405c..978487112 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1548,9 +1548,11 @@ deref_func_name( int no_autoload) { dictitem_T *v; + typval_T *tv = NULL; int cc; char_u *s = NULL; hashtab_T *ht; + int did_type = FALSE; if (partialp != NULL) *partialp = NULL; @@ -1562,20 +1564,59 @@ deref_func_name( name[*lenp] = cc; if (v != NULL) { - if (v->di_tv.v_type == VAR_FUNC) + tv = &v->di_tv; + } + else if (in_vim9script() || STRNCMP(name, "s:", 2) == 0) + { + imported_T *import; + char_u *p = name; + int len = *lenp; + + if (STRNCMP(name, "s:", 2) == 0) + { + p = name + 2; + len -= 2; + } + import = find_imported(p, len, NULL); + + // imported variable from another script + if (import != NULL) + { + if (import->imp_funcname != NULL) + { + s = import->imp_funcname; + *lenp = (int)STRLEN(s); + return s; + } + // TODO: what if (import->imp_flags & IMP_FLAGS_STAR) + { + scriptitem_T *si = SCRIPT_ITEM(import->imp_sid); + svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + + import->imp_var_vals_idx; + tv = sv->sv_tv; + if (type != NULL) + *type = sv->sv_type; + did_type = TRUE; + } + } + } + + if (tv != NULL) + { + if (tv->v_type == VAR_FUNC) { - if (v->di_tv.vval.v_string == NULL) + if (tv->vval.v_string == NULL) { *lenp = 0; return (char_u *)""; // just in case } - s = v->di_tv.vval.v_string; + s = tv->vval.v_string; *lenp = (int)STRLEN(s); } - if (v->di_tv.v_type == VAR_PARTIAL) + if (tv->v_type == VAR_PARTIAL) { - partial_T *pt = v->di_tv.vval.v_partial; + partial_T *pt = tv->vval.v_partial; if (pt == NULL) { @@ -1590,9 +1631,9 @@ deref_func_name( if (s != NULL) { - if (type != NULL && ht == get_script_local_ht()) + if (!did_type && type != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(&v->di_tv); + svar_T *sv = find_typval_in_script(tv); if (sv != NULL) *type = sv->sv_type; diff --git a/src/version.c b/src/version.c index 362129eb2..ea396cd57 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3557, +/**/ 3556, /**/ 3555, |