0
0
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:
Bram Moolenaar
2021-01-01 21:05:55 +01:00
parent c368957b19
commit 3862ea3f62
7 changed files with 54 additions and 15 deletions

View File

@@ -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)

View File

@@ -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())
{

View File

@@ -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

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2268,
/**/
2267,
/**/

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}