Mercurial > vim
diff src/vim9script.c @ 22596:107eae953b87 v8.2.1846
patch 8.2.1846: Vim9: block variables are not found in compiled function
Commit: https://github.com/vim/vim/commit/fbbcd00367e1a4fafd047d42ffce0e5dce88925c
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Oct 15 12:46:44 2020 +0200
patch 8.2.1846: Vim9: block variables are not found in compiled function
Problem: Vim9: variables declared in a local block are not found in
when a function is compiled.
Solution: Look for script variables in sn_all_vars.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 15 Oct 2020 13:00:05 +0200 |
parents | 209c7aa56325 |
children | 71b57779177d |
line wrap: on
line diff
--- a/src/vim9script.c +++ b/src/vim9script.c @@ -193,7 +193,8 @@ find_exported( int sid, char_u *name, ufunc_T **ufunc, - type_T **type) + type_T **type, + cctx_T *cctx) { int idx = -1; svar_T *sv; @@ -201,7 +202,7 @@ find_exported( // find name in "script" // TODO: also find script-local user function - idx = get_script_item_idx(sid, name, FALSE); + idx = get_script_item_idx(sid, name, FALSE, cctx); if (idx >= 0) { sv = ((svar_T *)script->sn_var_vals.ga_data) + idx; @@ -248,6 +249,7 @@ find_exported( /* * Handle an ":import" command and add the resulting imported_T to "gap", when * not NULL, or script "import_sid" sn_imports. + * "cctx" is NULL at the script level. * Returns a pointer to after the command or NULL in case of failure */ char_u * @@ -461,7 +463,7 @@ handle_import( ufunc_T *ufunc = NULL; type_T *type; - idx = find_exported(sid, name, &ufunc, &type); + idx = find_exported(sid, name, &ufunc, &type, cctx); if (idx < 0 && ufunc == NULL) goto erret; @@ -623,9 +625,14 @@ add_vim9_script_var(dictitem_T *di, typv } } +/* + * Hide a script variable when leaving a block. + * "idx" is de index in sn_var_vals. + */ void -hide_script_var(scriptitem_T *si, svar_T *sv) +hide_script_var(scriptitem_T *si, int idx) { + svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; hashtab_T *script_ht = get_script_local_ht(); hashtab_T *all_ht = &si->sn_all_vars.dv_hashtab; hashitem_T *script_hi; @@ -640,11 +647,19 @@ hide_script_var(scriptitem_T *si, svar_T dictitem_T *di = HI2DI(script_hi); sallvar_T *sav = HI2SAV(all_hi); - sav->sav_tv = di->di_tv; - di->di_tv.v_type = VAR_UNKNOWN; - sav->sav_flags = di->di_flags; - sav->sav_di = NULL; - delete_var(script_ht, script_hi); + // There can be multiple entries with the same name in different + // blocks, find the right one. + while (sav != NULL && sav->sav_var_vals_idx != idx) + sav = sav->sav_next; + if (sav != NULL) + { + sav->sav_tv = di->di_tv; + di->di_tv.v_type = VAR_UNKNOWN; + sav->sav_flags = di->di_flags; + sav->sav_di = NULL; + delete_var(script_ht, script_hi); + sv->sv_tv = &sav->sav_tv; + } } }