changeset 20347:0e1dfff4f294 v8.2.0729

patch 8.2.0729: Vim9: When reloading a script variables are not cleared Commit: https://github.com/vim/vim/commit/89483d40438830fb9e74a5ec6c92d2470b05e4c2 Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 10 15:24:44 2020 +0200 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.
author Bram Moolenaar <Bram@vim.org>
date Sun, 10 May 2020 15:30:03 +0200
parents cd52b48baba5
children 25253a43acdf
files src/dict.c src/proto/dict.pro src/scriptfile.c src/testdir/test_vim9_script.vim src/version.c
diffstat 5 files changed, 57 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/dict.c
+++ b/src/dict.c
@@ -105,28 +105,37 @@ rettv_dict_set(typval_T *rettv, dict_T *
     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
--- 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);
--- 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);
--- 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()
--- 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,