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
|
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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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()
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user