mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.2290: Vim9: unlet of global variable cannot be compiled
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)
This commit is contained in:
parent
e5a2dc87fd
commit
2ef951dd31
@ -813,9 +813,9 @@ get_lval(
|
|||||||
// Clear everything in "lp".
|
// Clear everything in "lp".
|
||||||
CLEAR_POINTER(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 = name;
|
||||||
lp->ll_name_end = find_name_end(name, NULL, NULL,
|
lp->ll_name_end = find_name_end(name, NULL, NULL,
|
||||||
FNE_INCL_BR | fne_flags);
|
FNE_INCL_BR | fne_flags);
|
||||||
|
@ -1340,6 +1340,15 @@ def Test_unlet()
|
|||||||
assert_false(exists('s:somevar'))
|
assert_false(exists('s:somevar'))
|
||||||
unlet! 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([
|
CheckScriptFailure([
|
||||||
'vim9script',
|
'vim9script',
|
||||||
'var svar = 123',
|
'var svar = 123',
|
||||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2290,
|
||||||
/**/
|
/**/
|
||||||
2289,
|
2289,
|
||||||
/**/
|
/**/
|
||||||
|
@ -2544,12 +2544,14 @@ typedef enum {
|
|||||||
#define TFN_NO_DEREF 0x08 // do not dereference a Funcref
|
#define TFN_NO_DEREF 0x08 // do not dereference a Funcref
|
||||||
#define TFN_READ_ONLY 0x10 // will not change the var
|
#define TFN_READ_ONLY 0x10 // will not change the var
|
||||||
#define TFN_NO_DECL 0x20 // only used for GLV_NO_DECL
|
#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:
|
// Values for get_lval() flags argument:
|
||||||
#define GLV_QUIET TFN_QUIET // no error messages
|
#define GLV_QUIET TFN_QUIET // no error messages
|
||||||
#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD // do not use script autoloading
|
#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_READ_ONLY TFN_READ_ONLY // will not change the var
|
||||||
#define GLV_NO_DECL TFN_NO_DECL // assignment without :var or :let
|
#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
|
#define DO_NOT_FREE_CNT 99999 // refcount for dict or list that should not
|
||||||
// be freed.
|
// be freed.
|
||||||
|
@ -6130,6 +6130,12 @@ compile_unlet(
|
|||||||
|
|
||||||
// Normal name. Only supports g:, w:, t: and b: namespaces.
|
// Normal name. Only supports g:, w:, t: and b: namespaces.
|
||||||
*name_end = NUL;
|
*name_end = NUL;
|
||||||
|
if (vim_strchr(p, '.') != NULL || vim_strchr(p, '[') != NULL)
|
||||||
|
{
|
||||||
|
*name_end = cc;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
if (*p == '$')
|
if (*p == '$')
|
||||||
ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
|
ret = generate_UNLET(cctx, ISN_UNLETENV, p + 1, eap->forceit);
|
||||||
else if (check_vim9_unlet(p) == FAIL)
|
else if (check_vim9_unlet(p) == FAIL)
|
||||||
@ -6141,8 +6147,11 @@ compile_unlet(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failed:
|
||||||
// TODO: unlet {list}[idx]
|
// TODO: unlet {list}[idx]
|
||||||
// TODO: unlet {dict}[key]
|
// 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");
|
emsg("Sorry, :unlet not fully implemented yet");
|
||||||
return FAIL;
|
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
|
// 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;
|
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user