# HG changeset patch # User Bram Moolenaar # Date 1588021203 -7200 # Node ID 63cc54100ae431f758bdc30df2c791f6137c536b # Parent 085eb4da46f4f3cdc89671743b871a0e103d7fc1 patch 8.2.0650: Vim9: script function can be deleted Commit: https://github.com/vim/vim/commit/4c17ad94ecb0a0fb26d6fface2614bc5172dea18 Author: Bram Moolenaar Date: Mon Apr 27 22:47:51 2020 +0200 patch 8.2.0650: Vim9: script function can be deleted Problem: Vim9: script function can be deleted. Solution: Disallow deleting script function. Delete functions when sourcing a script again. diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2679,6 +2679,7 @@ common_function(typval_T *argvars, typva int use_string = FALSE; partial_T *arg_pt = NULL; char_u *trans_name = NULL; + int is_global = FALSE; if (argvars[0].v_type == VAR_FUNC) { @@ -2702,21 +2703,10 @@ common_function(typval_T *argvars, typva if ((use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL) || is_funcref) { name = s; - trans_name = trans_function_name(&name, FALSE, + trans_name = trans_function_name(&name, &is_global, FALSE, TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL, NULL); if (*name != NUL) s = NULL; - else if (trans_name != NULL - && ASCII_ISUPPER(*s) - && current_sctx.sc_version == SCRIPT_VERSION_VIM9 - && find_func(trans_name, NULL) == NULL) - { - // With Vim9 script "MyFunc" can be script-local to the current - // script or global. The script-local name is not found, assume - // global. - vim_free(trans_name); - trans_name = vim_strsave(s); - } } if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s)) @@ -2724,8 +2714,8 @@ common_function(typval_T *argvars, typva semsg(_(e_invarg2), use_string ? tv_get_string(&argvars[0]) : s); // Don't check an autoload name for existence here. else if (trans_name != NULL && (is_funcref - ? find_func(trans_name, NULL) == NULL - : !translated_function_exists(trans_name))) + ? find_func(trans_name, is_global, NULL) == NULL + : !translated_function_exists(trans_name, is_global))) semsg(_("E700: Unknown function: %s"), s); else { @@ -2862,7 +2852,7 @@ common_function(typval_T *argvars, typva } else if (is_funcref) { - pt->pt_func = find_func(trans_name, NULL); + pt->pt_func = find_func(trans_name, is_global, NULL); func_ptr_ref(pt->pt_func); vim_free(name); } diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro --- a/src/proto/userfunc.pro +++ b/src/proto/userfunc.pro @@ -7,11 +7,12 @@ char_u *deref_func_name(char_u *name, in void emsg_funcname(char *ermsg, char_u *name); int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe); char_u *fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error); -ufunc_T *find_func(char_u *name, cctx_T *cctx); +ufunc_T *find_func(char_u *name, int is_global, cctx_T *cctx); int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict); void save_funccal(funccal_entry_T *entry); void restore_funccal(void); funccall_T *get_current_funccal(void); +void delete_script_functions(int sid); void free_all_functions(void); int builtin_function(char_u *name, int len); int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv); @@ -19,11 +20,11 @@ int get_callback_depth(void); int call_callback(callback_T *callback, int len, typval_T *rettv, int argcount, typval_T *argvars); void user_func_error(int error, char_u *name); int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, funcexe_T *funcexe); -char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fdp, partial_T **partial); +char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial); char_u *untrans_function_name(char_u *name); void ex_function(exarg_T *eap); int eval_fname_script(char_u *p); -int translated_function_exists(char_u *name); +int translated_function_exists(char_u *name, int is_global); int has_varargs(ufunc_T *ufunc); int function_exists(char_u *name, int no_deref); char_u *get_expanded_name(char_u *name, int check); diff --git a/src/scriptfile.c b/src/scriptfile.c --- a/src/scriptfile.c +++ b/src/scriptfile.c @@ -1275,6 +1275,7 @@ do_source( hashitem_T *hi; dictitem_T *di; int todo; + int is_vim9 = si->sn_version == SCRIPT_VERSION_VIM9; // loading the same script again si->sn_had_command = FALSE; @@ -1293,6 +1294,10 @@ do_source( // old imports are no longer valid free_imports(sid); + + // in Vim9 script functions are marked deleted + if (is_vim9) + delete_script_functions(sid); } else { diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -207,12 +207,12 @@ def Test_expr4_equal() assert_equal(true, g:adict == #{bbb: 8, aaa: 2}) assert_equal(false, #{ccc: 9, aaa: 2} == g:adict) - assert_equal(true, function('Test_expr4_equal') == function('Test_expr4_equal')) - assert_equal(false, function('Test_expr4_equal') == function('Test_expr4_is')) + assert_equal(true, function('g:Test_expr4_equal') == function('g:Test_expr4_equal')) + assert_equal(false, function('g:Test_expr4_equal') == function('g:Test_expr4_is')) - assert_equal(true, function('Test_expr4_equal', [123]) == function('Test_expr4_equal', [123])) - assert_equal(false, function('Test_expr4_equal', [123]) == function('Test_expr4_is', [123])) - assert_equal(false, function('Test_expr4_equal', [123]) == function('Test_expr4_equal', [999])) + assert_equal(true, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [123])) + assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_is', [123])) + assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [999])) enddef " test != comperator @@ -274,12 +274,12 @@ def Test_expr4_notequal() assert_equal(false, g:adict != #{bbb: 8, aaa: 2}) assert_equal(true, #{ccc: 9, aaa: 2} != g:adict) - assert_equal(false, function('Test_expr4_equal') != function('Test_expr4_equal')) - assert_equal(true, function('Test_expr4_equal') != function('Test_expr4_is')) + assert_equal(false, function('g:Test_expr4_equal') != function('g:Test_expr4_equal')) + assert_equal(true, function('g:Test_expr4_equal') != function('g:Test_expr4_is')) - assert_equal(false, function('Test_expr4_equal', [123]) != function('Test_expr4_equal', [123])) - assert_equal(true, function('Test_expr4_equal', [123]) != function('Test_expr4_is', [123])) - assert_equal(true, function('Test_expr4_equal', [123]) != function('Test_expr4_equal', [999])) + assert_equal(false, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [123])) + assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_is', [123])) + assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [999])) enddef " test > comperator @@ -929,15 +929,15 @@ endfunc def Test_expr7_trailing() " user function call - assert_equal(123, CallMe(123)) - assert_equal(123, CallMe( 123)) - assert_equal(123, CallMe(123 )) - assert_equal('yesno', CallMe2('yes', 'no')) - assert_equal('yesno', CallMe2( 'yes', 'no' )) - assert_equal('nothing', CallMe('nothing')) + assert_equal(123, g:CallMe(123)) + assert_equal(123, g:CallMe( 123)) + assert_equal(123, g:CallMe(123 )) + assert_equal('yesno', g:CallMe2('yes', 'no')) + assert_equal('yesno', g:CallMe2( 'yes', 'no' )) + assert_equal('nothing', g:CallMe('nothing')) " partial call - let Part = function('CallMe') + let Part = function('g:CallMe') assert_equal('yes', Part('yes')) " funcref call, using list index diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -353,7 +353,7 @@ endfunc def Test_delfunc() let lines =<< trim END vim9script - def GoneSoon() + def g:GoneSoon() echo 'hello' enddef @@ -361,7 +361,7 @@ def Test_delfunc() GoneSoon() enddef - delfunc GoneSoon + delfunc g:GoneSoon CallGoneSoon() END writefile(lines, 'XToDelFunc') 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 @@ -53,7 +53,7 @@ def Test_assignment() endif let Funky1: func let Funky2: func = function('len') - let Party2: func = funcref('Test_syntax') + let Party2: func = funcref('g:Test_syntax') # type becomes list let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] @@ -282,6 +282,49 @@ def Test_unlet() assert_equal('', $ENVVAR) enddef +def Test_delfunction() + " Check function is defined in script namespace + CheckScriptSuccess([ + 'vim9script', + 'func CheckMe()', + ' return 123', + 'endfunc', + 'assert_equal(123, s:CheckMe())', + ]) + + " Check function in script namespace cannot be deleted + CheckScriptFailure([ + 'vim9script', + 'func DeleteMe1()', + 'endfunc', + 'delfunction DeleteMe1', + ], 'E1084:') + CheckScriptFailure([ + 'vim9script', + 'func DeleteMe2()', + 'endfunc', + 'def DoThat()', + ' delfunction DeleteMe2', + 'enddef', + 'DoThat()', + ], 'E1084:') + CheckScriptFailure([ + 'vim9script', + 'def DeleteMe3()', + 'enddef', + 'delfunction DeleteMe3', + ], 'E1084:') + CheckScriptFailure([ + 'vim9script', + 'def DeleteMe4()', + 'enddef', + 'def DoThat()', + ' delfunction DeleteMe4', + 'enddef', + 'DoThat()', + ], 'E1084:') +enddef + func Test_wrong_type() call CheckDefFailure(['let var: list'], 'E1010:') call CheckDefFailure(['let var: list>'], 'E1010:') @@ -649,7 +692,7 @@ def Test_vim9script_fails() assert_fails('export something', 'E1043') enddef -def Test_vim9script_reload() +def Test_vim9script_reload_import() let lines =<< trim END vim9script const var = '' @@ -700,6 +743,47 @@ def Test_vim9script_reload() delete('Ximport.vim') enddef +def Test_vim9script_reload_delfunc() + let first_lines =<< trim END + vim9script + def FuncYes(): string + return 'yes' + enddef + END + let middle_lines =<< trim END + def FuncNo(): string + return 'no' + enddef + END + let final_lines =<< trim END + def g:DoCheck(no_exists: bool) + assert_equal('yes', FuncYes()) + if no_exists + assert_equal('no', FuncNo()) + else + assert_fails('call FuncNo()', 'E117:') + endif + enddef + END + + # FuncNo() is defined + writefile(first_lines + middle_lines + final_lines, 'Xreloaded.vim') + source Xreloaded.vim + g:DoCheck(true) + + # FuncNo() is not redefined + writefile(first_lines + final_lines, 'Xreloaded.vim') + source Xreloaded.vim + g:DoCheck(false) + + # FuncNo() is back + writefile(first_lines + middle_lines + final_lines, 'Xreloaded.vim') + source Xreloaded.vim + g:DoCheck(true) + + delete('Xreloaded.vim') +enddef + def Test_import_absolute() let import_lines = [ 'vim9script', @@ -1445,15 +1529,15 @@ def Test_vim9_comment() CheckScriptSuccess([ 'vim9script', - 'func DeleteMe()', + 'func g:DeleteMeA()', 'endfunc', - 'delfunction DeleteMe # comment', + 'delfunction g:DeleteMeA # comment', ]) CheckScriptFailure([ 'vim9script', - 'func DeleteMe()', + 'func g:DeleteMeB()', 'endfunc', - 'delfunction DeleteMe# comment', + 'delfunction g:DeleteMeB# comment', ], 'E488:') CheckScriptSuccess([ diff --git a/src/testing.c b/src/testing.c --- a/src/testing.c +++ b/src/testing.c @@ -789,7 +789,7 @@ f_test_refcount(typval_T *argvars, typva { ufunc_T *fp; - fp = find_func(argvars[0].vval.v_string, NULL); + fp = find_func(argvars[0].vval.v_string, FALSE, NULL); if (fp != NULL) retval = fp->uf_refcount; } diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -25,6 +25,7 @@ #define FC_DEAD 0x80 // function kept only for reference to dfunc #define FC_EXPORT 0x100 // "export def Func()" #define FC_NOARGS 0x200 // no a: variables in lambda +#define FC_VIM9 0x400 // defined in vim9 script file /* * All user-defined functions are found in this hashtable. @@ -710,16 +711,17 @@ find_func_with_sid(char_u *name, int sid /* * Find a function by name, return pointer to it in ufuncs. + * When "is_global" is true don't find script-local or imported functions. * Return NULL for unknown function. */ static ufunc_T * -find_func_even_dead(char_u *name, cctx_T *cctx) +find_func_even_dead(char_u *name, int is_global, cctx_T *cctx) { hashitem_T *hi; ufunc_T *func; imported_T *imported; - if (in_vim9script()) + if (in_vim9script() && !is_global) { // Find script-local function before global one. func = find_func_with_sid(name, current_sctx.sc_sid); @@ -750,9 +752,9 @@ find_func_even_dead(char_u *name, cctx_T * Return NULL for unknown or dead function. */ ufunc_T * -find_func(char_u *name, cctx_T *cctx) +find_func(char_u *name, int is_global, cctx_T *cctx) { - ufunc_T *fp = find_func_even_dead(name, cctx); + ufunc_T *fp = find_func_even_dead(name, is_global, cctx); if (fp != NULL && (fp->uf_flags & FC_DEAD) == 0) return fp; @@ -1575,6 +1577,38 @@ get_current_funccal(void) return current_funccal; } +/* + * Mark all functions of script "sid" as deleted. + */ + void +delete_script_functions(int sid) +{ + hashitem_T *hi; + ufunc_T *fp; + long_u todo; + char buf[30]; + size_t len; + + buf[0] = K_SPECIAL; + buf[1] = KS_EXTRA; + buf[2] = (int)KE_SNR; + sprintf(buf + 3, "%d_", sid); + len = STRLEN(buf); + + todo = func_hashtab.ht_used; + for (hi = func_hashtab.ht_array; todo > 0; ++hi) + if (!HASHITEM_EMPTY(hi)) + { + if (STRNCMP(fp->uf_name, buf, len) == 0) + { + fp = HI2UF(hi); + fp->uf_flags |= FC_DEAD; + func_clear(fp, TRUE); + } + --todo; + } +} + #if defined(EXITFREE) || defined(PROTO) void free_all_functions(void) @@ -1884,22 +1918,22 @@ call_func( * User defined function. */ if (fp == NULL) - fp = find_func(rfname, NULL); + fp = find_func(rfname, FALSE, NULL); // Trigger FuncUndefined event, may load the function. if (fp == NULL && apply_autocmds(EVENT_FUNCUNDEFINED, - rfname, rfname, TRUE, NULL) + rfname, rfname, TRUE, NULL) && !aborting()) { // executed an autocommand, search for the function again - fp = find_func(rfname, NULL); + fp = find_func(rfname, FALSE, NULL); } // Try loading a package. if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) { // loaded a package, search for the function again - fp = find_func(rfname, NULL); + fp = find_func(rfname, FALSE, NULL); } if (fp == NULL) { @@ -1908,7 +1942,7 @@ call_func( // If using Vim9 script try not local to the script. // TODO: should not do this if the name started with "s:". if (p != NULL) - fp = find_func(p, NULL); + fp = find_func(p, FALSE, NULL); } if (fp != NULL && (fp->uf_flags & FC_DELETED)) @@ -2079,6 +2113,8 @@ list_func_head(ufunc_T *fp, int indent) * Get a function name, translating "" and "". * Also handles a Funcref in a List or Dictionary. * Returns the function name in allocated memory, or NULL for failure. + * Set "*is_global" to TRUE when the function must be global, unless + * "is_global" is NULL. * flags: * TFN_INT: internal function name OK * TFN_QUIET: be quiet @@ -2089,6 +2125,7 @@ list_func_head(ufunc_T *fp, int indent) char_u * trans_function_name( char_u **pp, + int *is_global, int skip, // only find the end, don't evaluate int flags, funcdict_T *fdp, // return: info about dictionary used @@ -2239,7 +2276,11 @@ trans_function_name( { // skip over "s:" and "g:" if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':')) + { + if (is_global != NULL && lv.ll_name[0] == 'g') + *is_global = TRUE; lv.ll_name += 2; + } len = (int)(end - lv.ll_name); } @@ -2347,6 +2388,7 @@ ex_function(exarg_T *eap) int saved_did_emsg; int saved_wait_return = need_wait_return; char_u *name = NULL; + int is_global = FALSE; char_u *p; char_u *arg; char_u *line_arg = NULL; @@ -2463,7 +2505,8 @@ ex_function(exarg_T *eap) * g:func global function name, same as "func" */ p = eap->arg; - name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); + name = trans_function_name(&p, &is_global, eap->skip, + TFN_NO_AUTOLOAD, &fudi, NULL); paren = (vim_strchr(p, '(') != NULL); if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) { @@ -2503,7 +2546,7 @@ ex_function(exarg_T *eap) *p = NUL; if (!eap->skip && !got_int) { - fp = find_func(name, NULL); + fp = find_func(name, is_global, NULL); if (fp == NULL && ASCII_ISUPPER(*eap->arg)) { char_u *up = untrans_function_name(name); @@ -2511,7 +2554,7 @@ ex_function(exarg_T *eap) // With Vim9 script the name was made script-local, if not // found try again with the original name. if (up != NULL) - fp = find_func(up, NULL); + fp = find_func(up, FALSE, NULL); } if (fp != NULL) @@ -2675,7 +2718,7 @@ ex_function(exarg_T *eap) { if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) emsg(_(e_funcdict)); - else if (name != NULL && find_func(name, NULL) != NULL) + else if (name != NULL && find_func(name, is_global, NULL) != NULL) emsg_funcname(e_funcexts, name); } @@ -2825,7 +2868,7 @@ ex_function(exarg_T *eap) if (*p == '!') p = skipwhite(p + 1); p += eval_fname_script(p); - vim_free(trans_function_name(&p, TRUE, 0, NULL, NULL)); + vim_free(trans_function_name(&p, NULL, TRUE, 0, NULL, NULL)); if (*skipwhite(p) == '(') { if (nesting == MAX_FUNC_NESTING - 1) @@ -2963,7 +3006,7 @@ ex_function(exarg_T *eap) goto erret; } - fp = find_func_even_dead(name, NULL); + fp = find_func_even_dead(name, is_global, NULL); if (fp != NULL) { int dead = fp->uf_flags & FC_DEAD; @@ -3208,6 +3251,8 @@ ex_function(exarg_T *eap) fp->uf_varargs = varargs; if (sandbox) flags |= FC_SANDBOX; + if (in_vim9script() && !ASCII_ISUPPER(*fp->uf_name)) + flags |= FC_VIM9; fp->uf_flags = flags; fp->uf_calls = 0; fp->uf_cleared = FALSE; @@ -3261,11 +3306,11 @@ eval_fname_script(char_u *p) } int -translated_function_exists(char_u *name) +translated_function_exists(char_u *name, int is_global) { if (builtin_function(name, -1)) return has_internal_func(name); - return find_func(name, NULL) != NULL; + return find_func(name, is_global, NULL) != NULL; } /* @@ -3289,17 +3334,18 @@ function_exists(char_u *name, int no_der char_u *p; int n = FALSE; int flag; + int is_global = FALSE; flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD; if (no_deref) flag |= TFN_NO_DEREF; - p = trans_function_name(&nm, FALSE, flag, NULL, NULL); + p = trans_function_name(&nm, &is_global, FALSE, flag, NULL, NULL); nm = skipwhite(nm); // Only accept "funcname", "funcname ", "funcname (..." and // "funcname(...", not "funcname!...". if (p != NULL && (*nm == NUL || *nm == '(')) - n = translated_function_exists(p); + n = translated_function_exists(p, is_global); vim_free(p); return n; } @@ -3310,12 +3356,14 @@ get_expanded_name(char_u *name, int chec { char_u *nm = name; char_u *p; - - p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL, NULL); - - if (p != NULL && *nm == NUL) - if (!check || translated_function_exists(p)) - return p; + int is_global = FALSE; + + p = trans_function_name(&nm, &is_global, FALSE, + TFN_INT|TFN_QUIET, NULL, NULL); + + if (p != NULL && *nm == NUL + && (!check || translated_function_exists(p, is_global))) + return p; vim_free(p); return NULL; @@ -3376,9 +3424,10 @@ ex_delfunction(exarg_T *eap) char_u *p; char_u *name; funcdict_T fudi; + int is_global = FALSE; p = eap->arg; - name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); + name = trans_function_name(&p, &is_global, eap->skip, 0, &fudi, NULL); vim_free(fudi.fd_newkey); if (name == NULL) { @@ -3397,7 +3446,7 @@ ex_delfunction(exarg_T *eap) *p = NUL; if (!eap->skip) - fp = find_func(name, NULL); + fp = find_func(name, is_global, NULL); vim_free(name); if (!eap->skip) @@ -3413,6 +3462,11 @@ ex_delfunction(exarg_T *eap) semsg(_("E131: Cannot delete function %s: It is in use"), eap->arg); return; } + if (fp->uf_flags & FC_VIM9) + { + semsg(_("E1084: Cannot delete Vim9 script function %s"), eap->arg); + return; + } if (fudi.fd_dict != NULL) { @@ -3452,7 +3506,7 @@ func_unref(char_u *name) if (name == NULL || !func_name_refcount(name)) return; - fp = find_func(name, NULL); + fp = find_func(name, FALSE, NULL); if (fp == NULL && isdigit(*name)) { #ifdef EXITFREE @@ -3495,7 +3549,7 @@ func_ref(char_u *name) if (name == NULL || !func_name_refcount(name)) return; - fp = find_func(name, NULL); + fp = find_func(name, FALSE, NULL); if (fp != NULL) ++fp->uf_refcount; else if (isdigit(*name)) @@ -3611,7 +3665,8 @@ ex_call(exarg_T *eap) return; } - tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial); + tofree = trans_function_name(&arg, NULL, eap->skip, + TFN_INT, &fudi, &partial); if (fudi.fd_newkey != NULL) { // Still need to give an error message for missing key. @@ -3969,7 +4024,7 @@ make_partial(dict_T *selfdict_in, typval : rettv->vval.v_partial->pt_name; // Translate "s:func" to the stored function name. fname = fname_trans_sid(fname, fname_buf, &tofree, &error); - fp = find_func(fname, NULL); + fp = find_func(fname, FALSE, NULL); vim_free(tofree); } @@ -4391,7 +4446,7 @@ set_ref_in_func(char_u *name, ufunc_T *f if (fp_in == NULL) { fname = fname_trans_sid(name, fname_buf, &tofree, &error); - fp = find_func(fname, NULL); + fp = find_func(fname, FALSE, NULL); } if (fp != NULL) { diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 650, +/**/ 649, /**/ 648, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2210,7 +2210,7 @@ compile_load_scriptvar( static int generate_funcref(cctx_T *cctx, char_u *name) { - ufunc_T *ufunc = find_func(name, cctx); + ufunc_T *ufunc = find_func(name, FALSE, cctx); if (ufunc == NULL) return FAIL; @@ -2452,7 +2452,7 @@ compile_call(char_u **arg, size_t varlen } // If we can find the function by name generate the right call. - ufunc = find_func(name, cctx); + ufunc = find_func(name, FALSE, cctx); if (ufunc != NULL) { res = generate_CALL(cctx, ufunc, argcount); diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -400,7 +400,7 @@ call_by_name(char_u *name, int argcount, return call_bfunc(func_idx, argcount, ectx); } - ufunc = find_func(name, NULL); + ufunc = find_func(name, FALSE, NULL); if (ufunc != NULL) return call_ufunc(ufunc, argcount, ectx, iptr); @@ -1944,8 +1944,9 @@ ex_disassemble(exarg_T *eap) int current; int line_idx = 0; int prev_current = 0; + int is_global = FALSE; - fname = trans_function_name(&arg, FALSE, + fname = trans_function_name(&arg, &is_global, FALSE, TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL, NULL); if (fname == NULL) { @@ -1953,14 +1954,14 @@ ex_disassemble(exarg_T *eap) return; } - ufunc = find_func(fname, NULL); + ufunc = find_func(fname, is_global, NULL); if (ufunc == NULL) { char_u *p = untrans_function_name(fname); if (p != NULL) // Try again without making it script-local. - ufunc = find_func(p, NULL); + ufunc = find_func(p, FALSE, NULL); } vim_free(fname); if (ufunc == NULL) diff --git a/src/vim9script.c b/src/vim9script.c --- a/src/vim9script.c +++ b/src/vim9script.c @@ -217,7 +217,7 @@ find_exported( funcname[1] = KS_EXTRA; funcname[2] = (int)KE_SNR; sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); - *ufunc = find_func(funcname, NULL); + *ufunc = find_func(funcname, FALSE, NULL); if (funcname != buffer) vim_free(funcname);