mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.1338: Vim9: assigning to script-local variable doesn't check type
Problem: Vim9: assigning to script-local variable doesn't check type. Solution: Use the type. (issue #6591)
This commit is contained in:
@@ -251,6 +251,29 @@ def Test_assignment_dict()
|
|||||||
|
|
||||||
# type becomes dict<any>
|
# type becomes dict<any>
|
||||||
let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
|
let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
|
||||||
|
|
||||||
|
# assignment to script-local dict
|
||||||
|
let lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
let test: dict<any> = {}
|
||||||
|
def FillDict(): dict<any>
|
||||||
|
test['a'] = 43
|
||||||
|
return test
|
||||||
|
enddef
|
||||||
|
assert_equal(#{a: 43}, FillDict())
|
||||||
|
END
|
||||||
|
call CheckScriptSuccess(lines)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
let test: dict<any>
|
||||||
|
def FillDict(): dict<any>
|
||||||
|
test['a'] = 43
|
||||||
|
return test
|
||||||
|
enddef
|
||||||
|
FillDict()
|
||||||
|
END
|
||||||
|
call CheckScriptFailure(lines, 'E1103:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_assignment_local()
|
def Test_assignment_local()
|
||||||
|
@@ -754,6 +754,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 */
|
||||||
|
/**/
|
||||||
|
1338,
|
||||||
/**/
|
/**/
|
||||||
1337,
|
1337,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -5070,6 +5070,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
char_u *ret = NULL;
|
char_u *ret = NULL;
|
||||||
int var_count = 0;
|
int var_count = 0;
|
||||||
int var_idx;
|
int var_idx;
|
||||||
|
int scriptvar_sid = 0;
|
||||||
|
int scriptvar_idx = -1;
|
||||||
int semicolon = 0;
|
int semicolon = 0;
|
||||||
garray_T *instr = &cctx->ctx_instr;
|
garray_T *instr = &cctx->ctx_instr;
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
@@ -5333,7 +5335,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
imported_T *import = NULL;
|
||||||
|
|
||||||
for (idx = 0; reserved[idx] != NULL; ++idx)
|
for (idx = 0; reserved[idx] != NULL; ++idx)
|
||||||
if (STRCMP(reserved[idx], name) == 0)
|
if (STRCMP(reserved[idx], name) == 0)
|
||||||
@@ -5374,9 +5377,11 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)
|
else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)
|
||||||
|| lookup_script(var_start, varlen) == OK
|
|| lookup_script(var_start, varlen) == OK
|
||||||
|| find_imported(var_start, varlen, cctx) != NULL)
|
|| (import = find_imported(var_start, varlen, cctx))
|
||||||
|
!= NULL)
|
||||||
{
|
{
|
||||||
dest = dest_script;
|
char_u *rawname = name + (name[1] == ':' ? 2 : 0);
|
||||||
|
|
||||||
if (is_decl)
|
if (is_decl)
|
||||||
{
|
{
|
||||||
if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0))
|
if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0))
|
||||||
@@ -5387,6 +5392,21 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
name);
|
name);
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
dest = dest_script;
|
||||||
|
|
||||||
|
// existing script-local variables should have a type
|
||||||
|
scriptvar_sid = current_sctx.sc_sid;
|
||||||
|
if (import != NULL)
|
||||||
|
scriptvar_sid = import->imp_sid;
|
||||||
|
scriptvar_idx = get_script_item_idx(scriptvar_sid,
|
||||||
|
rawname, TRUE);
|
||||||
|
if (scriptvar_idx >= 0)
|
||||||
|
{
|
||||||
|
scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
|
||||||
|
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
|
||||||
|
+ scriptvar_idx;
|
||||||
|
type = sv->sv_type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (name[1] == ':' && name[2] != NUL)
|
else if (name[1] == ':' && name[2] != NUL)
|
||||||
{
|
{
|
||||||
@@ -5766,21 +5786,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
break;
|
break;
|
||||||
case dest_script:
|
case dest_script:
|
||||||
{
|
{
|
||||||
char_u *rawname = name + (name[1] == ':' ? 2 : 0);
|
if (scriptvar_idx < 0)
|
||||||
imported_T *import = NULL;
|
|
||||||
int sid = current_sctx.sc_sid;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
if (name[1] != ':')
|
|
||||||
{
|
|
||||||
import = find_imported(name, 0, cctx);
|
|
||||||
if (import != NULL)
|
|
||||||
sid = import->imp_sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = get_script_item_idx(sid, rawname, TRUE);
|
|
||||||
// TODO: specific type
|
|
||||||
if (idx < 0)
|
|
||||||
{
|
{
|
||||||
char_u *name_s = name;
|
char_u *name_s = name;
|
||||||
|
|
||||||
@@ -5796,14 +5802,14 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
vim_snprintf((char *)name_s, len,
|
vim_snprintf((char *)name_s, len,
|
||||||
"s:%s", name);
|
"s:%s", name);
|
||||||
}
|
}
|
||||||
generate_OLDSCRIPT(cctx, ISN_STORES, name_s, sid,
|
generate_OLDSCRIPT(cctx, ISN_STORES, name_s,
|
||||||
&t_any);
|
scriptvar_sid, type);
|
||||||
if (name_s != name)
|
if (name_s != name)
|
||||||
vim_free(name_s);
|
vim_free(name_s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
|
generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
|
||||||
sid, idx, &t_any);
|
scriptvar_sid, scriptvar_idx, type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case dest_local:
|
case dest_local:
|
||||||
|
@@ -1422,6 +1422,11 @@ call_def_function(
|
|||||||
dict_T *dict = tv_dict->vval.v_dict;
|
dict_T *dict = tv_dict->vval.v_dict;
|
||||||
dictitem_T *di;
|
dictitem_T *di;
|
||||||
|
|
||||||
|
if (dict == NULL)
|
||||||
|
{
|
||||||
|
emsg(_(e_dictnull));
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
key = (char_u *)"";
|
key = (char_u *)"";
|
||||||
tv = STACK_TV_BOT(-3);
|
tv = STACK_TV_BOT(-3);
|
||||||
|
Reference in New Issue
Block a user