summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-05-10 15:24:44 +0200
committerBram Moolenaar <Bram@vim.org>2020-05-10 15:24:44 +0200
commit89483d40438830fb9e74a5ec6c92d2470b05e4c2 (patch)
treebeb03e9bded5798073787f275b2f3cee63814f8b
parent69212b11d18d9d8951968f6ca88e6ce046c90675 (diff)
downloadvim-git-89483d40438830fb9e74a5ec6c92d2470b05e4c2.tar.gz
patch 8.2.0729: Vim9: When reloading a script variables are not clearedv8.2.0729
Problem: Vim9: When reloading a script variables are not cleared. Solution: When sourcing a script again clear all script-local variables.
-rw-r--r--src/dict.c21
-rw-r--r--src/proto/dict.pro1
-rw-r--r--src/scriptfile.c27
-rw-r--r--src/testdir/test_vim9_script.vim26
-rw-r--r--src/version.c2
5 files changed, 57 insertions, 20 deletions
diff --git a/src/dict.c b/src/dict.c
index 88bd0e21c..54d3110b0 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -105,28 +105,37 @@ 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
diff --git a/src/proto/dict.pro b/src/proto/dict.pro
index d9b35c309..45bcfbf3a 100644
--- a/src/proto/dict.pro
+++ b/src/proto/dict.pro
@@ -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);
diff --git a/src/scriptfile.c b/src/scriptfile.c
index ba74a8aec..86e8b0110 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -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);
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 564e51d0a..d1cc1f9de 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -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()
diff --git a/src/version.c b/src/version.c
index c595e9df4..4bf624264 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 729,
+/**/
728,
/**/
727,