mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 8.2.2268: Vim9: list unpack seen as declaration
Problem: Vim9: list unpack seen as declaration. Solution: Check for "var". (closes #7594)
This commit is contained in:
@@ -1748,7 +1748,7 @@ next_for_item(void *fi_void, char_u *arg)
|
||||
{
|
||||
forinfo_T *fi = (forinfo_T *)fi_void;
|
||||
int result;
|
||||
int flag = in_vim9script() ? ASSIGN_NO_DECL : 0;
|
||||
int flag = in_vim9script() ? ASSIGN_DECL : 0;
|
||||
listitem_T *item;
|
||||
|
||||
if (fi->fi_blob != NULL)
|
||||
|
@@ -912,7 +912,7 @@ ex_let_vars(
|
||||
int copy, // copy values from "tv", don't move
|
||||
int semicolon, // from skip_var_list()
|
||||
int var_count, // from skip_var_list()
|
||||
int flags, // ASSIGN_FINAL, ASSIGN_CONST, ASSIGN_NO_DECL
|
||||
int flags, // ASSIGN_FINAL, ASSIGN_CONST, etc.
|
||||
char_u *op)
|
||||
{
|
||||
char_u *arg = arg_start;
|
||||
@@ -1267,7 +1267,7 @@ ex_let_one(
|
||||
char_u *arg, // points to variable name
|
||||
typval_T *tv, // value to assign to variable
|
||||
int copy, // copy value from "tv"
|
||||
int flags, // ASSIGN_CONST, ASSIGN_FINAL, ASSIGN_NO_DECL
|
||||
int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
|
||||
char_u *endchars, // valid chars after variable name or NULL
|
||||
char_u *op) // "+", "-", "." or NULL
|
||||
{
|
||||
@@ -1279,7 +1279,7 @@ ex_let_one(
|
||||
int opt_flags;
|
||||
char_u *tofree = NULL;
|
||||
|
||||
if (in_vim9script() && (flags & ASSIGN_NO_DECL) == 0
|
||||
if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
|
||||
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
|
||||
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
|
||||
{
|
||||
@@ -1476,7 +1476,8 @@ ex_let_one(
|
||||
lval_T lv;
|
||||
|
||||
p = get_lval(arg, tv, &lv, FALSE, FALSE,
|
||||
(flags & ASSIGN_NO_DECL) ? GLV_NO_DECL : 0, FNE_CHECK_START);
|
||||
(flags & (ASSIGN_NO_DECL | ASSIGN_DECL))
|
||||
? GLV_NO_DECL : 0, FNE_CHECK_START);
|
||||
if (p != NULL && lv.ll_name != NULL)
|
||||
{
|
||||
if (endchars != NULL && vim_strchr(endchars,
|
||||
@@ -3053,7 +3054,7 @@ set_var(
|
||||
typval_T *tv,
|
||||
int copy) // make copy of value in "tv"
|
||||
{
|
||||
set_var_const(name, NULL, tv, copy, ASSIGN_NO_DECL);
|
||||
set_var_const(name, NULL, tv, copy, ASSIGN_DECL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3067,7 +3068,7 @@ set_var_const(
|
||||
type_T *type,
|
||||
typval_T *tv_arg,
|
||||
int copy, // make copy of value in "tv"
|
||||
int flags) // ASSIGN_CONST, ASSIGN_FINAL, ASSIGN_NO_DECL
|
||||
int flags) // ASSIGN_CONST, ASSIGN_FINAL, etc.
|
||||
{
|
||||
typval_T *tv = tv_arg;
|
||||
typval_T bool_tv;
|
||||
@@ -3087,7 +3088,7 @@ set_var_const(
|
||||
|
||||
if (vim9script
|
||||
&& !is_script_local
|
||||
&& (flags & ASSIGN_NO_DECL) == 0
|
||||
&& (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
|
||||
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
|
||||
&& name[1] == ':')
|
||||
{
|
||||
@@ -3126,7 +3127,7 @@ set_var_const(
|
||||
|
||||
if (is_script_local && vim9script)
|
||||
{
|
||||
if ((flags & ASSIGN_NO_DECL) == 0)
|
||||
if ((flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
|
||||
{
|
||||
semsg(_(e_redefining_script_item_str), name);
|
||||
goto failed;
|
||||
@@ -3200,8 +3201,15 @@ set_var_const(
|
||||
|
||||
clear_tv(&di->di_tv);
|
||||
}
|
||||
else // add a new variable
|
||||
else
|
||||
{
|
||||
// add a new variable
|
||||
if (vim9script && is_script_local && (flags & ASSIGN_NO_DECL))
|
||||
{
|
||||
semsg(_(e_unknown_variable_str), name);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// Can't add "v:" or "a:" variable.
|
||||
if (ht == &vimvarht || ht == get_funccal_args_ht())
|
||||
{
|
||||
|
@@ -261,6 +261,12 @@ def Test_assign_unpack()
|
||||
END
|
||||
CheckDefFailure(lines, 'E1031:', 3)
|
||||
|
||||
lines =<< trim END
|
||||
[v1, v2] = [1, 2]
|
||||
END
|
||||
CheckDefFailure(lines, 'E1089', 1)
|
||||
CheckScriptFailure(['vim9script'] + lines, 'E1089', 2)
|
||||
|
||||
lines =<< trim END
|
||||
var v1: number
|
||||
var v2: number
|
||||
@@ -759,6 +765,8 @@ def Test_assignment_default()
|
||||
assert_equal(5678, nr)
|
||||
enddef
|
||||
|
||||
let scriptvar = 'init'
|
||||
|
||||
def Test_assignment_var_list()
|
||||
var lines =<< trim END
|
||||
var v1: string
|
||||
@@ -794,10 +802,9 @@ def Test_assignment_var_list()
|
||||
assert_equal('some', $SOME_VAR)
|
||||
assert_equal('other', $OTHER_VAR)
|
||||
|
||||
[g:globalvar, s:scriptvar, b:bufvar, w:winvar, t:tabvar, v:errmsg] =
|
||||
['global', 'script', 'buf', 'win', 'tab', 'error']
|
||||
[g:globalvar, b:bufvar, w:winvar, t:tabvar, v:errmsg] =
|
||||
['global', 'buf', 'win', 'tab', 'error']
|
||||
assert_equal('global', g:globalvar)
|
||||
assert_equal('script', s:scriptvar)
|
||||
assert_equal('buf', b:bufvar)
|
||||
assert_equal('win', w:winvar)
|
||||
assert_equal('tab', t:tabvar)
|
||||
@@ -805,6 +812,21 @@ def Test_assignment_var_list()
|
||||
unlet g:globalvar
|
||||
END
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
|
||||
[g:globalvar, s:scriptvar, b:bufvar] = ['global', 'script', 'buf']
|
||||
assert_equal('global', g:globalvar)
|
||||
assert_equal('script', s:scriptvar)
|
||||
assert_equal('buf', b:bufvar)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var s:scriptvar = 'init'
|
||||
[g:globalvar, s:scriptvar, w:winvar] = ['global', 'script', 'win']
|
||||
assert_equal('global', g:globalvar)
|
||||
assert_equal('script', s:scriptvar)
|
||||
assert_equal('win', w:winvar)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_assignment_vim9script()
|
||||
@@ -1182,7 +1204,7 @@ def Test_var_declaration()
|
||||
g:other_var = other
|
||||
|
||||
# type is inferred
|
||||
s:dict = {['a']: 222}
|
||||
var s:dict = {['a']: 222}
|
||||
def GetDictVal(key: any)
|
||||
g:dict_val = s:dict[key]
|
||||
enddef
|
||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2268,
|
||||
/**/
|
||||
2267,
|
||||
/**/
|
||||
|
@@ -2146,6 +2146,7 @@ typedef enum {
|
||||
#define ASSIGN_FINAL 1 // ":final"
|
||||
#define ASSIGN_CONST 2 // ":const"
|
||||
#define ASSIGN_NO_DECL 4 // "name = expr" without ":let"/":const"/":final"
|
||||
#define ASSIGN_DECL 8 // may declare variable if it does not exist
|
||||
|
||||
#include "ex_cmds.h" // Ex command defines
|
||||
#include "spell.h" // spell checking stuff
|
||||
|
@@ -5634,6 +5634,11 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
semsg(_(e_cannot_use_operator_on_new_variable), name);
|
||||
goto theend;
|
||||
}
|
||||
if (!is_decl)
|
||||
{
|
||||
semsg(_(e_unknown_variable_str), name);
|
||||
goto theend;
|
||||
}
|
||||
|
||||
// new local variable
|
||||
if ((type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
|
||||
@@ -6140,6 +6145,7 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO: this doesn't work for local variables
|
||||
ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx);
|
||||
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
|
||||
}
|
||||
|
@@ -806,7 +806,7 @@ store_var(char_u *name, typval_T *tv)
|
||||
funccal_entry_T entry;
|
||||
|
||||
save_funccal(&entry);
|
||||
set_var_const(name, NULL, tv, FALSE, ASSIGN_NO_DECL);
|
||||
set_var_const(name, NULL, tv, FALSE, ASSIGN_DECL);
|
||||
restore_funccal();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user