diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-05-10 15:24:44 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-05-10 15:24:44 +0200 |
commit | 89483d40438830fb9e74a5ec6c92d2470b05e4c2 (patch) | |
tree | beb03e9bded5798073787f275b2f3cee63814f8b | |
parent | 69212b11d18d9d8951968f6ca88e6ce046c90675 (diff) | |
download | vim-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.c | 21 | ||||
-rw-r--r-- | src/proto/dict.pro | 1 | ||||
-rw-r--r-- | src/scriptfile.c | 27 | ||||
-rw-r--r-- | src/testdir/test_vim9_script.vim | 26 | ||||
-rw-r--r-- | src/version.c | 2 |
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, |