summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2021-07-15 12:49:58 +0200
committerBram Moolenaar <Bram@vim.org>2021-07-15 12:49:58 +0200
commit1a71d31bf34b0b2b08517903826004ec6fd440e5 (patch)
tree05f54a00199737fe81fdf49e9ea72c09dba483d9
parentc816a2c22667108fcd61f445de2c926f78ff9fa7 (diff)
patch 8.2.3162: Vim9: argument types are not checked at compile timev8.2.3162
Problem: Vim9: argument types are not checked at compile time. Solution: Add more type checks. (Yegappan Lakshmanan, closes #8560)
-rw-r--r--runtime/doc/channel.txt2
-rw-r--r--src/clientserver.c9
-rw-r--r--src/cmdhist.c6
-rw-r--r--src/errors.h2
-rw-r--r--src/evalfunc.c249
-rw-r--r--src/evalwindow.c6
-rw-r--r--src/filepath.c6
-rw-r--r--src/globals.h1
-rw-r--r--src/popupwin.c50
-rw-r--r--src/proto/typval.pro1
-rw-r--r--src/sign.c4
-rw-r--r--src/strings.c25
-rw-r--r--src/terminal.c5
-rw-r--r--src/testdir/test_normal.vim2
-rw-r--r--src/testdir/test_reltime.vim4
-rw-r--r--src/testdir/test_vim9_builtin.vim605
-rw-r--r--src/testdir/test_vim9_expr.vim2
-rw-r--r--src/testing.c15
-rw-r--r--src/textprop.c9
-rw-r--r--src/time.c27
-rw-r--r--src/typval.c17
-rw-r--r--src/version.c2
22 files changed, 780 insertions, 269 deletions
diff --git a/runtime/doc/channel.txt b/runtime/doc/channel.txt
index 6e5cfc8356..4049f22b44 100644
--- a/runtime/doc/channel.txt
+++ b/runtime/doc/channel.txt
@@ -852,7 +852,7 @@ available.
job_getchannel({job}) *job_getchannel()*
Get the channel handle that {job} is using.
To check if the job has no channel: >
- if string(job_getchannel()) == 'channel fail'
+ if string(job_getchannel(job)) == 'channel fail'
<
Can also be used as a |method|: >
GetJob()->job_getchannel()
diff --git a/src/clientserver.c b/src/clientserver.c
index 7215aa7ffb..00bea6f56a 100644
--- a/src/clientserver.c
+++ b/src/clientserver.c
@@ -887,8 +887,15 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
char_u *r = NULL;
#ifdef FEAT_CLIENTSERVER
- char_u *serverid = tv_get_string_chk(&argvars[0]);
+ char_u *serverid;
+
+ if (in_vim9script()
+ && (check_for_string_arg(argvars, 0) == FAIL
+ || (argvars[1].v_type != VAR_UNKNOWN
+ && check_for_number_arg(argvars, 1) == FAIL)))
+ return;
+ serverid = tv_get_string_chk(&argvars[0]);
if (serverid != NULL && !check_restricted() && !check_secure())
{
int timeout = 0;
diff --git a/src/cmdhist.c b/src/cmdhist.c
index 8bb3cb61c7..1b04e62237 100644
--- a/src/cmdhist.c
+++ b/src/cmdhist.c
@@ -597,6 +597,12 @@ f_histget(typval_T *argvars UNUSED, typval_T *rettv)
int idx;
char_u *str;
+ if (in_vim9script()
+ && (check_for_string_arg(argvars, 0) == FAIL
+ || (argvars[1].v_type != VAR_UNKNOWN
+ && check_for_number_arg(argvars, 1) == FAIL)))
+ return;
+
str = tv_get_string_chk(&argvars[0]); // NULL on type error
if (str == NULL)
rettv->vval.v_string = NULL;
diff --git a/src/errors.h b/src/errors.h
index bfbe0296ed..09679b23ac 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -500,3 +500,5 @@ EXTERN char e_complete_used_without_nargs[]
INIT(= N_("E1208: -complete used without -nargs"));
EXTERN char e_invalid_value_for_line_number_str[]
INIT(= N_("E1209: Invalid value for a line number: \"%s\""));
+EXTERN char e_number_required_for_argument_nr[]
+ INIT(= N_("E1210: Number required for argument %d"));
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 029c8a6411..dee1ecb0fc 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -255,6 +255,15 @@ arg_dict_any(type_T *type, argcontext_T *context)
}
/*
+ * Check "type" is a list of 'any'.
+ */
+ static int
+arg_list_any(type_T *type, argcontext_T *context)
+{
+ return check_arg_type(&t_list_any, type, context);
+}
+
+/*
* Check "type" is a list of numbers.
*/
static int
@@ -287,9 +296,6 @@ arg_string(type_T *type, argcontext_T *context)
static int
arg_bool(type_T *type, argcontext_T *context)
{
- if (type->tt_type == VAR_ANY
- || type->tt_type == VAR_NUMBER || type->tt_type == VAR_BOOL)
- return OK;
return check_arg_type(&t_bool, type, context);
}
@@ -353,7 +359,7 @@ arg_string_or_list_any(type_T *type, argcontext_T *context)
}
/*
- * Check "type" is a list or a dict.
+ * Check "type" is a list of 'any' or a dict of 'any'.
*/
static int
arg_list_or_dict(type_T *type, argcontext_T *context)
@@ -366,12 +372,22 @@ arg_list_or_dict(type_T *type, argcontext_T *context)
}
/*
+ * Check "type" is a job.
+ */
+ static int
+arg_job(type_T *type, argcontext_T *context)
+{
+ return check_arg_type(&t_job, type, context);
+}
+
+/*
* Check "type" is a channel or a job.
*/
static int
arg_chan_or_job(type_T *type, argcontext_T *context)
{
- if (type->tt_type == VAR_CHANNEL || type->tt_type == VAR_JOB)
+ if (type->tt_type == VAR_ANY ||
+ type->tt_type == VAR_CHANNEL || type->tt_type == VAR_JOB)
return OK;
arg_type_mismatch(&t_channel, type, context->arg_idx + 1);
return FAIL;
@@ -459,38 +475,47 @@ arg_extend3(type_T *type, argcontext_T *context)
/*
* Lists of functions that check the argument types of a builtin function.
*/
-argcheck_T arg1_string[] = {arg_string};
-argcheck_T arg1_number[] = {arg_number};
-argcheck_T arg1_dict[] = {arg_dict_any};
-argcheck_T arg1_list_nr[] = {arg_list_number};
-argcheck_T arg1_list_string[] = {arg_list_string};
-argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
-argcheck_T arg1_string_or_nr[] = {arg_string_or_nr};
-argcheck_T arg1_string_or_list_any[] = {arg_string_or_list_any};
-argcheck_T arg1_string_or_list_string[] = {arg_string_or_list_string};
-argcheck_T arg1_list_or_blob[] = {arg_list_or_blob};
-argcheck_T arg1_chan_or_job[] = {arg_chan_or_job};
-argcheck_T arg2_float_or_nr[] = {arg_float_or_nr, arg_float_or_nr};
-argcheck_T arg2_number[] = {arg_number, arg_number};
-argcheck_T arg2_string[] = {arg_string, arg_string};
-argcheck_T arg2_list_nr[] = {arg_list_number, arg_list_number};
-argcheck_T arg2_dict_string[] = {arg_dict_any, arg_string};
-argcheck_T arg2_dict_string_or_nr[] = {arg_dict_any, arg_string_or_nr};
-argcheck_T arg2_string_dict[] = {arg_string, arg_dict_any};
-argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
-argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any};
-argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
-argcheck_T arg3_string[] = {arg_string, arg_string, arg_string};
-argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
-argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool};
-argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number};
-argcheck_T arg2_execute[] = {arg_string_or_list_string, arg_string};
-argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string};
-argcheck_T arg2_setline[] = {arg_string_or_nr, arg_string_or_list_any};
-argcheck_T arg3_setbufline[] = {arg_string_or_nr, arg_string_or_nr, arg_string_or_list_any};
-argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
-argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3};
-argcheck_T arg3_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
+static argcheck_T arg1_string[] = {arg_string};
+static argcheck_T arg1_number[] = {arg_number};
+static argcheck_T arg1_bool[] = {arg_bool};
+static argcheck_T arg1_dict_any[] = {arg_dict_any};
+static argcheck_T arg1_job[] = {arg_job};
+static argcheck_T arg1_list_any[] = {arg_list_any};
+static argcheck_T arg1_list_nr[] = {arg_list_number};
+static argcheck_T arg1_list_string[] = {arg_list_string};
+static argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
+static argcheck_T arg1_string_or_nr[] = {arg_string_or_nr};
+static argcheck_T arg1_string_or_list_any[] = {arg_string_or_list_any};
+static argcheck_T arg1_string_or_list_string[] = {arg_string_or_list_string};
+static argcheck_T arg1_list_or_blob[] = {arg_list_or_blob};
+static argcheck_T arg1_list_or_dict[] = {arg_list_or_dict};
+static argcheck_T arg1_chan_or_job[] = {arg_chan_or_job};
+static argcheck_T arg2_float_or_nr[] = {arg_float_or_nr, arg_float_or_nr};
+static argcheck_T arg2_number[] = {arg_number, arg_number};
+static argcheck_T arg2_string[] = {arg_string, arg_string};
+static argcheck_T arg2_list_nr[] = {arg_list_number, arg_list_number};
+static argcheck_T arg2_nr_string[] = {arg_number, arg_string};
+static argcheck_T arg2_dict_string[] = {arg_dict_any, arg_string};
+static argcheck_T arg2_dict_string_or_nr[] = {arg_dict_any, arg_string_or_nr};
+static argcheck_T arg2_string_dict[] = {arg_string, arg_dict_any};
+static argcheck_T arg2_string_nr[] = {arg_string, arg_number};
+//static argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
+static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any};
+static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
+static argcheck_T arg2_chan_or_job_dict[] = {arg_chan_or_job, arg_dict_any};
+static argcheck_T arg2_nr_dict_any[] = {arg_number, arg_dict_any};
+//static argcheck_T arg2_string_number[] = {arg_string, arg_number};
+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_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 arg2_execute[] = {arg_string_or_list_string, arg_string};
+static argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string};
+static argcheck_T arg2_setline[] = {arg_string_or_nr, NULL};
+static argcheck_T arg3_setbufline[] = {arg_string_or_nr, arg_string_or_nr, arg_str_or_nr_or_list};
+static argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
+static argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3};
+static argcheck_T arg3_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
/*
* Functions that return the return type of a builtin function.
@@ -762,9 +787,9 @@ static funcentry_T global_functions[] =
ret_first_arg, f_add},
{"and", 2, 2, FEARG_1, arg2_number,
ret_number, f_and},
- {"append", 2, 2, FEARG_2, NULL,
+ {"append", 2, 2, FEARG_2, arg2_setline,
ret_number_bool, f_append},
- {"appendbufline", 3, 3, FEARG_3, NULL,
+ {"appendbufline", 3, 3, FEARG_3, arg3_setbufline,
ret_number_bool, f_appendbufline},
{"argc", 0, 1, 0, arg1_number,
ret_number, f_argc},
@@ -776,7 +801,7 @@ static funcentry_T global_functions[] =
ret_argv, f_argv},
{"asin", 1, 1, FEARG_1, arg1_float_or_nr,
ret_float, FLOAT_FUNC(f_asin)},
- {"assert_beeps", 1, 2, FEARG_1, NULL,
+ {"assert_beeps", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_assert_beeps},
{"assert_equal", 2, 3, FEARG_2, NULL,
ret_number_bool, f_assert_equal},
@@ -792,7 +817,7 @@ static funcentry_T global_functions[] =
ret_number_bool, f_assert_inrange},
{"assert_match", 2, 3, FEARG_2, arg3_string,
ret_number_bool, f_assert_match},
- {"assert_nobeep", 1, 2, FEARG_1, NULL,
+ {"assert_nobeep", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_assert_nobeep},
{"assert_notequal", 2, 3, FEARG_2, NULL,
ret_number_bool, f_assert_notequal},
@@ -860,9 +885,9 @@ static funcentry_T global_functions[] =
ret_number, f_bufwinnr},
{"byte2line", 1, 1, FEARG_1, arg1_number,
ret_number, f_byte2line},
- {"byteidx", 2, 2, FEARG_1, NULL,
+ {"byteidx", 2, 2, FEARG_1, arg2_string_nr,
ret_number, f_byteidx},
- {"byteidxcomp", 2, 2, FEARG_1, NULL,
+ {"byteidxcomp", 2, 2, FEARG_1, arg2_string_nr,
ret_number, f_byteidxcomp},
{"call", 2, 3, FEARG_1, NULL,
ret_any, f_call},
@@ -880,7 +905,7 @@ static funcentry_T global_functions[] =
ret_any, JOB_FUNC(f_ch_evalraw)},
{"ch_getbufnr", 2, 2, FEARG_1, NULL,
ret_number, JOB_FUNC(f_ch_getbufnr)},
- {"ch_getjob", 1, 1, FEARG_1, NULL,
+ {"ch_getjob", 1, 1, FEARG_1, arg1_chan_or_job,
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)},
@@ -890,19 +915,19 @@ static funcentry_T global_functions[] =
ret_void, JOB_FUNC(f_ch_logfile)},
{"ch_open", 1, 2, FEARG_1, arg2_string_dict,
ret_channel, JOB_FUNC(f_ch_open)},
- {"ch_read", 1, 2, FEARG_1, NULL,
+ {"ch_read", 1, 2, FEARG_1, arg2_chan_or_job_dict,
ret_string, JOB_FUNC(f_ch_read)},
- {"ch_readblob", 1, 2, FEARG_1, NULL,
+ {"ch_readblob", 1, 2, FEARG_1, arg2_chan_or_job_dict,
ret_blob, JOB_FUNC(f_ch_readblob)},
- {"ch_readraw", 1, 2, FEARG_1, NULL,
+ {"ch_readraw", 1, 2, FEARG_1, arg2_chan_or_job_dict,
ret_string, JOB_FUNC(f_ch_readraw)},
{"ch_sendexpr", 2, 3, FEARG_1, NULL,
ret_void, JOB_FUNC(f_ch_sendexpr)},
{"ch_sendraw", 2, 3, FEARG_1, NULL,
ret_void, JOB_FUNC(f_ch_sendraw)},
- {"ch_setoptions", 2, 2, FEARG_1, NULL,
+ {"ch_setoptions", 2, 2, FEARG_1, arg2_chan_or_job_dict,
ret_void, JOB_FUNC(f_ch_setoptions)},
- {"ch_status", 1, 2, FEARG_1, NULL,
+ {"ch_status", 1, 2, FEARG_1, arg2_chan_or_job_dict,
ret_string, JOB_FUNC(f_ch_status)},
{"changenr", 0, 0, 0, NULL,
ret_number, f_changenr},
@@ -964,7 +989,7 @@ static funcentry_T global_functions[] =
ret_number, f_diff_filler},
{"diff_hlID", 2, 2, FEARG_1, NULL,
ret_number, f_diff_hlID},
- {"echoraw", 1, 1, FEARG_1, NULL,
+ {"echoraw", 1, 1, FEARG_1, arg1_string,
ret_void, f_echoraw},
{"empty", 1, 1, FEARG_1, NULL,
ret_number_bool, f_empty},
@@ -1040,7 +1065,7 @@ static funcentry_T global_functions[] =
ret_func_any, f_funcref},
{"function", 1, 3, FEARG_1, NULL,
ret_f_function, f_function},
- {"garbagecollect", 0, 1, 0, NULL,
+ {"garbagecollect", 0, 1, 0, arg1_bool,
ret_void, f_garbagecollect},
{"get", 2, 3, FEARG_1, NULL,
ret_any, f_get},
@@ -1052,15 +1077,15 @@ static funcentry_T global_functions[] =
ret_any, f_getbufvar},
{"getchangelist", 0, 1, FEARG_1, arg1_string_or_nr,
ret_list_any, f_getchangelist},
- {"getchar", 0, 1, 0, NULL,
+ {"getchar", 0, 1, 0, arg1_bool,
ret_any, f_getchar},
{"getcharmod", 0, 0, 0, NULL,
ret_number, f_getcharmod},
- {"getcharpos", 1, 1, FEARG_1, NULL,
+ {"getcharpos", 1, 1, FEARG_1, arg1_string,
ret_list_number, f_getcharpos},
{"getcharsearch", 0, 0, 0, NULL,
ret_dict_any, f_getcharsearch},
- {"getcharstr", 0, 1, 0, NULL,
+ {"getcharstr", 0, 1, 0, arg1_bool,
ret_string, f_getcharstr},
{"getcmdline", 0, 0, 0, NULL,
ret_string, f_getcmdline},
@@ -1096,7 +1121,7 @@ static funcentry_T global_functions[] =
ret_list_any, f_getjumplist},
{"getline", 1, 2, FEARG_1, NULL,
ret_f_getline, f_getline},
- {"getloclist", 1, 2, 0, NULL,
+ {"getloclist", 1, 2, 0, arg2_nr_dict_any,
ret_list_or_dict_1, f_getloclist},
{"getmarklist", 0, 1, FEARG_1, arg1_string_or_nr,
ret_list_dict_any, f_getmarklist},
@@ -1108,7 +1133,7 @@ static funcentry_T global_functions[] =
ret_number, f_getpid},
{"getpos", 1, 1, FEARG_1, arg1_string,
ret_list_number, f_getpos},
- {"getqflist", 0, 1, 0, arg1_dict,
+ {"getqflist", 0, 1, 0, arg1_dict_any,
ret_list_or_dict_0, f_getqflist},
{"getreg", 0, 3, FEARG_1, NULL,
ret_getreg, f_getreg},
@@ -1158,7 +1183,7 @@ static funcentry_T global_functions[] =
ret_number_bool, f_histadd},
{"histdel", 1, 2, FEARG_1, NULL,
ret_number_bool, f_histdel},
- {"histget", 1, 2, FEARG_1, NULL,
+ {"histget", 1, 2, FEARG_1, arg2_string_nr,
ret_string, f_histget},
{"histnr", 1, 1, FEARG_1, arg1_string,
ret_number, f_histnr},
@@ -1196,21 +1221,21 @@ static funcentry_T global_functions[] =
ret_number_bool, f_isdirectory},
{"isinf", 1, 1, FEARG_1, arg1_float_or_nr,
ret_number, MATH_FUNC(f_isinf)},
- {"islocked", 1, 1, FEARG_1, NULL,
+ {"islocked", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_islocked},
{"isnan", 1, 1, FEARG_1, arg1_float_or_nr,
ret_number_bool, MATH_FUNC(f_isnan)},
- {"items", 1, 1, FEARG_1, arg1_dict,
+ {"items", 1, 1, FEARG_1, arg1_dict_any,
ret_list_items, f_items},
- {"job_getchannel", 1, 1, FEARG_1, NULL,
+ {"job_getchannel", 1, 1, FEARG_1, arg1_job,
ret_channel, JOB_FUNC(f_job_getchannel)},
- {"job_info", 0, 1, FEARG_1, NULL,
+ {"job_info", 0, 1, FEARG_1, arg1_job,
ret_job_info, JOB_FUNC(f_job_info)},
{"job_setoptions", 2, 2, FEARG_1, NULL,
ret_void, JOB_FUNC(f_job_setoptions)},
{"job_start", 1, 2, FEARG_1, NULL,
ret_job, JOB_FUNC(f_job_start)},
- {"job_status", 1, 1, FEARG_1, NULL,
+ {"job_status", 1, 1, FEARG_1, arg1_job,
ret_string, JOB_FUNC(f_job_status)},
{"job_stop", 1, 2, FEARG_1, NULL,
ret_number_bool, JOB_FUNC(f_job_stop)},
@@ -1224,7 +1249,7 @@ static funcentry_T global_functions[] =
ret_any, f_json_decode},
{"json_encode", 1, 1, FEARG_1, NULL,
ret_string, f_json_encode},
- {"keys", 1, 1, FEARG_1, arg1_dict,
+ {"keys", 1, 1, FEARG_1, arg1_dict_any,
ret_list_string, f_keys},
{"last_buffer_nr", 0, 0, 0, arg1_string_or_nr, // obsolete
ret_number, f_last_buffer_nr},
@@ -1234,7 +1259,7 @@ static funcentry_T global_functions[] =
ret_string, f_libcall},
{"libcallnr", 3, 3, FEARG_3, NULL,
ret_number, f_libcallnr},
- {"line", 1, 2, FEARG_1, NULL,
+ {"line", 1, 2, FEARG_1, arg2_string_nr,
ret_number, f_line},
{"line2byte", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_line2byte},
@@ -1294,7 +1319,7 @@ static funcentry_T global_functions[] =
ret_string, f_matchstr},
{"matchstrpos", 2, 4, FEARG_1, NULL,
ret_list_any, f_matchstrpos},
- {"max", 1, 1, FEARG_1, NULL,
+ {"max", 1, 1, FEARG_1, arg1_list_or_dict,
ret_number, f_max},
{"menu_info", 1, 2, FEARG_1, arg2_string,
ret_dict_any,
@@ -1304,13 +1329,13 @@ static funcentry_T global_functions[] =
NULL
#endif
},
- {"min", 1, 1, FEARG_1, NULL,
+ {"min", 1, 1, FEARG_1, arg1_list_or_dict,
ret_number, f_min},
{"mkdir", 1, 3, FEARG_1, arg3_string_string_nr,
ret_number_bool, f_mkdir},
- {"mode", 0, 1, FEARG_1, NULL,
+ {"mode", 0, 1, FEARG_1, arg1_bool,
ret_string, f_mode},
- {"mzeval", 1, 1, FEARG_1, NULL,
+ {"mzeval", 1, 1, FEARG_1, arg1_string,
ret_any,
#ifdef FEAT_MZSCHEME
f_mzeval
@@ -1324,9 +1349,9 @@ static funcentry_T global_functions[] =
ret_string, f_nr2char},
{"or", 2, 2, FEARG_1, arg2_number,
ret_number, f_or},
- {"pathshorten", 1, 2, FEARG_1, NULL,
+ {"pathshorten", 1, 2, FEARG_1, arg2_string_nr,
ret_string, f_pathshorten},
- {"perleval", 1, 1, FEARG_1, NULL,
+ {"perleval", 1, 1, FEARG_1, arg1_string,
ret_any,
#ifdef FEAT_PERL
f_perleval
@@ -1338,7 +1363,7 @@ static funcentry_T global_functions[] =
ret_number, PROP_FUNC(f_popup_atcursor)},
{"popup_beval", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict,
ret_number, PROP_FUNC(f_popup_beval)},
- {"popup_clear", 0, 1, 0, NULL,
+ {"popup_clear", 0, 1, 0, arg1_bool,
ret_void, PROP_FUNC(f_popup_clear)},
{"popup_close", 1, 2, FEARG_1, NULL,
ret_void, PROP_FUNC(f_popup_close)},
@@ -1346,19 +1371,19 @@ static funcentry_T global_functions[] =
ret_number, PROP_FUNC(f_popup_create)},
{"popup_dialog", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict,
ret_number, PROP_FUNC(f_popup_dialog)},
- {"popup_filter_menu", 2, 2, 0, NULL,
+ {"popup_filter_menu", 2, 2, 0, arg2_nr_string,
ret_bool, PROP_FUNC(f_popup_filter_menu)},
- {"popup_filter_yesno", 2, 2, 0, NULL,
+ {"popup_filter_yesno", 2, 2, 0, arg2_nr_string,
ret_bool, PROP_FUNC(f_popup_filter_yesno)},
{"popup_findinfo", 0, 0, 0, NULL,
ret_number, PROP_FUNC(f_popup_findinfo)},
{"popup_findpreview", 0, 0, 0, NULL,
ret_number, PROP_FUNC(f_popup_findpreview)},
- {"popup_getoptions", 1, 1, FEARG_1, NULL,
+ {"popup_getoptions", 1, 1, FEARG_1, arg1_number,
ret_dict_any, PROP_FUNC(f_popup_getoptions)},
- {"popup_getpos", 1, 1, FEARG_1, NULL,
+ {"popup_getpos", 1, 1, FEARG_1, arg1_number,
ret_dict_any, PROP_FUNC(f_popup_getpos)},
- {"popup_hide", 1, 1, FEARG_1, NULL,
+ {"popup_hide", 1, 1, FEARG_1, arg1_number,
ret_void, PROP_FUNC(f_popup_hide)},
{"popup_list", 0, 0, 0, NULL,
ret_list_number, PROP_FUNC(f_popup_list)},
@@ -1366,15 +1391,15 @@ static funcentry_T global_functions[] =
ret_number, PROP_FUNC(f_popup_locate)},
{"popup_menu", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict,
ret_number, PROP_FUNC(f_popup_menu)},
- {"popup_move", 2, 2, FEARG_1, NULL,
+ {"popup_move", 2, 2, FEARG_1, arg2_nr_dict_any,
ret_void, PROP_FUNC(f_popup_move)},
{"popup_notification", 2, 2, FEARG_1, arg2_str_or_nr_or_list_dict,
ret_number, PROP_FUNC(f_popup_notification)},
- {"popup_setoptions", 2, 2, FEARG_1, NULL,
+ {"popup_setoptions", 2, 2, FEARG_1, arg2_nr_dict_any,
ret_void, PROP_FUNC(f_popup_setoptions)},
{"popup_settext", 2, 2, FEARG_1, NULL,
ret_void, PROP_FUNC(f_popup_settext)},
- {"popup_show", 1, 1, FEARG_1, NULL,
+ {"popup_show", 1, 1, FEARG_1, arg1_number,
ret_void, PROP_FUNC(f_popup_show)},
{"pow", 2, 2, FEARG_1, arg2_float_or_nr,
ret_float, FLOAT_FUNC(f_pow)},
@@ -1396,7 +1421,7 @@ static funcentry_T global_functions[] =
ret_void, PROP_FUNC(f_prop_clear)},
{"prop_find", 1, 2, FEARG_1, arg2_dict_string,
ret_dict_any, PROP_FUNC(f_prop_find)},
- {"prop_list", 1, 2, FEARG_1, NULL,
+ {"prop_list", 1, 2, FEARG_1, arg2_nr_dict_any,
ret_list_dict_any, PROP_FUNC(f_prop_list)},
{"prop_remove", 1, 3, FEARG_1, NULL,
ret_number, PROP_FUNC(f_prop_remove)},
@@ -1408,13 +1433,13 @@ static funcentry_T global_functions[] =
ret_void, PROP_FUNC(f_prop_type_delete)},
{"prop_type_get", 1, 2, FEARG_1, arg2_string_dict,
ret_dict_any, PROP_FUNC(f_prop_type_get)},
- {"prop_type_list", 0, 1, FEARG_1, NULL,
+ {"prop_type_list", 0, 1, FEARG_1, arg1_dict_any,
ret_list_string, PROP_FUNC(f_prop_type_list)},
{"pum_getpos", 0, 0, 0, NULL,
ret_dict_number, f_pum_getpos},
{"pumvisible", 0, 0, 0, NULL,
ret_number_bool, f_pumvisible},
- {"py3eval", 1, 1, FEARG_1, NULL,
+ {"py3eval", 1, 1, FEARG_1, arg1_string,
ret_any,
#ifdef FEAT_PYTHON3
f_py3eval
@@ -1422,7 +1447,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
- {"pyeval", 1, 1, FEARG_1, NULL,
+ {"pyeval", 1, 1, FEARG_1, arg1_string,
ret_any,
#ifdef FEAT_PYTHON
f_pyeval
@@ -1430,7 +1455,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
- {"pyxeval", 1, 1, FEARG_1, NULL,
+ {"pyxeval", 1, 1, FEARG_1, arg1_string,
ret_any,
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
f_pyxeval
@@ -1468,7 +1493,7 @@ static funcentry_T global_functions[] =
ret_string, f_remote_foreground},
{"remote_peek", 1, 2, FEARG_1, arg2_string,
ret_number, f_remote_peek},
- {"remote_read", 1, 2, FEARG_1, NULL,
+ {"remote_read", 1, 2, FEARG_1, arg2_string_nr,
ret_string, f_remote_read},
{"remote_send", 2, 3, FEARG_1, NULL,
ret_string, f_remote_send},
@@ -1486,7 +1511,7 @@ static funcentry_T global_functions[] =
ret_first_arg, f_reverse},
{"round", 1, 1, FEARG_1, arg1_float_or_nr,
ret_float, FLOAT_FUNC(f_round)},
- {"rubyeval", 1, 1, FEARG_1, NULL,
+ {"rubyeval", 1, 1, FEARG_1, arg1_string,
ret_any,
#ifdef FEAT_RUBY
f_rubyeval
@@ -1510,7 +1535,7 @@ static funcentry_T global_functions[] =
ret_string, f_screenstring},
{"search", 1, 5, FEARG_1, NULL,
ret_number, f_search},
- {"searchcount", 0, 1, FEARG_1, arg1_dict,
+ {"searchcount", 0, 1, FEARG_1, arg1_dict_any,
ret_dict_any, f_searchcount},
{"searchdecl", 1, 3, FEARG_1, NULL,
ret_number_bool, f_searchdecl},
@@ -1524,15 +1549,15 @@ static funcentry_T global_functions[] =
ret_number_bool, f_server2client},
{"serverlist", 0, 0, 0, NULL,
ret_string, f_serverlist},
- {"setbufline", 3, 3, FEARG_3, NULL,
+ {"setbufline", 3, 3, FEARG_3, arg3_setbufline,
ret_number_bool, f_setbufline},
{"setbufvar", 3, 3, FEARG_3, NULL,
ret_void, f_setbufvar},
- {"setcellwidths", 1, 1, FEARG_1, NULL,
+ {"setcellwidths", 1, 1, FEARG_1, arg1_list_any,
ret_void, f_setcellwidths},
{"setcharpos", 2, 2, FEARG_2, NULL,
ret_number_bool, f_setcharpos},
- {"setcharsearch", 1, 1, FEARG_1, arg1_dict,
+ {"setcharsearch", 1, 1, FEARG_1, arg1_dict_any,
ret_void, f_setcharsearch},
{"setcmdpos", 1, 1, FEARG_1, arg1_number,
ret_number_bool, f_setcmdpos},
@@ -1542,7 +1567,7 @@ static funcentry_T global_functions[] =
ret_void, f_setenv},
{"setfperm", 2, 2, FEARG_1, arg2_string,
ret_number_bool, f_setfperm},
- {"setline", 2, 2, FEARG_2, NULL,
+ {"setline", 2, 2, FEARG_2, arg2_setline,
ret_number_bool, f_setline},
{"setloclist", 2, 4, FEARG_2, NULL,
ret_number_bool, f_setloclist},
@@ -1576,7 +1601,7 @@ static funcentry_T global_functions[] =
ret_number, f_shiftwidth},
{"sign_define", 1, 2, FEARG_1, arg2_string_or_list_dict,
ret_any, SIGN_FUNC(f_sign_define)},
- {"sign_getdefined", 0, 1, FEARG_1, NULL,
+ {"sign_getdefined", 0, 1, FEARG_1, arg1_string,
ret_list_dict_any, SIGN_FUNC(f_sign_getdefined)},
{"sign_getplaced", 0, 2, FEARG_1, NULL,
ret_list_dict_any, SIGN_FUNC(f_sign_getplaced)},
@@ -1584,13 +1609,13 @@ static funcentry_T global_functions[] =
ret_number, SIGN_FUNC(f_sign_jump)},
{"sign_place", 4, 5, FEARG_1, NULL,
ret_number, SIGN_FUNC(f_sign_place)},
- {"sign_placelist", 1, 1, FEARG_1, NULL,
+ {"sign_placelist", 1, 1, FEARG_1, arg1_list_any,
ret_list_number, SIGN_FUNC(f_sign_placelist)},
{"sign_undefine", 0, 1, FEARG_1, arg1_string_or_list_string,
ret_number_bool, SIGN_FUNC(f_sign_undefine)},
{"sign_unplace", 1, 2, FEARG_1, arg2_string_dict,
ret_number_bool, SIGN_FUNC(f_sign_unplace)},
- {"sign_unplacelist", 1, 2, FEARG_1, NULL,
+ {"sign_unplacelist", 1, 2, FEARG_1, arg1_list_any,
ret_list_number, SIGN_FUNC(f_sign_unplacelist)},
{"simplify", 1, 1, FEARG_1, arg1_string,
ret_string, f_simplify},
@@ -1630,15 +1655,15 @@ static funcentry_T global_functions[] =
ret_list_number, f_str2list},
{"str2nr", 1, 3, FEARG_1, arg3_string_nr_bool,
ret_number, f_str2nr},
- {"strcharlen", 1, 1, FEARG_1, NULL,
+ {"strcharlen", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_strcharlen},
{"strcharpart", 2, 4, FEARG_1, NULL,
ret_string, f_strcharpart},
{"strchars", 1, 2, FEARG_1, NULL,
ret_number, f_strchars},
- {"strdisplaywidth", 1, 2, FEARG_1, NULL,
+ {"strdisplaywidth", 1, 2, FEARG_1, arg2_string_nr,
ret_number, f_strdisplaywidth},
- {"strftime", 1, 2, FEARG_1, NULL,
+ {"strftime", 1, 2, FEARG_1, arg2_string_nr,
ret_string,
#ifdef HAVE_STRFTIME
f_strftime
@@ -1646,7 +1671,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
- {"strgetchar", 2, 2, FEARG_1, NULL,
+ {"strgetchar", 2, 2, FEARG_1, arg2_string_nr,
ret_number, f_strgetchar},
{"stridx", 2, 3, FEARG_1, arg3_string_string_nr,
ret_number, f_stridx},
@@ -1696,7 +1721,7 @@ static funcentry_T global_functions[] =
ret_list_number, f_tabpagebuflist},
{"tabpagenr", 0, 1, 0, arg1_string,
ret_number, f_tabpagenr},
- {"tabpagewinnr", 1, 2, FEARG_1, NULL,
+ {"tabpagewinnr", 1, 2, FEARG_1, arg2_nr_string,
ret_number, f_tabpagewinnr},
{"tagfiles", 0, 0, 0, NULL,
ret_list_string, f_tagfiles},
@@ -1724,7 +1749,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
- {"term_getattr", 2, 2, FEARG_1, NULL,
+ {"term_getattr", 2, 2, FEARG_1, arg2_nr_string,
ret_number, TERM_FUNC(f_term_getattr)},
{"term_getcursor", 1, 1, FEARG_1, arg1_string_or_nr,
ret_list_any, TERM_FUNC(f_term_getcursor)},
@@ -1806,7 +1831,7 @@ static funcentry_T global_functions[] =
ret_string, f_test_null_string},
{"test_option_not_set", 1, 1, FEARG_1, arg1_string,
ret_void, f_test_option_not_set},
- {"test_override", 2, 2, FEARG_2, NULL,
+ {"test_override", 2, 2, FEARG_2, arg2_string_nr,
ret_void, f_test_override},
{"test_refcount", 1, 1, FEARG_1, NULL,
ret_number, f_test_refcount},
@@ -1858,11 +1883,11 @@ static funcentry_T global_functions[] =
ret_dict_any, f_undotree},
{"uniq", 1, 3, FEARG_1, NULL,
ret_list_any, f_uniq},
- {"values", 1, 1, FEARG_1, arg1_dict,
+ {"values", 1, 1, FEARG_1, arg1_dict_any,
ret_list_any, f_values},
{"virtcol", 1, 1, FEARG_1, arg1_string_or_list_any,
ret_number, f_virtcol},
- {"visualmode", 0, 1, 0, NULL,
+ {"visualmode", 0, 1, 0, arg1_bool,
ret_string, f_visualmode},
{"wildmenumode", 0, 0, 0, NULL,
ret_number, f_wildmenumode},
@@ -1900,7 +1925,7 @@ static funcentry_T global_functions[] =
ret_number, f_winnr},
{"winrestcmd", 0, 0, 0, NULL,
ret_string, f_winrestcmd},
- {"winrestview", 1, 1, FEARG_1, arg1_dict,
+ {"winrestview", 1, 1, FEARG_1, arg1_dict_any,
ret_void, f_winrestview},
{"winsaveview", 0, 0, 0, NULL,
ret_dict_number, f_winsaveview},
@@ -2763,8 +2788,12 @@ f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
static void
f_echoraw(typval_T *argvars, typval_T *rettv UNUSED)
{
- char_u *str = tv_get_string_chk(&argvars[0]);
+ char_u *str;
+
+ if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+ return;
+ str = tv_get_string_chk(&argvars[0]);
if (str != NULL && *str != NUL)
{
out_str(str);
@@ -5956,6 +5985,10 @@ f_islocked(typval_T *argvars, typval_T *rettv)
dictitem_T *di;
rettv->vval.v_number = -1;
+
+ if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+ return;
+
end = get_lval(tv_get_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
GLV_NO_AUTOLOAD | GLV_READ_ONLY, FNE_CHECK_START);
if (end != NULL && lv.ll_name != NULL)
@@ -6122,6 +6155,12 @@ f_line(typval_T *argvars, typval_T *rettv)
win_T *save_curwin;
tabpage_T *save_curtab;
+ if (in_vim9script()
+ && (check_for_string_arg(argvars, 0) == FAIL
+ || (argvars[1].v_type != VAR_UNKNOWN
+ && check_for_number_arg(argvars, 1) == FAIL)))
+ return;
+
if (argvars[1].v_type != VAR_UNKNOWN)
{
// use window specified in the second argument
diff --git a/src/evalwindow.c b/src/evalwindow.c
index 0e1a202da3..329413d0bd 100644
--- a/src/evalwindow.c
+++ b/src/evalwindow.c
@@ -653,6 +653,12 @@ f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv)
int nr = 1;
tabpage_T *tp;
+ if (in_vim9script()
+ && (check_for_number_arg(argvars, 0) == FAIL
+ || (argvars[1].v_type != VAR_UNKNOWN
+ && check_for_string_arg(argvars, 1) == FAIL)))
+ return;
+
tp = find_tabpage((int)tv_get_number(&argvars[0]));
if (tp == NULL)
nr = 0;
diff --git a/src/filepath.c b/src/filepath.c
index 0e29977227..40b5761aee 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -1447,6 +1447,12 @@ f_pathshorten(typval_T *argvars, typval_T *rettv)
char_u *p;
int trim_len = 1;
+ if (in_vim9script()
+ && (check_for_string_arg(argvars, 0) == FAIL
+ || (argvars[1].v_type != VAR_UNKNOWN
+ && check_for_number_arg(argvars, 1) == FAIL)))
+ return;
+
if (argvars[1].v_type != VAR_UNKNOWN)
{
trim_len = (int)tv_get_number(&argvars[1]);
diff --git a/src/globals.h b/src/globals.h
index 54ecb8e1f0..e486b6ea13 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1698,6 +1698,7 @@ EXTERN char e_cannot_mod[] INIT(= N_("E995: Cannot modify existing variable"));
EXTERN char e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%s\""));
EXTERN char e_readonlysbx[] INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\""));
EXTERN char e_stringreq[] INIT(= N_("E928: String required"));