0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 8.2.4446: Vim9: cannot refer to a global function like a local one

Problem:    Vim9: cannot refer to a global function like a local one.
Solution:   When g:name is not a variable but a function, use a function
            reference. (closes #9826)
This commit is contained in:
Bram Moolenaar 2022-02-22 19:39:13 +00:00
parent 29a9e69718
commit fe73255c92
3 changed files with 39 additions and 5 deletions

View File

@ -427,6 +427,21 @@ def Test_call_call()
call('reverse', [l]) call('reverse', [l])
l->assert_equal([1, 2, 3]) l->assert_equal([1, 2, 3])
var lines =<< trim END
vim9script
def Outer()
def g:Inner()
g:done = 'Inner'
enddef
call(g:Inner, [])
enddef
Outer()
assert_equal('Inner', g:done)
unlet g:done
END
v9.CheckScriptSuccess(lines)
delfunc g:Inner
v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1') v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1')
v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1') v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1')
v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2']) v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4446,
/**/ /**/
4445, 4445,
/**/ /**/

View File

@ -2333,16 +2333,33 @@ load_namespace_var(ectx_T *ectx, isntype_T isn_type, isn_T *iptr)
if (di == NULL) if (di == NULL)
{ {
if (isn_type == ISN_LOADG)
{
ufunc_T *ufunc = find_func(iptr->isn_arg.string, TRUE);
// g:Something could be a function
if (ufunc != NULL)
{
typval_T *tv = STACK_TV_BOT(0);
++ectx->ec_stack.ga_len;
tv->v_type = VAR_FUNC;
tv->vval.v_string = alloc(STRLEN(iptr->isn_arg.string) + 3);
if (tv->vval.v_string == NULL)
return FAIL;
STRCPY(tv->vval.v_string, "g:");
STRCPY(tv->vval.v_string + 2, iptr->isn_arg.string);
return OK;
}
}
SOURCING_LNUM = iptr->isn_lnum; SOURCING_LNUM = iptr->isn_lnum;
if (vim_strchr(iptr->isn_arg.string, if (vim_strchr(iptr->isn_arg.string, AUTOLOAD_CHAR) != NULL)
AUTOLOAD_CHAR) != NULL)
// no check if the item exists in the script but // no check if the item exists in the script but
// isn't exported, it is too complicated // isn't exported, it is too complicated
semsg(_(e_item_not_found_in_script_str), semsg(_(e_item_not_found_in_script_str), iptr->isn_arg.string);
iptr->isn_arg.string);
else else
semsg(_(e_undefined_variable_char_str), semsg(_(e_undefined_variable_char_str),
namespace, iptr->isn_arg.string); namespace, iptr->isn_arg.string);
return FAIL; return FAIL;
} }
else else