0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.2.0729: Vim9: When reloading a script variables are not cleared

Problem:    Vim9: When reloading a script variables are not cleared.
Solution:   When sourcing a script again clear all script-local variables.
This commit is contained in:
Bram Moolenaar
2020-05-10 15:24:44 +02:00
parent 69212b11d1
commit 89483d4043
5 changed files with 57 additions and 20 deletions

View File

@@ -104,29 +104,38 @@ rettv_dict_set(typval_T *rettv, dict_T *d)
*/
void
dict_free_contents(dict_T *d)
{
hashtab_free_contents(&d->dv_hashtab);
}
/*
* Clear hashtab "ht" and dict items it contains.
*/
void
hashtab_free_contents(hashtab_T *ht)
{
int todo;
hashitem_T *hi;
dictitem_T *di;
// Lock the hashtab, we don't want it to resize while freeing items.
hash_lock(&d->dv_hashtab);
todo = (int)d->dv_hashtab.ht_used;
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
hash_lock(ht);
todo = (int)ht->ht_used;
for (hi = ht->ht_array; todo > 0; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
// Remove the item before deleting it, just in case there is
// something recursive causing trouble.
di = HI2DI(hi);
hash_remove(&d->dv_hashtab, hi);
hash_remove(ht, hi);
dictitem_free(di);
--todo;
}
}
// The hashtab is still locked, it has to be re-initialized anyway
hash_clear(&d->dv_hashtab);
// The hashtab is still locked, it has to be re-initialized anyway.
hash_clear(ht);
}
static void

View File

@@ -5,6 +5,7 @@ dict_T *dict_alloc_lock(int lock);
int rettv_dict_alloc(typval_T *rettv);
void rettv_dict_set(typval_T *rettv, dict_T *d);
void dict_free_contents(dict_T *d);
void hashtab_free_contents(hashtab_T *ht);
void dict_unref(dict_T *d);
int dict_free_nonref(int copyID);
void dict_free_items(int copyID);

View File

@@ -1295,9 +1295,6 @@ do_source(
if (sid > 0)
{
hashtab_T *ht;
hashitem_T *hi;
dictitem_T *di;
int todo;
int is_vim9 = si->sn_version == SCRIPT_VERSION_VIM9;
// loading the same script again
@@ -1306,7 +1303,14 @@ do_source(
current_sctx.sc_sid = sid;
ht = &SCRIPT_VARS(sid);
todo = (int)ht->ht_used;
if (is_vim9)
hashtab_free_contents(ht);
else
{
int todo = (int)ht->ht_used;
hashitem_T *hi;
dictitem_T *di;
for (hi = ht->ht_array; todo > 0; ++hi)
if (!HASHITEM_EMPTY(hi))
{
@@ -1314,6 +1318,7 @@ do_source(
di = HI2DI(hi);
di->di_flags |= DI_FLAGS_RELOAD;
}
}
// old imports are no longer valid
free_imports(sid);

View File

@@ -610,7 +610,6 @@ def Test_vim9_import_export()
let import_star_lines =<< trim END
vim9script
import * from './Xexport.vim'
g:imported = exported
END
writefile(import_star_lines, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1045:')
@@ -807,6 +806,28 @@ def Test_vim9script_reload_delfunc()
delete('Xreloaded.vim')
enddef
def Test_vim9script_reload_delvar()
# write the script with a script-local variable
let lines =<< trim END
vim9script
let var = 'string'
END
writefile(lines, 'XreloadVar.vim')
source XreloadVar.vim
# now write the script using the same variable locally - works
lines =<< trim END
vim9script
def Func()
let var = 'string'
enddef
END
writefile(lines, 'XreloadVar.vim')
source XreloadVar.vim
delete('XreloadVar.vim')
enddef
def Test_import_absolute()
let import_lines = [
'vim9script',
@@ -862,8 +883,7 @@ def Test_import_rtp()
unlet g:imported_rtp
delete('Ximport_rtp.vim')
delete('import/Xexport_rtp.vim')
delete('import', 'd')
delete('import', 'rf')
enddef
def Test_fixed_size_list()

View File

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