# HG changeset patch # User Bram Moolenaar # Date 1634938204 -7200 # Node ID f773ef3c641dc06d8e9b6869dada5091295225e5 # Parent f67fadf790b9ab12e096d1841418d5275cb83a88 patch 8.2.3557: Vim9: cannot call imported funcref at script level Commit: https://github.com/vim/vim/commit/5fe07d2e08f05c6f3905fecdf07f4cfad4d6ed17 Author: Bram Moolenaar Date: Fri Oct 22 22:17:53 2021 +0100 patch 8.2.3557: Vim9: cannot call imported funcref at script level Problem: Vim9: cannot call imported funcref at script level. Solution: Check for an imported function. (closes https://github.com/vim/vim/issues/9007) diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- 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 --- 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 (v->di_tv.vval.v_string == 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 (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 --- 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,