]> granicus.if.org Git - vim/commitdiff
patch 8.2.0729: Vim9: When reloading a script variables are not cleared v8.2.0729
authorBram Moolenaar <Bram@vim.org>
Sun, 10 May 2020 13:24:44 +0000 (15:24 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 10 May 2020 13:24:44 +0000 (15:24 +0200)
Problem:    Vim9: When reloading a script variables are not cleared.
Solution:   When sourcing a script again clear all script-local variables.

src/dict.c
src/proto/dict.pro
src/scriptfile.c
src/testdir/test_vim9_script.vim
src/version.c

index 88bd0e21c6b3d9e2fe57f16792a52500e08ca3cf..54d3110b026b64af0cdca16570e404294c1bb7cc 100644 (file)
@@ -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
index d9b35c30919f68058eebe5d3909a1de439b295ff..45bcfbf3a9f7985812a1ef79fdcbadd811b3ead1 100644 (file)
@@ -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);
index ba74a8aece76dd424bf6e2d45946914a09f74d65..86e8b01105b3ec3bd4583e5fbfd2bbb4a2c71e28 100644 (file)
@@ -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);
index 564e51d0afffb0bb0a10acf63874b76e8098f78b..d1cc1f9de344b6463325ce228d266ca7e6108e3b 100644 (file)
@@ -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()
index c595e9df45aa000ab3182a79e1ccb42dec12f9ab..4bf6242645039675a70510b0d2fa620d4f937058 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    729,
 /**/
     728,
 /**/