summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-10-22 22:17:53 +0100
committerBram Moolenaar <Bram@vim.org>2021-10-22 22:17:53 +0100
commit5fe07d2e08f05c6f3905fecdf07f4cfad4d6ed17 (patch)
treeb722c70abe176a3daf37579d983efd95627f477b
parent841c225b9ef8c5bdf5e02968a0bd62521fff6ca8 (diff)
downloadvim-git-8.2.3557.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.vim27
-rw-r--r--src/userfunc.c55
-rw-r--r--src/version.c2
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,