diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-10-15 12:46:44 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-10-15 12:46:44 +0200 |
commit | fbbcd00367e1a4fafd047d42ffce0e5dce88925c (patch) | |
tree | 93f997f2b6fad6457ff728399b8be9da35ad1ead /src/vim9script.c | |
parent | 8d739de43b84ef7817b3b5b826d1cbfe7572a62a (diff) | |
download | vim-git-fbbcd00367e1a4fafd047d42ffce0e5dce88925c.tar.gz |
patch 8.2.1846: Vim9: block variables are not found in compiled functionv8.2.1846
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.
Diffstat (limited to 'src/vim9script.c')
-rw-r--r-- | src/vim9script.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/vim9script.c b/src/vim9script.c index a60fbdd21..a6ed4ba79 100644 --- 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, typval_T *tv, type_T *type) } } +/* + * 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 *sv) 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; + } } } |