diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-01-03 20:55:26 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-01-03 20:55:26 +0100 |
commit | 2ef951dd31505874ae9ac35a18513ef34ae0ea3e (patch) | |
tree | a9be93c17454efbd7edec7c520d6ebaea55f7135 | |
parent | e5a2dc87fd9d63dfd0d9c379e363ee8b8c05b14c (diff) | |
download | vim-git-2ef951dd31505874ae9ac35a18513ef34ae0ea3e.tar.gz |
patch 8.2.2290: Vim9: unlet of global variable cannot be compiledv8.2.2290
Problem: Vim9: unlet of global variable cannot be compiled.
Solution: Skip over variables that might be defined later. Give an error if
a subscript is found. (closes #7585)
-rw-r--r-- | src/eval.c | 4 | ||||
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 9 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 12 |
5 files changed, 26 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c index 87da4f325..75cbca96c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -813,9 +813,9 @@ get_lval( // Clear everything in "lp". CLEAR_POINTER(lp); - if (skip) + if (skip || (flags & GLV_COMPILING)) { - // When skipping just find the end of the name. + // When skipping or compiling just find the end of the name. lp->ll_name = name; lp->ll_name_end = find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 5f45b57a1..bdae6350a 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1340,6 +1340,15 @@ def Test_unlet() assert_false(exists('s:somevar')) unlet! s:somevar + # can compile unlet before variable exists + # This doesn't work yet + #g:someDict = {key: 'val'} + #var k = 'key' + #unlet g:someDict[k] + #assert_equal({}, g:someDict) + #unlet g:someDict + #assert_false(exists('g:someDict')) + CheckScriptFailure([ 'vim9script', 'var svar = 123', diff --git a/src/version.c b/src/version.c index c5017a461..558536544 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2290, +/**/ 2289, /**/ 2288, @@ -2544,12 +2544,14 @@ typedef enum { #define TFN_NO_DEREF 0x08 // do not dereference a Funcref #define TFN_READ_ONLY 0x10 // will not change the var #define TFN_NO_DECL 0x20 // only used for GLV_NO_DECL +#define TFN_COMPILING 0x40 // only used for GLV_COMPILING // Values for get_lval() flags argument: #define GLV_QUIET TFN_QUIET // no error messages #define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD // do not use script autoloading #define GLV_READ_ONLY TFN_READ_ONLY // will not change the var #define GLV_NO_DECL TFN_NO_DECL // assignment without :var or :let +#define GLV_COMPILING TFN_COMPILING // variable may be defined later #define DO_NOT_FREE_CNT 99999 // refcount for dict or list that should not // be freed. diff --git a/src/vim9compile.c b/src/vim9compile.c index 79d28c2bb..412f0c96c 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -6130,6 +6130,12 @@ compile_unlet( // Normal name. Only supports g:, w:, t: and b: namespaces. *name_end = NUL; + if (vim_strchr(p, '.') != NULL || vim_strchr(p, '[') != NULL) + { + *name_end = cc; + goto failed; + } + if (*p == '$') ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit); else if (check_vim9_unlet(p) == FAIL) @@ -6141,8 +6147,11 @@ compile_unlet( return ret; } +failed: // TODO: unlet {list}[idx] // TODO: unlet {dict}[key] + // complication: {list} can be global while "idx" is local, thus we can't + // call ex_unlet(). emsg("Sorry, :unlet not fully implemented yet"); return FAIL; } @@ -6163,7 +6172,8 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx) } // TODO: this doesn't work for local variables - ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx); + ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD | GLV_COMPILING, + compile_unlet, cctx); return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd; } |