1
0
forked from aniani/vim

patch 8.2.0492: Vim9: some error messages not tested

Problem:    Vim9: some error messages not tested.
Solution:   Add more tests.  Remove dead code.  Fix uncovered bugs.
This commit is contained in:
Bram Moolenaar
2020-04-01 21:17:24 +02:00
parent 2da0f0c445
commit a8c1770469
5 changed files with 66 additions and 17 deletions

View File

@@ -106,6 +106,8 @@ func Test_expr2_fails()
call CheckDefFailure("let x = 1||2", msg) call CheckDefFailure("let x = 1||2", msg)
call CheckDefFailure("let x = 1 ||2", msg) call CheckDefFailure("let x = 1 ||2", msg)
call CheckDefFailure("let x = 1|| 2", msg) call CheckDefFailure("let x = 1|| 2", msg)
call CheckDefFailure("let x = 1 || xxx", 'E1001:')
endfunc endfunc
" test && " test &&
@@ -877,7 +879,7 @@ func Test_expr7_fails()
call CheckDefFailure("let x = 123->{x -> x + 5) }", "E451:") call CheckDefFailure("let x = 123->{x -> x + 5) }", "E451:")
call CheckDefFailure("let x = &notexist", 'E113:') call CheckDefFailure("let x = &notexist", 'E113:')
call CheckDefExecFailure("&grepprg = [343]", 'E1051:') call CheckDefFailure("&grepprg = [343]", 'E1013:')
call CheckDefExecFailure("echo s:doesnt_exist", 'E121:') call CheckDefExecFailure("echo s:doesnt_exist", 'E121:')
call CheckDefExecFailure("echo g:doesnt_exist", 'E121:') call CheckDefExecFailure("echo g:doesnt_exist", 'E121:')

View File

@@ -31,6 +31,8 @@ endfunc
let s:appendToMe = 'xxx' let s:appendToMe = 'xxx'
let s:addToMe = 111 let s:addToMe = 111
let g:existing = 'yes' let g:existing = 'yes'
let g:inc_counter = 1
let $SOME_ENV_VAR = 'some'
def Test_assignment() def Test_assignment()
let bool1: bool = true let bool1: bool = true
@@ -94,6 +96,27 @@ def Test_assignment()
assert_equal(333, s:addToMe) assert_equal(333, s:addToMe)
s:newVar = 'new' s:newVar = 'new'
assert_equal('new', s:newVar) assert_equal('new', s:newVar)
set ts=7
&ts += 1
assert_equal(8, &ts)
call CheckDefFailure(['&notex += 3'], 'E113:')
call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
call CheckDefFailure(['&path += 3'], 'E1013:')
g:inc_counter += 1
assert_equal(2, g:inc_counter)
$SOME_ENV_VAR ..= 'more'
assert_equal('somemore', $SOME_ENV_VAR)
call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1013:')
call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1013:')
@a = 'areg'
@a ..= 'add'
assert_equal('aregadd', @a)
call CheckDefFailure(['@a += "more"'], 'E1013:')
call CheckDefFailure(['@a += 123'], 'E1013:')
enddef enddef
func Test_assignment_failure() func Test_assignment_failure()

View File

@@ -738,6 +738,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 */
/**/
492,
/**/ /**/
491, 491,
/**/ /**/

View File

@@ -277,6 +277,25 @@ get_dict_type(type_T *member_type, garray_T *type_list)
return type; return type;
} }
/*
* Return the type_T for a typval. Only for primitive types.
*/
static type_T *
typval2type(typval_T *tv)
{
if (tv->v_type == VAR_NUMBER)
return &t_number;
if (tv->v_type == VAR_BOOL)
return &t_bool;
if (tv->v_type == VAR_STRING)
return &t_string;
if (tv->v_type == VAR_LIST) // e.g. for v:oldfiles
return &t_list_string;
if (tv->v_type == VAR_DICT) // e.g. for v:completed_item
return &t_dict_any;
return &t_any;
}
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// Following generate_ functions expect the caller to call ga_grow(). // Following generate_ functions expect the caller to call ga_grow().
@@ -1402,7 +1421,7 @@ parse_type_member(char_u **arg, type_T *type, garray_T *type_list)
/* /*
* Parse a type at "arg" and advance over it. * Parse a type at "arg" and advance over it.
* Return NULL for failure. * Return &t_any for failure.
*/ */
type_T * type_T *
parse_type(char_u **arg, garray_T *type_list) parse_type(char_u **arg, garray_T *type_list)
@@ -3462,7 +3481,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
int vimvaridx = -1; int vimvaridx = -1;
int oplen = 0; int oplen = 0;
int heredoc = FALSE; int heredoc = FALSE;
type_T *type; type_T *type = &t_any;
lvar_T *lvar; lvar_T *lvar;
char_u *name; char_u *name;
char_u *sp; char_u *sp;
@@ -3532,6 +3551,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
else if (*arg == '$') else if (*arg == '$')
{ {
dest = dest_env; dest = dest_env;
type = &t_string;
if (is_decl) if (is_decl)
{ {
semsg(_("E1065: Cannot declare an environment variable: %s"), name); semsg(_("E1065: Cannot declare an environment variable: %s"), name);
@@ -3546,6 +3566,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
goto theend; goto theend;
} }
dest = dest_reg; dest = dest_reg;
type = &t_string;
if (is_decl) if (is_decl)
{ {
semsg(_("E1066: Cannot declare a register: %s"), name); semsg(_("E1066: Cannot declare a register: %s"), name);
@@ -3563,6 +3584,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
} }
else if (STRNCMP(arg, "v:", 2) == 0) else if (STRNCMP(arg, "v:", 2) == 0)
{ {
typval_T *vtv;
vimvaridx = find_vim_var(name + 2); vimvaridx = find_vim_var(name + 2);
if (vimvaridx < 0) if (vimvaridx < 0)
{ {
@@ -3570,6 +3593,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
goto theend; goto theend;
} }
dest = dest_vimvar; dest = dest_vimvar;
vtv = get_vim_var_tv(vimvaridx);
type = typval2type(vtv);
if (is_decl) if (is_decl)
{ {
semsg(_("E1064: Cannot declare a v: variable: %s"), name); semsg(_("E1064: Cannot declare a v: variable: %s"), name);
@@ -3625,16 +3650,9 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
// parse optional type: "let var: type = expr" // parse optional type: "let var: type = expr"
p = skipwhite(p + 1); p = skipwhite(p + 1);
type = parse_type(&p, cctx->ctx_type_list); type = parse_type(&p, cctx->ctx_type_list);
if (type == NULL)
goto theend;
has_type = TRUE; has_type = TRUE;
} }
else if (idx < 0) else if (idx >= 0)
{
// global and new local default to "any" type
type = &t_any;
}
else
{ {
lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
type = lvar->lv_type; type = lvar->lv_type;
@@ -3701,6 +3719,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
else if (oplen > 0) else if (oplen > 0)
{ {
int r; int r;
type_T *stacktype;
garray_T *stack;
// for "+=", "*=", "..=" etc. first load the current value // for "+=", "*=", "..=" etc. first load the current value
if (*op != '=') if (*op != '=')
@@ -3709,7 +3729,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
{ {
case dest_option: case dest_option:
// TODO: check the option exists // TODO: check the option exists
generate_LOAD(cctx, ISN_LOADOPT, 0, name + 1, type); generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
break; break;
case dest_global: case dest_global:
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type); generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
@@ -3746,12 +3766,10 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
if (r == FAIL) if (r == FAIL)
goto theend; goto theend;
stack = &cctx->ctx_type_stack;
stacktype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
if (idx >= 0 && (is_decl || !has_type)) if (idx >= 0 && (is_decl || !has_type))
{ {
garray_T *stack = &cctx->ctx_type_stack;
type_T *stacktype =
((type_T **)stack->ga_data)[stack->ga_len - 1];
lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
if (!has_type) if (!has_type)
{ {
@@ -3767,6 +3785,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
if (check_type(lvar->lv_type, stacktype, TRUE) == FAIL) if (check_type(lvar->lv_type, stacktype, TRUE) == FAIL)
goto theend; goto theend;
} }
else if (*p != '=' && check_type(type, stacktype, TRUE) == FAIL)
goto theend;
} }
else if (cmdidx == CMD_const) else if (cmdidx == CMD_const)
{ {

View File

@@ -684,6 +684,8 @@ call_def_function(
typval_T optval; typval_T optval;
char_u *name = iptr->isn_arg.string; char_u *name = iptr->isn_arg.string;
// This is not expected to fail, name is checked during
// compilation: don't set SOURCING_LNUM.
if (ga_grow(&ectx.ec_stack, 1) == FAIL) if (ga_grow(&ectx.ec_stack, 1) == FAIL)
goto failed; goto failed;
if (get_option_tv(&name, &optval, TRUE) == FAIL) if (get_option_tv(&name, &optval, TRUE) == FAIL)