# HG changeset patch # User Bram Moolenaar # Date 1661886005 -7200 # Node ID 86eb4aba16c31a4b6db4b071dfe846dfa52b751f # Parent 8dd1900432a0e89c19d2ecc0deeef5cd08da0628 patch 9.0.0335: checks for Dictionary argument often give a vague error Commit: https://github.com/vim/vim/commit/04c4c5746e15884768d2cb41370c3276a196cd4c Author: Yegappan Lakshmanan Date: Tue Aug 30 19:48:24 2022 +0100 patch 9.0.0335: checks for Dictionary argument often give a vague error Problem: Checks for Dictionary argument often give a vague error message. Solution: Give a useful error message. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/11009) diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -1392,11 +1392,8 @@ channel_open_func(typval_T *argvars) 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)) - { - emsg(_(e_invalid_argument)); + && check_for_nonnull_dict_arg(argvars, 1) == FAIL) return NULL; - } if (*address == NUL) { @@ -4601,11 +4598,9 @@ ch_expr_common(typval_T *argvars, typval if (rettv_dict_alloc(rettv) == FAIL) return; - if (argvars[1].v_type != VAR_DICT) - { - semsg(_(e_dict_required_for_argument_nr), 2); + if (check_for_dict_arg(argvars, 1) == FAIL) return; - } + d = argvars[1].vval.v_dict; di = dict_find(d, (char_u *)"id", -1); if (di != NULL && di->di_tv.v_type != VAR_NUMBER) diff --git a/src/dict.c b/src/dict.c --- a/src/dict.c +++ b/src/dict.c @@ -1578,11 +1578,9 @@ f_has_key(typval_T *argvars, typval_T *r || check_for_string_or_number_arg(argvars, 1) == FAIL)) return; - if (argvars[0].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 0) == FAIL) return; - } + if (argvars[0].vval.v_dict == NULL) return; diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -3318,3 +3318,5 @@ EXTERN char e_cannot_specify_both_type_a EXTERN char e_can_only_use_left_padding_when_column_is_zero[] INIT(= N_("E1296: Can only use left padding when column is zero")); #endif +EXTERN char e_non_null_dict_required_for_argument_nr[] + INIT(= N_("E1297: Non-NULL Dictionary required for argument %d")); diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -3277,11 +3277,9 @@ f_call(typval_T *argvars, typval_T *rett if (argvars[2].v_type != VAR_UNKNOWN) { - if (argvars[2].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 2) == FAIL) return; - } + selfdict = argvars[2].vval.v_dict; } @@ -4501,9 +4499,8 @@ common_function(typval_T *argvars, typva arg_idx = 1; if (dict_idx > 0) { - if (argvars[dict_idx].v_type != VAR_DICT) + if (check_for_dict_arg(argvars, dict_idx) == FAIL) { - emsg(_(e_expected_dict)); vim_free(name); goto theend; } @@ -9291,14 +9288,8 @@ f_setcharsearch(typval_T *argvars, typva dictitem_T *di; char_u *csearch; - if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) - return; - - if (argvars[0].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); - return; - } + if (check_for_dict_arg(argvars, 0) == FAIL) + return; if ((d = argvars[0].vval.v_dict) != NULL) { @@ -9637,11 +9628,8 @@ f_settagstack(typval_T *argvars, typval_ return; // second argument: dict with items to set in the tag stack - if (argvars[1].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); - return; - } + if (check_for_dict_arg(argvars, 1) == FAIL) + return; d = argvars[1].vval.v_dict; if (d == NULL) return; diff --git a/src/evalwindow.c b/src/evalwindow.c --- a/src/evalwindow.c +++ b/src/evalwindow.c @@ -1009,11 +1009,8 @@ f_win_splitmove(typval_T *argvars, typva dict_T *d; dictitem_T *di; - if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) - { - emsg(_(e_invalid_argument)); + if (check_for_nonnull_dict_arg(argvars, 2) == FAIL) return; - } d = argvars[2].vval.v_dict; if (dict_get_bool(d, "vertical", FALSE)) @@ -1227,50 +1224,45 @@ f_winrestview(typval_T *argvars, typval_ { dict_T *dict; - if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) + if (check_for_nonnull_dict_arg(argvars, 0) == FAIL) return; - if (argvars[0].v_type != VAR_DICT - || (dict = argvars[0].vval.v_dict) == NULL) - emsg(_(e_invalid_argument)); - else + dict = argvars[0].vval.v_dict; + if (dict_has_key(dict, "lnum")) + curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, "lnum"); + if (dict_has_key(dict, "col")) + curwin->w_cursor.col = (colnr_T)dict_get_number(dict, "col"); + if (dict_has_key(dict, "coladd")) + curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, "coladd"); + if (dict_has_key(dict, "curswant")) { - if (dict_has_key(dict, "lnum")) - curwin->w_cursor.lnum = (linenr_T)dict_get_number(dict, "lnum"); - if (dict_has_key(dict, "col")) - curwin->w_cursor.col = (colnr_T)dict_get_number(dict, "col"); - if (dict_has_key(dict, "coladd")) - curwin->w_cursor.coladd = (colnr_T)dict_get_number(dict, "coladd"); - if (dict_has_key(dict, "curswant")) - { - curwin->w_curswant = (colnr_T)dict_get_number(dict, "curswant"); - curwin->w_set_curswant = FALSE; - } + curwin->w_curswant = (colnr_T)dict_get_number(dict, "curswant"); + curwin->w_set_curswant = FALSE; + } - if (dict_has_key(dict, "topline")) - set_topline(curwin, (linenr_T)dict_get_number(dict, "topline")); + if (dict_has_key(dict, "topline")) + set_topline(curwin, (linenr_T)dict_get_number(dict, "topline")); #ifdef FEAT_DIFF - if (dict_has_key(dict, "topfill")) - curwin->w_topfill = (int)dict_get_number(dict, "topfill"); + if (dict_has_key(dict, "topfill")) + curwin->w_topfill = (int)dict_get_number(dict, "topfill"); #endif - if (dict_has_key(dict, "leftcol")) - curwin->w_leftcol = (colnr_T)dict_get_number(dict, "leftcol"); - if (dict_has_key(dict, "skipcol")) - curwin->w_skipcol = (colnr_T)dict_get_number(dict, "skipcol"); + if (dict_has_key(dict, "leftcol")) + curwin->w_leftcol = (colnr_T)dict_get_number(dict, "leftcol"); + if (dict_has_key(dict, "skipcol")) + curwin->w_skipcol = (colnr_T)dict_get_number(dict, "skipcol"); - check_cursor(); - win_new_height(curwin, curwin->w_height); - win_new_width(curwin, curwin->w_width); - changed_window_setting(); + check_cursor(); + win_new_height(curwin, curwin->w_height); + win_new_width(curwin, curwin->w_width); + changed_window_setting(); - if (curwin->w_topline <= 0) - curwin->w_topline = 1; - if (curwin->w_topline > curbuf->b_ml.ml_line_count) - curwin->w_topline = curbuf->b_ml.ml_line_count; + if (curwin->w_topline <= 0) + curwin->w_topline = 1; + if (curwin->w_topline > curbuf->b_ml.ml_line_count) + curwin->w_topline = curbuf->b_ml.ml_line_count; #ifdef FEAT_DIFF - check_topfill(curwin, TRUE); + check_topfill(curwin, TRUE); #endif - } } /* diff --git a/src/list.c b/src/list.c --- a/src/list.c +++ b/src/list.c @@ -2236,11 +2236,8 @@ parse_sort_uniq_args(typval_T *argvars, if (argvars[2].v_type != VAR_UNKNOWN) { // optional third argument: {dict} - if (argvars[2].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 2) == FAIL) return FAIL; - } info->item_compare_selfdict = argvars[2].vval.v_dict; } diff --git a/src/map.c b/src/map.c --- a/src/map.c +++ b/src/map.c @@ -2635,11 +2635,8 @@ f_mapset(typval_T *argvars, typval_T *re return; is_abbr = (int)tv_get_bool(&argvars[1]); - if (argvars[2].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 2) == FAIL) return; - } d = argvars[2].vval.v_dict; } mode = get_map_mode_string(which, is_abbr); diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -2016,11 +2016,8 @@ popup_create(typval_T *argvars, typval_T emsg(_(e_buffer_number_text_or_list_required)); return NULL; } - if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 1) == FAIL) return NULL; - } d = argvars[1].vval.v_dict; } @@ -2928,11 +2925,8 @@ f_popup_move(typval_T *argvars, typval_T if (wp == NULL) return; // invalid {id} - if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 1) == FAIL) return; - } dict = argvars[1].vval.v_dict; apply_move_options(wp, dict); @@ -2963,11 +2957,8 @@ f_popup_setoptions(typval_T *argvars, ty if (wp == NULL) return; // invalid {id} - if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 1) == FAIL) return; - } dict = argvars[1].vval.v_dict; old_firstline = wp->w_firstline; diff --git a/src/proto/typval.pro b/src/proto/typval.pro --- a/src/proto/typval.pro +++ b/src/proto/typval.pro @@ -22,6 +22,7 @@ int check_for_blob_arg(typval_T *args, i int check_for_list_arg(typval_T *args, int idx); int check_for_opt_list_arg(typval_T *args, int idx); int check_for_dict_arg(typval_T *args, int idx); +int check_for_nonnull_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); diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -764,7 +764,7 @@ searchit( col = at_first_line && (options & SEARCH_COL) ? pos->col : (colnr_T)0; nmatched = vim_regexec_multi(®match, win, buf, - lnum, col, timed_out); + lnum, col, timed_out); // vim_regexec_multi() may clear "regprog" if (regmatch.regprog == NULL) break; @@ -1072,11 +1072,11 @@ searchit( * twice. */ if (!p_ws || stop_lnum != 0 || got_int - || called_emsg > called_emsg_before || *timed_out + || called_emsg > called_emsg_before || *timed_out #ifdef FEAT_SEARCH_EXTRA - || break_loop + || break_loop #endif - || found || loop) + || found || loop) break; /* @@ -4095,11 +4095,8 @@ f_searchcount(typval_T *argvars, typval_ listitem_T *li; int error = FALSE; - if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 0) == FAIL) return; - } dict = argvars[0].vval.v_dict; di = dict_find(dict, (char_u *)"timeout", -1); if (di != NULL) @@ -4815,11 +4812,8 @@ do_fuzzymatch(typval_T *argvars, typval_ dict_T *d; dictitem_T *di; - if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 2) == FAIL) return; - } // To search a dict, either a callback function or a key can be // specified. diff --git a/src/sign.c b/src/sign.c --- a/src/sign.c +++ b/src/sign.c @@ -2349,11 +2349,8 @@ f_sign_define(typval_T *argvars, typval_ if (name == NULL) return; - if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_opt_dict_arg(argvars, 1) == FAIL) return; - } rettv->vval.v_number = sign_define_from_dict(name, argvars[1].v_type == VAR_DICT ? argvars[1].vval.v_dict : NULL); @@ -2411,12 +2408,9 @@ f_sign_getplaced(typval_T *argvars, typv if (argvars[1].v_type != VAR_UNKNOWN) { - if (argvars[1].v_type != VAR_DICT || - ((dict = argvars[1].vval.v_dict) == NULL)) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 1) == FAIL) return; - } + dict = argvars[1].vval.v_dict; if ((di = dict_find(dict, (char_u *)"lnum", -1)) != NULL) { // get signs placed at this line @@ -2640,12 +2634,11 @@ f_sign_place(typval_T *argvars, typval_T || check_for_opt_dict_arg(argvars, 4) == FAIL)) return; - if (argvars[4].v_type != VAR_UNKNOWN - && (argvars[4].v_type != VAR_DICT - || ((dict = argvars[4].vval.v_dict) == NULL))) + if (argvars[4].v_type != VAR_UNKNOWN) { - emsg(_(e_dictionary_required)); - return; + if (check_for_nonnull_dict_arg(argvars, 4) == FAIL) + return; + dict = argvars[4].vval.v_dict; } rettv->vval.v_number = sign_place_from_dict(&argvars[0], &argvars[1], @@ -2872,11 +2865,8 @@ f_sign_unplace(typval_T *argvars, typval if (argvars[1].v_type != VAR_UNKNOWN) { - if (argvars[1].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 1) == FAIL) return; - } dict = argvars[1].vval.v_dict; } diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -4989,11 +4989,8 @@ f_term_dumpwrite(typval_T *argvars, typv { dict_T *d; - if (argvars[2].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 2) == FAIL) return; - } d = argvars[2].vval.v_dict; if (d != NULL) { diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -1509,7 +1509,7 @@ func Test_open_fail() call assert_fails("let ch = ch_open('noserver')", 'E475:') echo ch let d = ch - call assert_fails("let ch = ch_open('noserver', 10)", 'E474:') + call assert_fails("let ch = ch_open('noserver', 10)", 'E1206:') call assert_fails("let ch = ch_open('localhost:-1')", 'E475:') call assert_fails("let ch = ch_open('localhost:65537')", 'E475:') call assert_fails("let ch = ch_open('localhost:8765', {'timeout' : -1})", diff --git a/src/testdir/test_charsearch.vim b/src/testdir/test_charsearch.vim --- a/src/testdir/test_charsearch.vim +++ b/src/testdir/test_charsearch.vim @@ -39,7 +39,7 @@ func Test_charsearch() call setcharsearch({'char' : ''}) call assert_equal('', getcharsearch().char) - call assert_fails("call setcharsearch([])", 'E715:') + call assert_fails("call setcharsearch([])", 'E1206:') enew! endfunc diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim --- a/src/testdir/test_expr.vim +++ b/src/testdir/test_expr.vim @@ -113,7 +113,7 @@ func Test_dict() END call v9.CheckLegacyAndVim9Success(lines) - call v9.CheckLegacyAndVim9Failure(["VAR i = has_key([], 'a')"], ['E715:', 'E1013:', 'E1206:']) + call v9.CheckLegacyAndVim9Failure(["VAR i = has_key([], 'a')"], ['E1206:', 'E1013:', 'E1206:']) endfunc func Test_strgetchar() diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim --- a/src/testdir/test_functions.vim +++ b/src/testdir/test_functions.vim @@ -2294,7 +2294,7 @@ func Test_call() endfunction let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")} eval mydict.len->call([], mydict)->assert_equal(4) - call assert_fails("call call('Mylen', [], 0)", 'E715:') + call assert_fails("call call('Mylen', [], 0)", 'E1206:') call assert_fails('call foo', 'E107:') " These once caused a crash. diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -981,7 +981,7 @@ func Test_reverse_sort_uniq() call assert_fails('call reverse("")', 'E899:') call assert_fails('call uniq([1, 2], {x, y -> []})', 'E745:') - call assert_fails("call sort([1, 2], function('min'), 1)", "E715:") + call assert_fails("call sort([1, 2], function('min'), 1)", "E1206:") call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:") call assert_fails("call sort([1, 2], function('min'))", "E118:") diff --git a/src/testdir/test_map_functions.vim b/src/testdir/test_map_functions.vim --- a/src/testdir/test_map_functions.vim +++ b/src/testdir/test_map_functions.vim @@ -273,7 +273,7 @@ func Test_mapset() bwipe! call assert_fails('call mapset([], v:false, {})', 'E730:') - call assert_fails('call mapset("i", 0, "")', 'E715:') + call assert_fails('call mapset("i", 0, "")', 'E1206:') call assert_fails('call mapset("i", 0, {})', 'E460:') endfunc diff --git a/src/testdir/test_matchfuzzy.vim b/src/testdir/test_matchfuzzy.vim --- a/src/testdir/test_matchfuzzy.vim +++ b/src/testdir/test_matchfuzzy.vim @@ -67,14 +67,14 @@ func Test_matchfuzzy() call assert_equal([{'id' : 6, 'val' : 'camera'}], matchfuzzy(l, 'cam', {'key' : 'val'})) call assert_equal([], matchfuzzy(l, 'day', {'text_cb' : {v -> v.val}})) call assert_equal([], matchfuzzy(l, 'day', {'key' : 'val'})) - call assert_fails("let x = matchfuzzy(l, 'cam', 'random')", 'E715:') + call assert_fails("let x = matchfuzzy(l, 'cam', 'random')", 'E1206:') call assert_equal([], matchfuzzy(l, 'day', {'text_cb' : {v -> []}})) call assert_equal([], matchfuzzy(l, 'day', {'text_cb' : {v -> 1}})) call assert_fails("let x = matchfuzzy(l, 'day', {'text_cb' : {a, b -> 1}})", 'E119:') call assert_equal([], matchfuzzy(l, 'cam')) call assert_fails("let x = matchfuzzy(l, 'cam', {'text_cb' : []})", 'E921:') call assert_fails("let x = matchfuzzy(l, 'foo', {'key' : []})", 'E730:') - call assert_fails("let x = matchfuzzy(l, 'cam', test_null_dict())", 'E715:') + call assert_fails("let x = matchfuzzy(l, 'cam', test_null_dict())", 'E1297:') call assert_fails("let x = matchfuzzy(l, 'foo', {'key' : test_null_string()})", 'E475:') call assert_fails("let x = matchfuzzy(l, 'foo', {'text_cb' : test_null_function()})", 'E475:') " matches with same score should not be reordered @@ -140,14 +140,14 @@ func Test_matchfuzzypos() \ matchfuzzypos(l, 'cam', {'key' : 'val'})) call assert_equal([[], [], []], matchfuzzypos(l, 'day', {'text_cb' : {v -> v.val}})) call assert_equal([[], [], []], matchfuzzypos(l, 'day', {'key' : 'val'})) - call assert_fails("let x = matchfuzzypos(l, 'cam', 'random')", 'E715:') + call assert_fails("let x = matchfuzzypos(l, 'cam', 'random')", 'E1206:') call assert_equal([[], [], []], matchfuzzypos(l, 'day', {'text_cb' : {v -> []}})) call assert_equal([[], [], []], matchfuzzypos(l, 'day', {'text_cb' : {v -> 1}})) call assert_fails("let x = matchfuzzypos(l, 'day', {'text_cb' : {a, b -> 1}})", 'E119:') call assert_equal([[], [], []], matchfuzzypos(l, 'cam')) call assert_fails("let x = matchfuzzypos(l, 'cam', {'text_cb' : []})", 'E921:') call assert_fails("let x = matchfuzzypos(l, 'foo', {'key' : []})", 'E730:') - call assert_fails("let x = matchfuzzypos(l, 'cam', test_null_dict())", 'E715:') + call assert_fails("let x = matchfuzzypos(l, 'cam', test_null_dict())", 'E1297:') call assert_fails("let x = matchfuzzypos(l, 'foo', {'key' : test_null_string()})", 'E475:') call assert_fails("let x = matchfuzzypos(l, 'foo', {'text_cb' : test_null_function()})", 'E475:') diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim --- a/src/testdir/test_partial.vim +++ b/src/testdir/test_partial.vim @@ -88,7 +88,7 @@ func Test_partial_dict() call assert_equal("Hello", dict.tr()) call assert_fails("let F=function('setloclist', 10)", "E923:") - call assert_fails("let F=function('setloclist', [], [])", "E922:") + call assert_fails("let F=function('setloclist', [], [])", "E1206:") endfunc func Test_partial_implicit() diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -1035,7 +1035,7 @@ endfunc func Test_popup_invalid_arguments() call assert_fails('call popup_create(666, {})', 'E86:') call popup_clear() - call assert_fails('call popup_create("text", "none")', 'E715:') + call assert_fails('call popup_create("text", "none")', 'E1206:') call popup_clear() call assert_fails('call popup_create(test_null_string(), {})', 'E450:') call assert_fails('call popup_create(test_null_list(), {})', 'E450:') @@ -1309,8 +1309,8 @@ func Test_popup_move() let line = join(map(range(1, 6), 'screenstring(1, v:val)'), '') call assert_equal('hworld', line) - call assert_fails('call popup_move(winid, [])', 'E715:') - call assert_fails('call popup_move(winid, test_null_dict())', 'E715:') + call assert_fails('call popup_move(winid, [])', 'E1206:') + call assert_fails('call popup_move(winid, test_null_dict())', 'E1297:') call popup_close(winid) @@ -2577,8 +2577,8 @@ func Test_set_get_options() call assert_equal(1, options.drag) call assert_equal('Another', options.highlight) - call assert_fails('call popup_setoptions(winid, [])', 'E715:') - call assert_fails('call popup_setoptions(winid, test_null_dict())', 'E715:') + call assert_fails('call popup_setoptions(winid, [])', 'E1206:') + call assert_fails('call popup_setoptions(winid, test_null_dict())', 'E1297:') call popup_close(winid) call assert_equal(0, popup_setoptions(winid, options.wrap)) diff --git a/src/testdir/test_search_stat.vim b/src/testdir/test_search_stat.vim --- a/src/testdir/test_search_stat.vim +++ b/src/testdir/test_search_stat.vim @@ -259,7 +259,7 @@ func Test_search_stat() endfunc func Test_searchcount_fails() - call assert_fails('echo searchcount("boo!")', 'E715:') + call assert_fails('echo searchcount("boo!")', 'E1206:') call assert_fails('echo searchcount({"timeout" : []})', 'E745:') call assert_fails('echo searchcount({"maxcount" : []})', 'E745:') call assert_fails('echo searchcount({"pattern" : []})', 'E730:') diff --git a/src/testdir/test_signs.vim b/src/testdir/test_signs.vim --- a/src/testdir/test_signs.vim +++ b/src/testdir/test_signs.vim @@ -449,7 +449,7 @@ func Test_sign_funcs() call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:') call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:') call assert_fails('call sign_define({})', 'E731:') - call assert_fails('call sign_define("sign6", [])', 'E715:') + call assert_fails('call sign_define("sign6", [])', 'E1206:') " Tests for sign_getdefined() call assert_equal([], sign_getdefined("none")) @@ -476,8 +476,7 @@ func Test_sign_funcs() " Tests for invalid arguments to sign_place() call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:') call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:') - call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])', - \ 'E715:') + call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])', 'E1206:') call assert_fails('call sign_place(-1, "", "sign1", "Xsign", \ {"lnum" : 30})', 'E474:') call assert_fails('call sign_place(10, "", "xsign1x", "Xsign", @@ -512,7 +511,7 @@ func Test_sign_funcs() call assert_fails("call sign_getplaced('dummy.sign')", 'E158:') call assert_fails('call sign_getplaced("&")', 'E158:') call assert_fails('call sign_getplaced(-1)', 'E158:') - call assert_fails('call sign_getplaced("Xsign", [])', 'E715:') + call assert_fails('call sign_getplaced("Xsign", [])', 'E1206:') call assert_equal([{'bufnr' : bufnr(''), 'signs' : []}], \ sign_getplaced('Xsign', {'lnum' : 1000000})) call assert_fails("call sign_getplaced('Xsign', {'lnum' : []})", @@ -535,7 +534,7 @@ func Test_sign_funcs() \ {'id' : 20, 'buffer' : '&'})", 'E158:') call assert_fails("call sign_unplace('g1', \ {'id' : 20, 'buffer' : 200})", 'E158:') - call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:') + call assert_fails("call sign_unplace('g1', 'mySign')", 'E1206:') call sign_unplace('*') @@ -1554,8 +1553,7 @@ func Test_sign_priority() \ s[0].signs) " Error case - call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', - \ [])", 'E715:') + call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', [])", 'E1206:') call assert_fails("call sign_place(1, 'g1', 'sign1', 'Xsign', \ {'priority' : []})", 'E745:') call sign_unplace('*') diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim --- a/src/testdir/test_tagjump.vim +++ b/src/testdir/test_tagjump.vim @@ -403,7 +403,7 @@ func Test_getsettagstack() " Error cases call assert_equal({}, gettagstack(100)) call assert_equal(-1, settagstack(100, {'items' : []})) - call assert_fails('call settagstack(1, [1, 10])', 'E715:') + call assert_fails('call settagstack(1, [1, 10])', 'E1206:') call assert_fails("call settagstack(1, {'items' : 10})", 'E714:') call assert_fails("call settagstack(1, {'items' : []}, 10)", 'E928:') call assert_fails("call settagstack(1, {'items' : []}, 'b')", 'E962:') diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -1453,7 +1453,7 @@ func Test_terminal_dumpwrite_errors() call assert_fails("call term_dumpwrite({}, 'Xtest.dump')", 'E728:') let buf = RunVimInTerminal('', {}) call TermWait(buf) - call assert_fails("call term_dumpwrite(buf, 'Xtest.dump', '')", 'E715:') + call assert_fails("call term_dumpwrite(buf, 'Xtest.dump', '')", 'E1206:') call assert_fails("call term_dumpwrite(buf, [])", 'E730:') call writefile([], 'Xtest.dump') call assert_fails("call term_dumpwrite(buf, 'Xtest.dump')", 'E953:') diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -1679,14 +1679,14 @@ 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())', 'E715:') + call assert_fails('call prop_find(test_null_dict())', 'E1297:') call assert_fails('call prop_find({"bufnr" : []})', 'E730:') call assert_fails('call prop_find({})', 'E968:') call assert_fails('call prop_find({}, "x")', 'E474:') call assert_fails('call prop_find({"lnum" : -2})', 'E16:') - call assert_fails('call prop_list(1, [])', 'E715:') + call assert_fails('call prop_list(1, [])', 'E1206:') call assert_fails('call prop_list(-1, {})', 'E16:') - call assert_fails('call prop_remove([])', 'E474:') + call assert_fails('call prop_remove([])', 'E1206:') call assert_fails('call prop_remove({}, -2)', 'E16:') call assert_fails('call prop_remove({})', 'E968:') call assert_fails('call prop_type_add([], {})', 'E730:') @@ -1699,7 +1699,7 @@ func Test_prop_func_invalid_args() call assert_fails("call prop_type_add('yyy', 'not_a_dict')", 'E715:') call assert_fails("call prop_add(1, 5, {'type':'missing_type', 'length':1})", 'E971:') call assert_fails("call prop_add(1, 5, {'type': ''})", 'E971:') - call assert_fails('call prop_add(1, 1, 0)', 'E715:') + call assert_fails('call prop_add(1, 1, 0)', 'E1206:') new call setline(1, ['first', 'second']) diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim --- a/src/testdir/test_timers.vim +++ b/src/testdir/test_timers.vim @@ -265,7 +265,7 @@ func Test_timer_errors() sleep 50m call assert_equal(3, g:call_count) - call assert_fails('call timer_start(100, "MyHandler", "abc")', 'E475:') + call assert_fails('call timer_start(100, "MyHandler", "abc")', 'E1206:') call assert_fails('call timer_start(100, [])', 'E921:') call assert_fails('call timer_stop("abc")', 'E39:') endfunc diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -745,7 +745,7 @@ func Test_relative_cursor_position_in_on only! bwipe! - call assert_fails('call winrestview(test_null_dict())', 'E474:') + call assert_fails('call winrestview(test_null_dict())', 'E1297:') endfunc func Test_relative_cursor_position_after_move_and_resize() @@ -946,7 +946,7 @@ func Test_winrestview() call assert_equal(view, winsaveview()) bwipe! - call assert_fails('call winrestview(test_null_dict())', 'E474:') + call assert_fails('call winrestview(test_null_dict())', 'E1297:') endfunc func Test_win_splitmove() @@ -977,7 +977,7 @@ func Test_win_splitmove() call assert_equal(bufname(winbufnr(2)), 'b') call assert_equal(bufname(winbufnr(3)), 'a') call assert_equal(bufname(winbufnr(4)), 'd') - call assert_fails('call win_splitmove(winnr(), winnr("k"), test_null_dict())', 'E474:') + call assert_fails('call win_splitmove(winnr(), winnr("k"), test_null_dict())', 'E1297:') only | bd call assert_fails('call win_splitmove(winnr(), 123)', 'E957:') diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -149,11 +149,8 @@ f_prop_add(typval_T *argvars, typval_T * start_lnum = tv_get_number(&argvars[0]); start_col = tv_get_number(&argvars[1]); - if (argvars[2].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 2) == FAIL) return; - } rettv->vval.v_number = prop_add_common(start_lnum, start_col, argvars[2].vval.v_dict, curbuf, &argvars[2]); @@ -1045,11 +1042,8 @@ f_prop_find(typval_T *argvars, typval_T || check_for_opt_string_arg(argvars, 1) == FAIL)) return; - if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) - { - emsg(_(e_dictionary_required)); + if (check_for_nonnull_dict_arg(argvars, 0) == FAIL) return; - } dict = argvars[0].vval.v_dict; if (get_bufnr_from_arg(&argvars[0], &buf) == FAIL) @@ -1396,11 +1390,8 @@ f_prop_list(typval_T *argvars, typval_T { dict_T *d; - if (argvars[1].v_type != VAR_DICT) - { - emsg(_(e_dictionary_required)); + if (check_for_dict_arg(argvars, 1) == FAIL) return; - } d = argvars[1].vval.v_dict; if (get_bufnr_from_arg(&argvars[1], &buf) == FAIL) @@ -1499,11 +1490,8 @@ f_prop_remove(typval_T *argvars, typval_ && check_for_opt_number_arg(argvars, 2) == FAIL))) return; - if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) - { - emsg(_(e_invalid_argument)); + if (check_for_nonnull_dict_arg(argvars, 0) == FAIL) return; - } if (argvars[1].v_type != VAR_UNKNOWN) { diff --git a/src/time.c b/src/time.c --- a/src/time.c +++ b/src/time.c @@ -872,12 +872,10 @@ f_timer_start(typval_T *argvars, typval_ msec = (long)tv_get_number(&argvars[0]); if (argvars[2].v_type != VAR_UNKNOWN) { - if (argvars[2].v_type != VAR_DICT - || (dict = argvars[2].vval.v_dict) == NULL) - { - semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2])); + if (check_for_nonnull_dict_arg(argvars, 2) == FAIL) return; - } + + dict = argvars[2].vval.v_dict; if (dict_has_key(dict, "repeat")) repeat = dict_get_number(dict, "repeat"); } diff --git a/src/typval.c b/src/typval.c --- a/src/typval.c +++ b/src/typval.c @@ -533,6 +533,23 @@ check_for_dict_arg(typval_T *args, int i } /* + * Give an error and return FAIL unless "args[idx]" is a non-NULL dict. + */ + int +check_for_nonnull_dict_arg(typval_T *args, int idx) +{ + if (check_for_dict_arg(args, idx) == FAIL) + return FAIL; + + if (args[idx].vval.v_dict == NULL) + { + semsg(_(e_non_null_dict_required_for_argument_nr), idx + 1); + return FAIL; + } + return OK; +} + +/* * Check for an optional dict argument at 'idx' */ int @@ -1179,7 +1196,7 @@ typval_compare( if (type_is && tv1->v_type != tv2->v_type) { - // For "is" a different type always means FALSE, for "notis" + // For "is" a different type always means FALSE, for "isnot" // it means TRUE. n1 = (type == EXPR_ISNOT); } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -708,6 +708,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 335, +/**/ 334, /**/ 333,