diff options
-rw-r--r-- | src/channel.c | 5 | ||||
-rw-r--r-- | src/errors.h | 2 | ||||
-rw-r--r-- | src/evalfunc.c | 164 | ||||
-rw-r--r-- | src/proto/typval.pro | 1 | ||||
-rw-r--r-- | src/terminal.c | 5 | ||||
-rw-r--r-- | src/testdir/test_search.vim | 12 | ||||
-rw-r--r-- | src/testdir/test_textprop.vim | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_builtin.vim | 524 | ||||
-rw-r--r-- | src/testing.c | 5 | ||||
-rw-r--r-- | src/textprop.c | 2 | ||||
-rw-r--r-- | src/typval.c | 25 | ||||
-rw-r--r-- | src/version.c | 2 |
12 files changed, 563 insertions, 186 deletions
diff --git a/src/channel.c b/src/channel.c index 65757f1d7e..c0572d3311 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1311,6 +1311,11 @@ channel_open_func(typval_T *argvars) jobopt_T opt; channel_T *channel = NULL; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_dict_arg(argvars, 1) == FAIL)) + return NULL; + address = tv_get_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN && (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL)) diff --git a/src/errors.h b/src/errors.h index 3a76d9e959..14c5b8def8 100644 --- a/src/errors.h +++ b/src/errors.h @@ -492,3 +492,5 @@ EXTERN char e_regexp_number_after_dot_pos_search[] INIT(= N_("E1204: No Number allowed after .: '\\%%%c'")); EXTERN char e_no_white_space_allowed_between_option_and[] INIT(= N_("E1205: No white space allowed between option and")); +EXTERN char e_dict_required_for_argument_nr[] + INIT(= N_("E1206: Dictionary required for argument %d")); diff --git a/src/evalfunc.c b/src/evalfunc.c index bdfb570882..10477d1ca3 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -375,6 +375,18 @@ arg_list_or_dict(type_T *type, argcontext_T *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) + return OK; + arg_type_mismatch(&t_channel, type, context->arg_idx + 1); + return FAIL; +} + +/* * Check "type" is the same type as the previous argument. * Must not be used for the first argcheck_T entry. */ @@ -444,15 +456,19 @@ arg_extend3(type_T *type, argcontext_T *context) argcheck_T arg1_string[] = {arg_string}; argcheck_T arg1_number[] = {arg_number}; argcheck_T arg1_dict[] = {arg_dict_any}; -argcheck_T arg1_list_number[] = {arg_list_number}; -argcheck_T arg1_string_list[] = {arg_list_string}; +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[] = {arg_string_or_list}; +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_number[] = {arg_list_number, arg_list_number}; +argcheck_T arg2_list_nr[] = {arg_list_number, arg_list_number}; +argcheck_T arg2_dict_string[] = {arg_dict_any, arg_string}; +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_execute[] = {arg_string_or_list, arg_string}; argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3}; @@ -460,6 +476,7 @@ argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_e 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 arg3_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number}; /* @@ -750,9 +767,9 @@ static funcentry_T global_functions[] = ret_number_bool, f_assert_beeps}, {"assert_equal", 2, 3, FEARG_2, NULL, ret_number_bool, f_assert_equal}, - {"assert_equalfile", 2, 3, FEARG_1, NULL, + {"assert_equalfile", 2, 3, FEARG_1, arg3_string, ret_number_bool, f_assert_equalfile}, - {"assert_exception", 1, 2, 0, NULL, + {"assert_exception", 1, 2, 0, arg2_string, ret_number_bool, f_assert_exception}, {"assert_fails", 1, 5, FEARG_1, NULL, ret_number_bool, f_assert_fails}, @@ -760,13 +777,13 @@ static funcentry_T global_functions[] = ret_number_bool, f_assert_false}, {"assert_inrange", 3, 4, FEARG_3, NULL, ret_number_bool, f_assert_inrange}, - {"assert_match", 2, 3, FEARG_2, NULL, + {"assert_match", 2, 3, FEARG_2, arg3_string, ret_number_bool, f_assert_match}, {"assert_nobeep", 1, 2, FEARG_1, NULL, ret_number_bool, f_assert_nobeep}, {"assert_notequal", 2, 3, FEARG_2, NULL, ret_number_bool, f_assert_notequal}, - {"assert_notmatch", 2, 3, FEARG_2, NULL, + {"assert_notmatch", 2, 3, FEARG_2, arg3_string, ret_number_bool, f_assert_notmatch}, {"assert_report", 1, 1, FEARG_1, NULL, ret_number_bool, f_assert_report}, @@ -802,7 +819,7 @@ static funcentry_T global_functions[] = }, {"browse", 4, 4, 0, NULL, ret_string, f_browse}, - {"browsedir", 2, 2, 0, NULL, + {"browsedir", 2, 2, 0, arg2_string, ret_string, f_browsedir}, {"bufadd", 1, 1, FEARG_1, arg1_string, ret_number, f_bufadd}, @@ -838,11 +855,11 @@ static funcentry_T global_functions[] = ret_any, f_call}, {"ceil", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, FLOAT_FUNC(f_ceil)}, - {"ch_canread", 1, 1, FEARG_1, NULL, + {"ch_canread", 1, 1, FEARG_1, arg1_chan_or_job, ret_number_bool, JOB_FUNC(f_ch_canread)}, - {"ch_close", 1, 1, FEARG_1, NULL, + {"ch_close", 1, 1, FEARG_1, arg1_chan_or_job, ret_void, JOB_FUNC(f_ch_close)}, - {"ch_close_in", 1, 1, FEARG_1, NULL, + {"ch_close_in", 1, 1, FEARG_1, arg1_chan_or_job, ret_void, JOB_FUNC(f_ch_close_in)}, {"ch_evalexpr", 2, 3, FEARG_1, NULL, ret_any, JOB_FUNC(f_ch_evalexpr)}, @@ -852,13 +869,13 @@ static funcentry_T global_functions[] = ret_number, JOB_FUNC(f_ch_getbufnr)}, {"ch_getjob", 1, 1, FEARG_1, NULL, ret_job, JOB_FUNC(f_ch_getjob)}, - {"ch_info", 1, 1, FEARG_1, NULL, + {"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, ret_void, JOB_FUNC(f_ch_log)}, - {"ch_logfile", 1, 2, FEARG_1, NULL, + {"ch_logfile", 1, 2, FEARG_1, arg2_string, ret_void, JOB_FUNC(f_ch_logfile)}, - {"ch_open", 1, 2, FEARG_1, NULL, + {"ch_open", 1, 2, FEARG_1, arg2_string_dict, ret_channel, JOB_FUNC(f_ch_open)}, {"ch_read", 1, 2, FEARG_1, NULL, ret_string, JOB_FUNC(f_ch_read)}, @@ -880,9 +897,9 @@ static funcentry_T global_functions[] = ret_number, f_char2nr}, {"charclass", 1, 1, FEARG_1, arg1_string, ret_number, f_charclass}, - {"charcol", 1, 1, FEARG_1, NULL, + {"charcol", 1, 1, FEARG_1, arg1_string_or_list, ret_number, f_charcol}, - {"charidx", 2, 3, FEARG_1, NULL, + {"charidx", 2, 3, FEARG_1, arg3_string_nr_bool, ret_number, f_charidx}, {"chdir", 1, 1, FEARG_1, arg1_string, ret_string, f_chdir}, @@ -890,7 +907,7 @@ static funcentry_T global_functions[] = ret_number, f_cindent}, {"clearmatches", 0, 1, FEARG_1, arg1_number, ret_void, f_clearmatches}, - {"col", 1, 1, FEARG_1, NULL, + {"col", 1, 1, FEARG_1, arg1_string_or_list, ret_number, f_col}, {"complete", 2, 2, FEARG_2, NULL, ret_void, f_complete}, @@ -898,7 +915,7 @@ static funcentry_T global_functions[] = ret_number, f_complete_add}, {"complete_check", 0, 0, 0, NULL, ret_number_bool, f_complete_check}, - {"complete_info", 0, 1, FEARG_1, arg1_string_list, + {"complete_info", 0, 1, FEARG_1, arg1_list_string, ret_dict_any, f_complete_info}, {"confirm", 1, 4, FEARG_1, NULL, ret_number, f_confirm}, @@ -924,7 +941,7 @@ static funcentry_T global_functions[] = }, {"deepcopy", 1, 2, FEARG_1, NULL, ret_first_arg, f_deepcopy}, - {"delete", 1, 2, FEARG_1, NULL, + {"delete", 1, 2, FEARG_1, arg2_string, ret_number_bool, f_delete}, {"deletebufline", 2, 3, FEARG_1, NULL, ret_number_bool, f_deletebufline}, @@ -974,9 +991,9 @@ static funcentry_T global_functions[] = ret_number, f_filewritable}, {"filter", 2, 2, FEARG_1, NULL, ret_first_arg, f_filter}, - {"finddir", 1, 3, FEARG_1, NULL, + {"finddir", 1, 3, FEARG_1, arg3_string_string_nr, ret_string, f_finddir}, - {"findfile", 1, 3, FEARG_1, NULL, + {"findfile", 1, 3, FEARG_1, arg3_string_string_nr, ret_string, f_findfile}, {"flatten", 1, 2, FEARG_1, NULL, ret_list_any, f_flatten}, @@ -1114,7 +1131,7 @@ static funcentry_T global_functions[] = ret_any, f_globpath}, {"has", 1, 2, 0, NULL, ret_number_bool, f_has}, - {"has_key", 2, 2, FEARG_1, NULL, + {"has_key", 2, 2, FEARG_1, arg2_dict_string, ret_number_bool, f_has_key}, {"haslocaldir", 0, 2, FEARG_1, arg2_number, ret_number, f_haslocaldir}, @@ -1140,15 +1157,15 @@ static funcentry_T global_functions[] = ret_string, f_hostname}, {"iconv", 3, 3, FEARG_1, arg3_string, ret_string, f_iconv}, - {"indent", 1, 1, FEARG_1, NULL, + {"indent", 1, 1, FEARG_1, arg1_string_or_nr, ret_number, f_indent}, {"index", 2, 4, FEARG_1, NULL, ret_number, f_index}, - {"input", 1, 3, FEARG_1, NULL, + {"input", 1, 3, FEARG_1, arg3_string, ret_string, f_input}, - {"inputdialog", 1, 3, FEARG_1, NULL, + {"inputdialog", 1, 3, FEARG_1, arg3_string, ret_string, f_inputdialog}, - {"inputlist", 1, 1, FEARG_1, arg1_string_list, + {"inputlist", 1, 1, FEARG_1, arg1_list_string, ret_number, f_inputlist}, {"inputrestore", 0, 0, 0, NULL, ret_number_bool, f_inputrestore}, @@ -1196,7 +1213,7 @@ static funcentry_T global_functions[] = ret_string, f_json_encode}, {"keys", 1, 1, FEARG_1, arg1_dict, ret_list_string, f_keys}, - {"last_buffer_nr", 0, 0, 0, NULL, // obsolete + {"last_buffer_nr", 0, 0, 0, arg1_string_or_nr, // obsolete ret_number, f_last_buffer_nr}, {"len", 1, 1, FEARG_1, NULL, ret_number, f_len}, @@ -1214,7 +1231,7 @@ static funcentry_T global_functions[] = ret_string, f_list2str}, {"listener_add", 1, 2, FEARG_2, NULL, ret_number, f_listener_add}, - {"listener_flush", 0, 1, FEARG_1, NULL, + {"listener_flush", 0, 1, FEARG_1, arg1_string_or_nr, ret_void, f_listener_flush}, {"listener_remove", 1, 1, FEARG_1, arg1_number, ret_number_bool, f_listener_remove}, @@ -1276,7 +1293,7 @@ static funcentry_T global_functions[] = }, {"min", 1, 1, FEARG_1, NULL, ret_number, f_min}, - {"mkdir", 1, 3, FEARG_1, NULL, + {"mkdir", 1, 3, FEARG_1, arg3_string_string_nr, ret_number_bool, f_mkdir}, {"mode", 0, 1, FEARG_1, NULL, ret_string, f_mode}, @@ -1332,7 +1349,7 @@ static funcentry_T global_functions[] = ret_void, PROP_FUNC(f_popup_hide)}, {"popup_list", 0, 0, 0, NULL, ret_list_number, PROP_FUNC(f_popup_list)}, - {"popup_locate", 2, 2, 0, NULL, + {"popup_locate", 2, 2, 0, arg2_number, ret_number, PROP_FUNC(f_popup_locate)}, {"popup_menu", 2, 2, FEARG_1, NULL, ret_number, PROP_FUNC(f_popup_menu)}, @@ -1364,19 +1381,19 @@ static funcentry_T global_functions[] = ret_void, PROP_FUNC(f_prop_add)}, {"prop_clear", 1, 3, FEARG_1, NULL, ret_void, PROP_FUNC(f_prop_clear)}, - {"prop_find", 1, 2, FEARG_1, NULL, + {"prop_find", 1, 2, FEARG_1, arg2_dict_string, ret_dict_any, PROP_FUNC(f_prop_find)}, {"prop_list", 1, 2, FEARG_1, NULL, ret_list_dict_any, PROP_FUNC(f_prop_list)}, {"prop_remove", 1, 3, FEARG_1, NULL, ret_number, PROP_FUNC(f_prop_remove)}, - {"prop_type_add", 2, 2, FEARG_1, NULL, + {"prop_type_add", 2, 2, FEARG_1, arg2_string_dict, ret_void, PROP_FUNC(f_prop_type_add)}, - {"prop_type_change", 2, 2, FEARG_1, NULL, + {"prop_type_change", 2, 2, FEARG_1, arg2_string_dict, ret_void, PROP_FUNC(f_prop_type_change)}, - {"prop_type_delete", 1, 2, FEARG_1, NULL, + {"prop_type_delete", 1, 2, FEARG_1, arg2_string_dict, ret_void, PROP_FUNC(f_prop_type_delete)}, - {"prop_type_get", 1, 2, FEARG_1, NULL, + {"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, ret_list_string, PROP_FUNC(f_prop_type_list)}, @@ -1408,9 +1425,9 @@ static funcentry_T global_functions[] = NULL #endif }, - {"rand", 0, 1, FEARG_1, arg1_list_number, + {"rand", 0, 1, FEARG_1, arg1_list_nr, ret_number, f_rand}, - {"range", 1, 3, FEARG_1, NULL, + {"range", 1, 3, FEARG_1, arg3_number, ret_list_number, f_range}, {"readblob", 1, 1, FEARG_1, arg1_string, ret_blob, f_readblob}, @@ -1418,7 +1435,7 @@ static funcentry_T global_functions[] = ret_list_string, f_readdir}, {"readdirex", 1, 3, FEARG_1, NULL, ret_list_dict_any, f_readdirex}, - {"readfile", 1, 3, FEARG_1, NULL, + {"readfile", 1, 3, FEARG_1, arg3_string_string_nr, ret_list_string, f_readfile}, {"reduce", 2, 3, FEARG_1, NULL, ret_any, f_reduce}, @@ -1426,17 +1443,17 @@ static funcentry_T global_functions[] = ret_string, f_reg_executing}, {"reg_recording", 0, 0, 0, NULL, ret_string, f_reg_recording}, - {"reltime", 0, 2, FEARG_1, arg2_list_number, + {"reltime", 0, 2, FEARG_1, arg2_list_nr, ret_list_any, f_reltime}, - {"reltimefloat", 1, 1, FEARG_1, arg1_list_number, + {"reltimefloat", 1, 1, FEARG_1, arg1_list_nr, ret_float, FLOAT_FUNC(f_reltimefloat)}, - {"reltimestr", 1, 1, FEARG_1, arg1_list_number, + {"reltimestr", 1, 1, FEARG_1, arg1_list_nr, ret_string, f_reltimestr}, {"remote_expr", 2, 4, FEARG_1, NULL, ret_string, f_remote_expr}, {"remote_foreground", 1, 1, FEARG_1, arg1_string, ret_string, f_remote_foreground}, - {"remote_peek", 1, 2, FEARG_1, NULL, + {"remote_peek", 1, 2, FEARG_1, arg2_string, ret_number, f_remote_peek}, {"remote_read", 1, 2, FEARG_1, NULL, ret_string, f_remote_read}, @@ -1452,7 +1469,7 @@ static funcentry_T global_functions[] = ret_first_arg, f_repeat}, {"resolve", 1, 1, FEARG_1, arg1_string, ret_string, f_resolve}, - {"reverse", 1, 1, FEARG_1, NULL, + {"reverse", 1, 1, FEARG_1, arg1_list_or_blob, ret_first_arg, f_reverse}, {"round", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, FLOAT_FUNC(f_round)}, @@ -1490,7 +1507,7 @@ static funcentry_T global_functions[] = ret_list_number, f_searchpairpos}, {"searchpos", 1, 5, FEARG_1, NULL, ret_list_number, f_searchpos}, - {"server2client", 2, 2, FEARG_1, NULL, + {"server2client", 2, 2, FEARG_1, arg2_string, ret_number_bool, f_server2client}, {"serverlist", 0, 0, 0, NULL, ret_string, f_serverlist}, @@ -1544,7 +1561,7 @@ static funcentry_T global_functions[] = ret_string, f_shellescape}, {"shiftwidth", 0, 1, FEARG_1, arg1_number, ret_number, f_shiftwidth}, - {"sign_define", 1, 2, FEARG_1, NULL, + {"sign_define", 1, 2, FEARG_1, arg2_string_dict, ret_any, SIGN_FUNC(f_sign_define)}, {"sign_getdefined", 0, 1, FEARG_1, NULL, ret_list_dict_any, SIGN_FUNC(f_sign_getdefined)}, @@ -1556,9 +1573,9 @@ static funcentry_T global_functions[] = ret_number, SIGN_FUNC(f_sign_place)}, {"sign_placelist", 1, 1, FEARG_1, NULL, ret_list_number, SIGN_FUNC(f_sign_placelist)}, - {"sign_undefine", 0, 1, FEARG_1, NULL, + {"sign_undefine", 0, 1, FEARG_1, arg1_string_or_list, ret_number_bool, SIGN_FUNC(f_sign_undefine)}, - {"sign_unplace", 1, 2, FEARG_1, NULL, + {"sign_unplace", 1, 2, FEARG_1, arg2_string_dict, ret_number_bool, SIGN_FUNC(f_sign_unplace)}, {"sign_unplacelist", 1, 2, FEARG_1, NULL, ret_list_number, SIGN_FUNC(f_sign_unplacelist)}, @@ -1618,7 +1635,7 @@ static funcentry_T global_functions[] = }, {"strgetchar", 2, 2, FEARG_1, NULL, ret_number, f_strgetchar}, - {"stridx", 2, 3, FEARG_1, NULL, + {"stridx", 2, 3, FEARG_1, arg3_string_string_nr, ret_number, f_stridx}, {"string", 1, 1, FEARG_1, NULL, ret_string, f_string}, @@ -1634,7 +1651,7 @@ static funcentry_T global_functions[] = NULL #endif }, - {"strridx", 2, 3, FEARG_1, NULL, + {"strridx", 2, 3, FEARG_1, arg3_string_string_nr, ret_number, f_strridx}, {"strtrans", 1, 1, FEARG_1, arg1_string, ret_string, f_strtrans}, @@ -1670,7 +1687,7 @@ static funcentry_T global_functions[] = ret_number, f_tabpagewinnr}, {"tagfiles", 0, 0, 0, NULL, ret_list_string, f_tagfiles}, - {"taglist", 1, 2, FEARG_1, NULL, + {"taglist", 1, 2, FEARG_1, arg2_string, ret_list_dict_any, f_taglist}, {"tan", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, FLOAT_FUNC(f_tan)}, @@ -1680,13 +1697,13 @@ static funcentry_T global_functions[] = ret_string, f_tempname}, {"term_dumpdiff", 2, 3, FEARG_1, NULL, ret_number, TERM_FUNC(f_term_dumpdiff)}, - {"term_dumpload", 1, 2, FEARG_1, NULL, + {"term_dumpload", 1, 2, FEARG_1, arg2_string_dict, ret_number, TERM_FUNC(f_term_dumpload)}, {"term_dumpwrite", 2, 3, FEARG_2, NULL, ret_void, TERM_FUNC(f_term_dumpwrite)}, - {"term_getaltscreen", 1, 1, FEARG_1, NULL, + {"term_getaltscreen", 1, 1, FEARG_1, arg1_string_or_nr, ret_number, TERM_FUNC(f_term_getaltscreen)}, - {"term_getansicolors", 1, 1, FEARG_1, NULL, + {"term_getansicolors", 1, 1, FEARG_1, arg1_string_or_nr, ret_list_string, #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) f_term_getansicolors @@ -1696,19 +1713,19 @@ static funcentry_T global_functions[] = }, {"term_getattr", 2, 2, FEARG_1, NULL, ret_number, TERM_FUNC(f_term_getattr)}, - {"term_getcursor", 1, 1, FEARG_1, NULL, + {"term_getcursor", 1, 1, FEARG_1, arg1_string_or_nr, ret_list_any, TERM_FUNC(f_term_getcursor)}, - {"term_getjob", 1, 1, FEARG_1, NULL, + {"term_getjob", 1, 1, FEARG_1, arg1_string_or_nr, ret_job, TERM_FUNC(f_term_getjob)}, {"term_getline", 2, 2, FEARG_1, NULL, ret_string, TERM_FUNC(f_term_getline)}, - {"term_getscrolled", 1, 1, FEARG_1, NULL, + {"term_getscrolled", 1, 1, FEARG_1, arg1_string_or_nr, ret_number, TERM_FUNC(f_term_getscrolled)}, - {"term_getsize", 1, 1, FEARG_1, NULL, + {"term_getsize", 1, 1, FEARG_1, arg1_string_or_nr, ret_list_number, TERM_FUNC(f_term_getsize)}, - {"term_getstatus", 1, 1, FEARG_1, NULL, + {"term_getstatus", 1, 1, FEARG_1, arg1_string_or_nr, ret_string, TERM_FUNC(f_term_getstatus)}, - {"term_gettitle", 1, 1, FEARG_1, NULL, + {"term_gettitle", 1, 1, FEARG_1, arg1_string_or_nr, ret_string, TERM_FUNC(f_term_gettitle)}, {"term_gettty", 1, 2, FEARG_1, NULL, ret_string, TERM_FUNC(f_term_gettty)}, @@ -1740,23 +1757,23 @@ static funcentry_T global_functions[] = ret_void, TERM_FUNC(f_term_wait)}, {"terminalprops", 0, 0, 0, NULL, ret_dict_string, f_terminalprops}, - {"test_alloc_fail", 3, 3, FEARG_1, NULL, + {"test_alloc_fail", 3, 3, FEARG_1, arg3_number, ret_void, f_test_alloc_fail}, {"test_autochdir", 0, 0, 0, NULL, ret_void, f_test_autochdir}, - {"test_feedinput", 1, 1, FEARG_1, NULL, + {"test_feedinput", 1, 1, FEARG_1, arg1_string, ret_void, f_test_feedinput}, {"test_garbagecollect_now", 0, 0, 0, NULL, ret_void, f_test_garbagecollect_now}, {"test_garbagecollect_soon", 0, 0, 0, NULL, ret_void, f_test_garbagecollect_soon}, - {"test_getvalue", 1, 1, FEARG_1, NULL, + {"test_getvalue", 1, 1, FEARG_1, arg1_string, ret_number, f_test_getvalue}, {"test_gui_drop_files", 4, 4, 0, NULL, ret_void, f_test_gui_drop_files}, {"test_gui_mouse_event", 5, 5, 0, NULL, ret_void, f_test_gui_mouse_event}, - {"test_ignore_error", 1, 1, FEARG_1, NULL, + {"test_ignore_error", 1, 1, FEARG_1, arg1_string, ret_void, f_test_ignore_error}, {"test_null_blob", 0, 0, 0, NULL, ret_blob, f_test_null_blob}, @@ -1774,7 +1791,7 @@ static funcentry_T global_functions[] = ret_func_any, f_test_null_partial}, {"test_null_string", 0, 0, 0, NULL, ret_string, f_test_null_string}, - {"test_option_not_set", 1, 1, FEARG_1, NULL, + {"test_option_not_set", 1, 1, FEARG_1, arg1_string, ret_void, f_test_option_not_set}, {"test_override", 2, 2, FEARG_2, NULL, ret_void, f_test_override}, @@ -1788,11 +1805,11 @@ static funcentry_T global_functions[] = NULL #endif }, - {"test_setmouse", 2, 2, 0, NULL, + {"test_setmouse", 2, 2, 0, arg2_number, ret_void, f_test_setmouse}, - {"test_settime", 1, 1, FEARG_1, NULL, + {"test_settime", 1, 1, FEARG_1, arg1_number, ret_void, f_test_settime}, - {"test_srand_seed", 0, 1, FEARG_1, NULL, + {"test_srand_seed", 0, 1, FEARG_1, arg1_number, ret_void, f_test_srand_seed}, {"test_unknown", 0, 0, 0, NULL, ret_any, f_test_unknown}, @@ -1814,7 +1831,7 @@ static funcentry_T global_functions[] = ret_string, f_toupper}, {"tr", 3, 3, FEARG_1, arg3_string, ret_string, f_tr}, - {"trim", 1, 3, FEARG_1, NULL, + {"trim", 1, 3, FEARG_1, arg3_string_string_nr, ret_string, f_trim}, {"trunc", 1, 1, FEARG_1, arg1_float_or_nr, ret_float, FLOAT_FUNC(f_trunc)}, @@ -1830,7 +1847,7 @@ static funcentry_T global_functions[] = ret_list_any, f_uniq}, {"values", 1, 1, FEARG_1, arg1_dict, ret_list_any, f_values}, - {"virtcol", 1, 1, FEARG_1, NULL, + {"virtcol", 1, 1, FEARG_1, arg1_string_or_list, ret_number, f_virtcol}, {"visualmode", 0, 1, 0, NULL, ret_string, f_visualmode}, @@ -2552,7 +2569,8 @@ f_charidx(typval_T *argvars, typval_T *rettv) if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_NUMBER || (argvars[2].v_type != VAR_UNKNOWN - && argvars[2].v_type != VAR_NUMBER)) + && argvars[2].v_type != VAR_NUMBER + && argvars[2].v_type != VAR_BOOL)) { emsg(_(e_invarg)); return; @@ -9763,6 +9781,12 @@ f_trim(typval_T *argvars, typval_T *rettv) if (head == NULL) return; + if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_STRING) + { + semsg(_(e_invarg2), tv_get_string(&argvars[1])); + return; + } + if (argvars[1].v_type == VAR_STRING) { mask = tv_get_string_buf_chk(&argvars[1], buf2); diff --git a/src/proto/typval.pro b/src/proto/typval.pro index ad20f8c4da..f6dd01ebb3 100644 --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -11,6 +11,7 @@ varnumber_T tv_get_bool_chk(typval_T *varp, int *denote); float_T tv_get_float(typval_T *varp); int check_for_string_arg(typval_T *args, int idx); int check_for_nonempty_string_arg(typval_T *args, int idx); +int check_for_dict_arg(typval_T *args, int idx); char_u *tv_get_string(typval_T *varp); char_u *tv_get_string_strict(typval_T *varp); char_u *tv_get_string_buf(typval_T *varp, char_u *buf); diff --git a/src/terminal.c b/src/terminal.c index e3945d03ac..9de516cc8b 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -5276,6 +5276,11 @@ term_load_dump(typval_T *argvars, typval_T *rettv, int do_diff) FILE *fd2 = NULL; char_u *textline = NULL; + if (in_vim9script() + && (check_for_string_arg(argvars, 0) == FAIL + || check_for_dict_arg(argvars, 1) == FAIL)) + return; + // First open the files. If this fails bail out. fname1 = tv_get_string_buf_chk(&argvars[0], buf1); if (do_diff) diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index 49e86f872d..045fa2ee8d 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -373,9 +373,9 @@ func Test_searchpairpos() endfunc func Test_searchpair_errors() - call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String') - call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String') - call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String') + call assert_fails("call searchpair([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String') + call assert_fails("call searchpair('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String') + call assert_fails("call searchpair('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String') call assert_fails("call searchpair('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags') call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99') call assert_fails("call searchpair('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100') @@ -384,9 +384,9 @@ func Test_searchpair_errors() endfunc func Test_searchpairpos_errors() - call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: using List as a String') - call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: using Funcref as a String') - call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: using Dictionary as a String') + call assert_fails("call searchpairpos([0], 'middle', 'end', 'bW', 'skip', 99, 100)", 'E730: Using a List as a String') + call assert_fails("call searchpairpos('start', {-> 0}, 'end', 'bW', 'skip', 99, 100)", 'E729: Using a Funcref as a String') + call assert_fails("call searchpairpos('start', 'middle', {'one': 1}, 'bW', 'skip', 99, 100)", 'E731: Using a Dictionary as a String') call assert_fails("call searchpairpos('start', 'middle', 'end', 'flags', 'skip', 99, 100)", 'E475: Invalid argument: flags') call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', -99, 100)", 'E475: Invalid argument: -99') call assert_fails("call searchpairpos('start', 'middle', 'end', 'bW', 'func', 99, -100)", 'E475: Invalid argument: -100') diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim index e2de3ba937..82834e4d52 100644 --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -1340,7 +1340,7 @@ endfunc func Test_prop_func_invalid_args() call assert_fails('call prop_clear(1, 2, [])', 'E715:') call assert_fails('call prop_clear(-1, 2)', 'E16:') - call assert_fails('call prop_find(test_null_dict())', 'E474:') + call assert_fails('call prop_find(test_null_dict())', 'E715:') call assert_fails('call prop_find({"bufnr" : []})', 'E730:') call assert_fails('call prop_find({})', 'E968:') call assert_fails('call prop_find({}, "x")', 'E474:') diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 5964ded70c..6b6278b8d0 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -156,8 +156,8 @@ def Test_add_blob() enddef def Test_and() - CheckDefFailure(['echo and("x", 0x2)'], 'E1013: Argument 1: type mismatch, expected number but got string') - CheckDefFailure(['echo and(0x1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string') + CheckDefAndScriptFailure2(['and("x", 0x2)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1030: Using a String as a Number') + CheckDefAndScriptFailure2(['and(0x1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1030: Using a String as a Number') enddef def Test_append() @@ -175,19 +175,42 @@ def Test_append() enddef def Test_argc() - CheckDefFailure(['echo argc("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['argc("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') enddef def Test_arglistid() - CheckDefFailure(['echo arglistid("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') - CheckDefFailure(['echo arglistid(1, "y")'], 'E1013: Argument 2: type mismatch, expected number but got string') - CheckDefFailure(['echo arglistid("x", "y")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['arglistid("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['arglistid(1, "y")'], 'E1013: Argument 2: type mismatch, expected number but got string') + CheckDefFailure(['arglistid("x", "y")'], 'E1013: Argument 1: type mismatch, expected number but got string') enddef def Test_argv() - CheckDefFailure(['echo argv("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') - CheckDefFailure(['echo argv(1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string') - CheckDefFailure(['echo argv("x", "y")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['argv("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['argv(1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string') + CheckDefFailure(['argv("x", "y")'], 'E1013: Argument 1: type mismatch, expected number but got string') +enddef + +def Test_assert_equalfile() + CheckDefFailure(['assert_equalfile(1, "f2")'], 'E1013: Argument 1: type mismatch, expected string but got number') + CheckDefFailure(['assert_equalfile("f1", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool') + CheckDefFailure(['assert_equalfile("f1", "f2", ["a"])'], 'E1013: Argument 3: type mismatch, expected string but got list<string>') +enddef + +def Test_assert_exception() + CheckDefFailure(['assert_exception({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>') + CheckDefFailure(['assert_exception("E1:", v:null)'], 'E1013: Argument 2: type mismatch, expected string but got special') +enddef + +def Test_assert_match() + CheckDefFailure(['assert_match({}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>') + CheckDefFailure(['assert_match("a", 1)'], 'E1013: Argument 2: type mismatch, expected string but got number') + CheckDefFailure(['assert_match("a", "b", null)'], 'E1013: Argument 3: type mismatch, expected string but got special') +enddef + +def Test_assert_notmatch() + CheckDefFailure(['assert_notmatch({}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>') + CheckDefFailure(['assert_notmatch("a", 1)'], 'E1013: Argument 2: type mismatch, expected string but got number') + CheckDefFailure(['assert_notmatch("a", "b", null)'], 'E1013: Argument 3: type mismatch, expected string but got special') enddef def Test_balloon_show() @@ -222,6 +245,11 @@ def Test_browse() CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4') enddef +def Test_browsedir() + CheckDefFailure(['browsedir({}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>') + CheckDefFailure(['browsedir("a", [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>') +enddef + def Test_bufadd() assert_fails('bufadd([])', 'E730:') enddef @@ -299,12 +327,51 @@ def Test_call_call() l->assert_equal([1, 2, 3]) enddef +def Test_ch_canread() + if !has('channel') + CheckFeature channel + endif + CheckDefFailure(['ch_canread(10)'], 'E1013: Argument 1: type mismatch, expected channel but got number') +enddef + +def Test_ch_close() + if !has('channel') + CheckFeature channel + endif + CheckDefFailure(['ch_close("c")'], 'E1013: Argument 1: type mismatch, expected channel but got string') +enddef + +def Test_ch_close_in() + if !has('channel') + CheckFeature channel + endif + CheckDefFailure(['ch_close_in(true)'], 'E1013: Argument 1: type mismatch, expected channel but got bool') +enddef + +def Test_ch_info() + if !has('channel') + CheckFeature channel + endif + CheckDefFailure(['ch_info([1])'], 'E1013: Argument 1: type mismatch, expected channel but got list<number>') +enddef + def Test_ch_logfile() if !has('channel') CheckFeature channel endif assert_fails('ch_logfile(true)', 'E1174:') assert_fails('ch_logfile("foo", true)', 'E1174:') + + CheckDefAndScriptFailure2(['ch_logfile(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1') + CheckDefAndScriptFailure2(['ch_logfile("a", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2') +enddef + +def Test_ch_open() + if !has('channel') + CheckFeature channel + endif + CheckDefAndScriptFailure2(['ch_open({"a": 10}, "a")'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1') + CheckDefAndScriptFailure2(['ch_open("a", [1])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2') enddef def Test_char2nr() @@ -317,6 +384,17 @@ def Test_charclass() assert_fails('charclass(true)', 'E1174:') enddef +def Test_charcol() + CheckDefFailure(['charcol(10)'], 'E1013: Argument 1: type mismatch, expected string but got number') + CheckDefFailure(['charcol({a: 10})'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>') +enddef + +def Test_charidx() + CheckDefFailure(['charidx("a", "b")'], 'E1013: Argument 2: type mismatch, expected number but got string') + CheckDefFailure(['charidx(0z10, 1)'], 'E1013: Argument 1: type mismatch, expected string but got blob') + CheckDefFailure(['charidx("a", 1, "")'], 'E1013: Argument 3: type mismatch, expected bool but got string') +enddef + def Test_chdir() assert_fails('chdir(true)', 'E1174:') enddef @@ -329,7 +407,7 @@ def Test_cindent() enddef def Test_clearmatches() - CheckDefFailure(['echo clearmatches("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['clearmatches("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') enddef def Test_col() @@ -338,6 +416,11 @@ def Test_col() col([1, '$'])->assert_equal(5) assert_fails('col(true)', 'E1174:') + + CheckDefFailure(['col(10)'], 'E1013: Argument 1: type mismatch, expected string but got number') + CheckDefFailure(['col({a: 10})'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>') + CheckDefFailure(['col(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool') + bw! enddef def Test_confirm() @@ -396,12 +479,15 @@ enddef def Test_debugbreak() CheckMSWindows - CheckDefFailure(['echo debugbreak("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') + CheckDefFailure(['debugbreak("x")'], 'E1013: Argument 1: type mismatch, expected number but got string') enddef def Test_delete() var res: bool = delete('doesnotexist') assert_equal(true, res) + + CheckDefFailure(['delete(10)'], 'E1013: Argument 1: type mismatch, expected string but got number') + CheckDefFailure(['delete("a", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number') enddef |