forked from aniani/vim
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:
21
src/dict.c
21
src/dict.c
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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,14 +1303,22 @@ do_source(
|
||||
current_sctx.sc_sid = sid;
|
||||
|
||||
ht = &SCRIPT_VARS(sid);
|
||||
todo = (int)ht->ht_used;
|
||||
for (hi = ht->ht_array; todo > 0; ++hi)
|
||||
if (!HASHITEM_EMPTY(hi))
|
||||
{
|
||||
--todo;
|
||||
di = HI2DI(hi);
|
||||
di->di_flags |= DI_FLAGS_RELOAD;
|
||||
}
|
||||
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))
|
||||
{
|
||||
--todo;
|
||||
di = HI2DI(hi);
|
||||
di->di_flags |= DI_FLAGS_RELOAD;
|
||||
}
|
||||
}
|
||||
|
||||
// old imports are no longer valid
|
||||
free_imports(sid);
|
||||
|
@@ -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()
|
||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
729,
|
||||
/**/
|
||||
728,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user