1
0
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:
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 void
dict_free_contents(dict_T *d) 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; int todo;
hashitem_T *hi; hashitem_T *hi;
dictitem_T *di; dictitem_T *di;
// Lock the hashtab, we don't want it to resize while freeing items. // Lock the hashtab, we don't want it to resize while freeing items.
hash_lock(&d->dv_hashtab); hash_lock(ht);
todo = (int)d->dv_hashtab.ht_used; todo = (int)ht->ht_used;
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) for (hi = ht->ht_array; todo > 0; ++hi)
{ {
if (!HASHITEM_EMPTY(hi)) if (!HASHITEM_EMPTY(hi))
{ {
// Remove the item before deleting it, just in case there is // Remove the item before deleting it, just in case there is
// something recursive causing trouble. // something recursive causing trouble.
di = HI2DI(hi); di = HI2DI(hi);
hash_remove(&d->dv_hashtab, hi); hash_remove(ht, hi);
dictitem_free(di); dictitem_free(di);
--todo; --todo;
} }
} }
// The hashtab is still locked, it has to be re-initialized anyway // The hashtab is still locked, it has to be re-initialized anyway.
hash_clear(&d->dv_hashtab); hash_clear(ht);
} }
static void static void

View File

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

View File

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

View File

@@ -610,7 +610,6 @@ def Test_vim9_import_export()
let import_star_lines =<< trim END let import_star_lines =<< trim END
vim9script vim9script
import * from './Xexport.vim' import * from './Xexport.vim'
g:imported = exported
END END
writefile(import_star_lines, 'Ximport.vim') writefile(import_star_lines, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1045:') assert_fails('source Ximport.vim', 'E1045:')
@@ -807,6 +806,28 @@ def Test_vim9script_reload_delfunc()
delete('Xreloaded.vim') delete('Xreloaded.vim')
enddef 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() def Test_import_absolute()
let import_lines = [ let import_lines = [
'vim9script', 'vim9script',
@@ -862,8 +883,7 @@ def Test_import_rtp()
unlet g:imported_rtp unlet g:imported_rtp
delete('Ximport_rtp.vim') delete('Ximport_rtp.vim')
delete('import/Xexport_rtp.vim') delete('import', 'rf')
delete('import', 'd')
enddef enddef
def Test_fixed_size_list() def Test_fixed_size_list()

View File

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