mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
patch 8.2.3211: Vim9: argument types are not checked at compile time
Problem: Vim9: argument types are not checked at compile time. Solution: Add several more type checks. Fix type check for matchaddpos(). (Yegappan Lakshmanan, closes #8619)
This commit is contained in:
committed by
Bram Moolenaar
parent
dd0b287c1e
commit
7973de35ba
@@ -4890,9 +4890,15 @@ f_ch_info(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
void
|
||||
f_ch_log(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
char_u *msg = tv_get_string(&argvars[0]);
|
||||
char_u *msg;
|
||||
channel_T *channel = NULL;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_string_arg(argvars, 0) == FAIL
|
||||
|| check_for_opt_chan_or_job_arg(argvars, 1) == FAIL))
|
||||
return;
|
||||
|
||||
msg = tv_get_string(&argvars[0]);
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
channel = get_channel_arg(&argvars[1], FALSE, FALSE, 0);
|
||||
|
||||
|
@@ -542,7 +542,8 @@ arg_dict_any_or_string(type_T *type, argcontext_T *context)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check "type" which is the third argument of extend().
|
||||
* Check "type" which is the third argument of extend() (number or string or
|
||||
* any)
|
||||
*/
|
||||
static int
|
||||
arg_extend3(type_T *type, argcontext_T *context)
|
||||
@@ -557,7 +558,8 @@ arg_extend3(type_T *type, argcontext_T *context)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check "type" which is the second argument of remove().
|
||||
* Check "type" which is the second argument of remove() (number or string or
|
||||
* any)
|
||||
*/
|
||||
static int
|
||||
arg_remove2(type_T *type, argcontext_T *context)
|
||||
@@ -572,7 +574,8 @@ arg_remove2(type_T *type, argcontext_T *context)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check "type" which is the first argument of repeat().
|
||||
* Check "type" which is the first argument of repeat() (string or number or
|
||||
* list or any)
|
||||
*/
|
||||
static int
|
||||
arg_repeat1(type_T *type, argcontext_T *context)
|
||||
@@ -588,7 +591,8 @@ arg_repeat1(type_T *type, argcontext_T *context)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check "type" which is the first argument of slice().
|
||||
* Check "type" which is the first argument of slice() (list or blob or string
|
||||
* or any)
|
||||
*/
|
||||
static int
|
||||
arg_slice1(type_T *type, argcontext_T *context)
|
||||
@@ -604,7 +608,8 @@ arg_slice1(type_T *type, argcontext_T *context)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check "type" which is the first argument of count().
|
||||
* Check "type" which is the first argument of count() (string or list or dict
|
||||
* or any)
|
||||
*/
|
||||
static int
|
||||
arg_count1(type_T *type, argcontext_T *context)
|
||||
@@ -620,7 +625,8 @@ arg_count1(type_T *type, argcontext_T *context)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check "type" which is the first argument of cursor().
|
||||
* Check "type" which is the first argument of cursor() (number or string or
|
||||
* list or any)
|
||||
*/
|
||||
static int
|
||||
arg_cursor1(type_T *type, argcontext_T *context)
|
||||
@@ -666,6 +672,7 @@ static argcheck_T arg2_string_list_nr[] = {arg_string, arg_list_number};
|
||||
static argcheck_T arg2_string_bool[] = {arg_string, arg_bool};
|
||||
static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
|
||||
static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr};
|
||||
static argcheck_T arg2_string_chan_or_job[] = {arg_string, arg_chan_or_job};
|
||||
static argcheck_T arg2_list_number[] = {arg_list_number, arg_list_number};
|
||||
static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool};
|
||||
static argcheck_T arg2_list_any_string[] = {arg_list_any, arg_string};
|
||||
@@ -690,11 +697,14 @@ static argcheck_T arg2_buffer_number[] = {arg_buffer, arg_number};
|
||||
static argcheck_T arg2_buffer_bool[] = {arg_buffer, arg_bool};
|
||||
static argcheck_T arg2_buffer_lnum[] = {arg_buffer, arg_lnum};
|
||||
static argcheck_T arg2_buffer_list_any[] = {arg_buffer, arg_list_any};
|
||||
static argcheck_T arg2_buffer_any[] = {arg_buffer, NULL};
|
||||
static argcheck_T arg3_string[] = {arg_string, arg_string, arg_string};
|
||||
static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
|
||||
static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any};
|
||||
static argcheck_T arg3_number_string_string[] = {arg_number, arg_string, arg_string};
|
||||
static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, NULL};
|
||||
static argcheck_T arg3_number_string_buffer[] = {arg_number, arg_string, arg_buffer};
|
||||
static argcheck_T arg3_number_any_dict[] = {arg_number, NULL, arg_dict_any};
|
||||
static argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool};
|
||||
static argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number};
|
||||
static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any};
|
||||
@@ -707,6 +717,7 @@ static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool};
|
||||
static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
|
||||
static argcheck_T arg3_buffer_number_number[] = {arg_buffer, arg_number, arg_number};
|
||||
static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any};
|
||||
static argcheck_T arg3_buffer_string_any[] = {arg_buffer, arg_string, NULL};
|
||||
static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL};
|
||||
static argcheck_T arg4_string_string_number_string[] = {arg_string, arg_string, arg_number, arg_string};
|
||||
static argcheck_T arg5_number[] = {arg_number, arg_number, arg_number, arg_number, arg_number};
|
||||
@@ -726,12 +737,13 @@ static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_numb
|
||||
static argcheck_T arg2_mapfilter[] = {arg_list_or_dict_or_blob, NULL};
|
||||
static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
|
||||
static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any};
|
||||
static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_number, arg_number, arg_number, arg_dict_any};
|
||||
static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any};
|
||||
static argcheck_T arg23_reduce[] = {arg_list_or_blob, NULL, NULL};
|
||||
static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number};
|
||||
static argcheck_T arg23_remove[] = {arg_list_or_dict_or_blob, arg_remove2, arg_number};
|
||||
static argcheck_T arg2_repeat[] = {arg_repeat1, arg_number};
|
||||
static argcheck_T arg15_search[] = {arg_string, arg_string, arg_number, arg_number, NULL};
|
||||
static argcheck_T arg37_searchpair[] = {arg_string, arg_string, arg_string, arg_string, NULL, arg_number, arg_number};
|
||||
static argcheck_T arg3_setbufline[] = {arg_buffer, arg_lnum, arg_str_or_nr_or_list};
|
||||
static argcheck_T arg2_setline[] = {arg_lnum, NULL};
|
||||
static argcheck_T arg24_setloclist[] = {arg_number, arg_list_any, arg_string, arg_dict_any};
|
||||
@@ -1146,7 +1158,7 @@ static funcentry_T global_functions[] =
|
||||
ret_job, JOB_FUNC(f_ch_getjob)},
|
||||
{"ch_info", 1, 1, FEARG_1, arg1_chan_or_job,
|
||||
ret_dict_any, JOB_FUNC(f_ch_info)},
|
||||
{"ch_log", 1, 2, FEARG_1, NULL,
|
||||
{"ch_log", 1, 2, FEARG_1, arg2_string_chan_or_job,
|
||||
ret_void, JOB_FUNC(f_ch_log)},
|
||||
{"ch_logfile", 1, 2, FEARG_1, arg2_string,
|
||||
ret_void, JOB_FUNC(f_ch_logfile)},
|
||||
@@ -1202,7 +1214,7 @@ static funcentry_T global_functions[] =
|
||||
ret_float, FLOAT_FUNC(f_cosh)},
|
||||
{"count", 2, 4, FEARG_1, arg24_count,
|
||||
ret_number, f_count},
|
||||
{"cscope_connection",0,3, 0, NULL,
|
||||
{"cscope_connection",0,3, 0, arg3_number_string_string,
|
||||
ret_number, f_cscope_connection},
|
||||
{"cursor", 1, 3, FEARG_1, arg13_cursor,
|
||||
ret_number, f_cursor},
|
||||
@@ -1310,7 +1322,7 @@ static funcentry_T global_functions[] =
|
||||
ret_list_dict_any, f_getbufinfo},
|
||||
{"getbufline", 2, 3, FEARG_1, arg3_buffer_lnum_lnum,
|
||||
ret_list_string, f_getbufline},
|
||||
{"getbufvar", 2, 3, FEARG_1, NULL,
|
||||
{"getbufvar", 2, 3, FEARG_1, arg3_buffer_string_any,
|
||||
ret_any, f_getbufvar},
|
||||
{"getchangelist", 0, 1, FEARG_1, arg1_buffer,
|
||||
ret_list_any, f_getchangelist},
|
||||
@@ -1650,9 +1662,9 @@ static funcentry_T global_functions[] =
|
||||
ret_string, f_printf},
|
||||
{"prompt_getprompt", 1, 1, FEARG_1, arg1_buffer,
|
||||
ret_string, JOB_FUNC(f_prompt_getprompt)},
|
||||
{"prompt_setcallback", 2, 2, FEARG_1, NULL,
|
||||
{"prompt_setcallback", 2, 2, FEARG_1, arg2_buffer_any,
|
||||
ret_void, JOB_FUNC(f_prompt_setcallback)},
|
||||
{"prompt_setinterrupt", 2, 2, FEARG_1, NULL,
|
||||
{"prompt_setinterrupt", 2, 2, FEARG_1, arg2_buffer_any,
|
||||
ret_void, JOB_FUNC(f_prompt_setinterrupt)},
|
||||
{"prompt_setprompt", 2, 2, FEARG_1, arg2_buffer_string,
|
||||
ret_void, JOB_FUNC(f_prompt_setprompt)},
|
||||
@@ -1780,9 +1792,9 @@ static funcentry_T global_functions[] =
|
||||
ret_dict_any, f_searchcount},
|
||||
{"searchdecl", 1, 3, FEARG_1, arg3_string_bool_bool,
|
||||
ret_number_bool, f_searchdecl},
|
||||
{"searchpair", 3, 7, 0, NULL,
|
||||
{"searchpair", 3, 7, 0, arg37_searchpair,
|
||||
ret_number, f_searchpair},
|
||||
{"searchpairpos", 3, 7, 0, NULL,
|
||||
{"searchpairpos", 3, 7, 0, arg37_searchpair,
|
||||
ret_list_number, f_searchpairpos},
|
||||
{"searchpos", 1, 5, FEARG_1, arg15_search,
|
||||
ret_list_number, f_searchpos},
|
||||
@@ -1792,7 +1804,7 @@ static funcentry_T global_functions[] =
|
||||
ret_string, f_serverlist},
|
||||
{"setbufline", 3, 3, FEARG_3, arg3_setbufline,
|
||||
ret_number_bool, f_setbufline},
|
||||
{"setbufvar", 3, 3, FEARG_3, NULL,
|
||||
{"setbufvar", 3, 3, FEARG_3, arg3_buffer_string_any,
|
||||
ret_void, f_setbufvar},
|
||||
{"setcellwidths", 1, 1, FEARG_1, arg1_list_any,
|
||||
ret_void, f_setcellwidths},
|
||||
@@ -1950,7 +1962,7 @@ static funcentry_T global_functions[] =
|
||||
ret_string, f_swapname},
|
||||
{"synID", 3, 3, 0, arg3_lnum_number_bool,
|
||||
ret_number, f_synID},
|
||||
{"synIDattr", 2, 3, FEARG_1, NULL,
|
||||
{"synIDattr", 2, 3, FEARG_1, arg3_number_string_string,
|
||||
ret_string, f_synIDattr},
|
||||
{"synIDtrans", 1, 1, FEARG_1, arg1_number,
|
||||
ret_number, f_synIDtrans},
|
||||
@@ -2102,7 +2114,7 @@ static funcentry_T global_functions[] =
|
||||
ret_list_dict_any, TIMER_FUNC(f_timer_info)},
|
||||
{"timer_pause", 2, 2, FEARG_1, arg2_number_bool,
|
||||
ret_void, TIMER_FUNC(f_timer_pause)},
|
||||
{"timer_start", 2, 3, FEARG_1, NULL,
|
||||
{"timer_start", 2, 3, FEARG_1, arg3_number_any_dict,
|
||||
ret_number, TIMER_FUNC(f_timer_start)},
|
||||
{"timer_stop", 1, 1, FEARG_1, arg1_number,
|
||||
ret_void, TIMER_FUNC(f_timer_stop)},
|
||||
@@ -8044,6 +8056,18 @@ searchpair_cmn(typval_T *argvars, pos_T *match_pos)
|
||||
long lnum_stop = 0;
|
||||
long time_limit = 0;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_string_arg(argvars, 0) == FAIL
|
||||
|| check_for_string_arg(argvars, 1) == FAIL
|
||||
|| check_for_string_arg(argvars, 2) == FAIL
|
||||
|| check_for_opt_string_arg(argvars, 3) == FAIL
|
||||
|| (argvars[3].v_type != VAR_UNKNOWN
|
||||
&& argvars[4].v_type != VAR_UNKNOWN
|
||||
&& (check_for_opt_number_arg(argvars, 5) == FAIL
|
||||
|| (argvars[5].v_type != VAR_UNKNOWN
|
||||
&& check_for_opt_number_arg(argvars, 6) == FAIL)))))
|
||||
goto theend;
|
||||
|
||||
// Get the three pattern arguments: start, middle, end. Will result in an
|
||||
// error if not a valid argument.
|
||||
spat = tv_get_string_chk(&argvars[0]);
|
||||
@@ -9245,6 +9269,13 @@ f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
char_u modebuf[NUMBUFLEN];
|
||||
int modec;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_number_arg(argvars, 0) == FAIL
|
||||
|| (check_for_string_arg(argvars, 1) == FAIL
|
||||
|| (argvars[1].v_type != VAR_UNKNOWN
|
||||
&& check_for_opt_string_arg(argvars, 2) == FAIL))))
|
||||
return;
|
||||
|
||||
id = (int)tv_get_number(&argvars[0]);
|
||||
what = tv_get_string(&argvars[1]);
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
|
@@ -4112,6 +4112,11 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
|
||||
dictitem_T *v;
|
||||
int done = FALSE;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_buffer_arg(argvars, 0) == FAIL
|
||||
|| check_for_string_arg(argvars, 1) == FAIL))
|
||||
return;
|
||||
|
||||
varname = tv_get_string_chk(&argvars[1]);
|
||||
buf = tv_get_buf_from_arg(&argvars[0]);
|
||||
|
||||
@@ -4251,6 +4256,12 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
|
||||
if (check_secure())
|
||||
return;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_buffer_arg(argvars, 0) == FAIL
|
||||
|| check_for_string_arg(argvars, 1) == FAIL))
|
||||
return;
|
||||
|
||||
varname = tv_get_string_chk(&argvars[1]);
|
||||
buf = tv_get_buf_from_arg(&argvars[0]);
|
||||
varp = &argvars[2];
|
||||
|
@@ -2496,6 +2496,14 @@ f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||
char_u *prepend = NULL;
|
||||
char_u buf[NUMBUFLEN];
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_opt_number_arg(argvars, 0) == FAIL
|
||||
|| (argvars[0].v_type != VAR_UNKNOWN
|
||||
&& (check_for_opt_string_arg(argvars, 1) == FAIL
|
||||
|| (argvars[1].v_type != VAR_UNKNOWN
|
||||
&& check_for_opt_string_arg(argvars, 2) == FAIL)))))
|
||||
return;
|
||||
|
||||
if (argvars[0].v_type != VAR_UNKNOWN
|
||||
&& argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
|
@@ -1658,6 +1658,10 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
|
||||
if (check_secure())
|
||||
return;
|
||||
|
||||
if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
|
||||
return;
|
||||
|
||||
buf = tv_get_buf(&argvars[0], FALSE);
|
||||
if (buf == NULL)
|
||||
return;
|
||||
@@ -1681,6 +1685,10 @@ f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
|
||||
if (check_secure())
|
||||
return;
|
||||
|
||||
if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
|
||||
return;
|
||||
|
||||
buf = tv_get_buf(&argvars[0], FALSE);
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
@@ -21,6 +21,7 @@ int check_for_opt_list_arg(typval_T *args, int idx);
|
||||
int check_for_dict_arg(typval_T *args, int idx);
|
||||
int check_for_opt_dict_arg(typval_T *args, int idx);
|
||||
int check_for_chan_or_job_arg(typval_T *args, int idx);
|
||||
int check_for_opt_chan_or_job_arg(typval_T *args, int idx);
|
||||
int check_for_job_arg(typval_T *args, int idx);
|
||||
int check_for_string_or_number_arg(typval_T *args, int idx);
|
||||
int check_for_buffer_arg(typval_T *args, int idx);
|
||||
|
@@ -445,6 +445,15 @@ def Test_ch_info()
|
||||
endif
|
||||
enddef
|
||||
|
||||
def Test_ch_log()
|
||||
if !has('channel')
|
||||
CheckFeature channel
|
||||
else
|
||||
CheckDefAndScriptFailure2(['ch_log(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
|
||||
CheckDefAndScriptFailure2(['ch_log("a", 1)'], 'E1013: Argument 2: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 2')
|
||||
endif
|
||||
enddef
|
||||
|
||||
def Test_ch_logfile()
|
||||
if !has('channel')
|
||||
CheckFeature channel
|
||||
@@ -654,6 +663,14 @@ def Test_count()
|
||||
count({a: 1.1, b: 2.2, c: 1.1}, 1.1)->assert_equal(2)
|
||||
enddef
|
||||
|
||||
def Test_cscope_connection()
|
||||
CheckFeature cscope
|
||||
assert_equal(0, cscope_connection())
|
||||
CheckDefAndScriptFailure2(['cscope_connection("a")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
|
||||
CheckDefAndScriptFailure2(['cscope_connection(1, 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
|
||||
CheckDefAndScriptFailure2(['cscope_connection(1, "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
|
||||
enddef
|
||||
|
||||
def Test_cursor()
|
||||
new
|
||||
setline(1, range(4))
|
||||
@@ -1144,6 +1161,11 @@ def Test_getbufline()
|
||||
CheckDefAndScriptFailure2(['getbufline("a", 2, 0z10)'], 'E1013: Argument 3: type mismatch, expected string but got blob', 'E1174: String required for argument 3')
|
||||
enddef
|
||||
|
||||
def Test_getbufvar()
|
||||
CheckDefAndScriptFailure2(['getbufvar(true, "v")'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
|
||||
CheckDefAndScriptFailure2(['getbufvar(1, 2, 3)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
|
||||
enddef
|
||||
|
||||
def Test_getchangelist()
|
||||
new
|
||||
setline(1, 'some text')
|
||||
@@ -1862,8 +1884,7 @@ enddef
|
||||
|
||||
def Test_matchaddpos()
|
||||
CheckDefAndScriptFailure2(['matchaddpos(1, [1])'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
|
||||
CheckDefAndScriptFailure2(['matchaddpos("a", "b")'], 'E1013: Argument 2: type mismatch, expected list<number> but got string', 'E1211: List required for argument 2')
|
||||
CheckDefFailure(['matchaddpos("a", ["2"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
|
||||
CheckDefAndScriptFailure2(['matchaddpos("a", "b")'], 'E1013: Argument 2: type mismatch, expected list<any> but got string', 'E1211: List required for argument 2')
|
||||
CheckDefAndScriptFailure2(['matchaddpos("a", [1], "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
|
||||
CheckDefAndScriptFailure2(['matchaddpos("a", [1], 1, "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
|
||||
CheckDefAndScriptFailure2(['matchaddpos("a", [1], 1, 1, [])'], 'E1013: Argument 5: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 5')
|
||||
@@ -2148,6 +2169,22 @@ def Test_prompt_getprompt()
|
||||
endif
|
||||
enddef
|
||||
|
||||
def Test_prompt_setcallback()
|
||||
if !has('channel')
|
||||
CheckFeature channel
|
||||
else
|
||||
CheckDefAndScriptFailure2(['prompt_setcallback(true, "1")'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
|
||||
endif
|
||||
enddef
|
||||
|
||||
def Test_prompt_setinterrupt()
|
||||
if !has('channel')
|
||||
CheckFeature channel
|
||||
else
|
||||
CheckDefAndScriptFailure2(['prompt_setinterrupt(true, "1")'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
|
||||
endif
|
||||
enddef
|
||||
|
||||
def Test_prompt_setprompt()
|
||||
if !has('channel')
|
||||
CheckFeature channel
|
||||
@@ -2575,13 +2612,20 @@ def Test_searchpair()
|
||||
|
||||
lines =<< trim END
|
||||
def TestPair()
|
||||
echo searchpair("a", "b", "c", "d", "1", "f")
|
||||
echo searchpair("a", "b", "c", "d", "1", 99)
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
bwipe!
|
||||
CheckDefAndScriptFailure2(['searchpair(1, "b", "c")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
|
||||
CheckDefAndScriptFailure2(['searchpair("a", 2, "c")'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
|
||||
CheckDefAndScriptFailure2(['searchpair("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
|
||||
CheckDefAndScriptFailure2(['searchpair("a", "b", "c", 4)'], 'E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4')
|
||||
# BUG: Vim crashes with the following test
|
||||
#CheckDefAndScriptFailure2(['searchpair("a", "b", "c", "d", "1", "f")'], 'E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4')
|
||||
#CheckDefAndScriptFailure2(['searchpair("a", "b", "c", "d", "1", 3, "g")'], 'E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4')
|
||||
enddef
|
||||
|
||||
def Test_searchpos()
|
||||
@@ -2676,6 +2720,9 @@ def Test_setbufvar()
|
||||
|
||||
setbufvar('%', 'myvar', 123)
|
||||
getbufvar('%', 'myvar')->assert_equal(123)
|
||||
|
||||
CheckDefAndScriptFailure2(['setbufvar(true, "v", 3)'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
|
||||
CheckDefAndScriptFailure2(['setbufvar(1, 2, 3)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
|
||||
enddef
|
||||
|
||||
def Test_setbufline()
|
||||
@@ -3112,6 +3159,12 @@ def Test_synID()
|
||||
CheckDefAndScriptFailure2(['synID(1, 1, 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
|
||||
enddef
|
||||
|
||||
def Test_synIDattr()
|
||||
CheckDefAndScriptFailure2(['synIDattr("a", "b")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
|
||||
CheckDefAndScriptFailure2(['synIDattr(1, 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
|
||||
CheckDefAndScriptFailure2(['synIDattr(1, "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
|
||||
enddef
|
||||
|
||||
def Test_synIDtrans()
|
||||
CheckDefFailure(['synIDtrans("a")'], 'E1013: Argument 1: type mismatch, expected number but got string')
|
||||
enddef
|
||||
@@ -3379,6 +3432,11 @@ def Test_timer_paused()
|
||||
timer_stop(id)
|
||||
enddef
|
||||
|
||||
def Test_timer_start()
|
||||
CheckDefAndScriptFailure2(['timer_start("a", "1")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
|
||||
CheckDefAndScriptFailure2(['timer_start(1, "1", [1])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3')
|
||||
enddef
|
||||
|
||||
def Test_timer_stop()
|
||||
CheckDefFailure(['timer_stop("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
|
||||
assert_equal(0, timer_stop(100))
|
||||
|
@@ -799,7 +799,7 @@ f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
void
|
||||
f_timer_start(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
long msec = (long)tv_get_number(&argvars[0]);
|
||||
long msec;
|
||||
timer_T *timer;
|
||||
int repeat = 0;
|
||||
callback_T callback;
|
||||
@@ -808,6 +808,13 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
|
||||
rettv->vval.v_number = -1;
|
||||
if (check_secure())
|
||||
return;
|
||||
|
||||
if (in_vim9script()
|
||||
&& (check_for_number_arg(argvars, 0) == FAIL
|
||||
|| check_for_opt_dict_arg(argvars, 2) == FAIL))
|
||||
return;
|
||||
|
||||
msec = (long)tv_get_number(&argvars[0]);
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
if (argvars[2].v_type != VAR_DICT
|
||||
|
11
src/typval.c
11
src/typval.c
@@ -522,6 +522,17 @@ check_for_chan_or_job_arg(typval_T *args, int idx)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give an error and return FAIL unless "args[idx]" is an optional channel or a
|
||||
* job.
|
||||
*/
|
||||
int
|
||||
check_for_opt_chan_or_job_arg(typval_T *args, int idx)
|
||||
{
|
||||
return (args[idx].v_type == VAR_UNKNOWN
|
||||
|| check_for_chan_or_job_arg(args, idx) != FAIL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Give an error and return FAIL unless "args[idx]" is a job.
|
||||
*/
|
||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3211,
|
||||
/**/
|
||||
3210,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user