mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:partial:9.0.0359: error message for wrong argument type is not specific (#23315)
Problem: Error message for wrong argument type is not specific.
Solution: Include more information in the error. (Yegappan Lakshmanan,
closes vim/vim#11037)
8deb2b30c7
Skip reduce() and deepcopy() changes because of missing patches.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
parent
ac9f8669a8
commit
7e0d668012
@ -3466,8 +3466,7 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
|
||||
| WILD_NO_BEEP | WILD_HOME_REPLACE;
|
||||
|
||||
if (argvars[1].v_type != VAR_STRING) {
|
||||
semsg(_(e_invarg2), "type must be a string");
|
||||
if (tv_check_for_string_arg(argvars, 1) == FAIL) {
|
||||
return;
|
||||
}
|
||||
const char *const type = tv_get_string(&argvars[1]);
|
||||
|
@ -793,12 +793,9 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
rettv->vval.v_number = -1;
|
||||
|
||||
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_BOOL)) {
|
||||
emsg(_(e_invarg));
|
||||
if ((tv_check_for_string_arg(argvars, 0) == FAIL
|
||||
|| tv_check_for_number_arg(argvars, 1) == FAIL
|
||||
|| tv_check_for_opt_bool_arg(argvars, 2) == FAIL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3114,14 +3111,12 @@ static void f_glob2regpat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
/// "gettext()" function
|
||||
static void f_gettext(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
if (argvars[0].v_type != VAR_STRING
|
||||
|| argvars[0].vval.v_string == NULL
|
||||
|| *argvars[0].vval.v_string == NUL) {
|
||||
semsg(_(e_invarg2), tv_get_string(&argvars[0]));
|
||||
} else {
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = xstrdup(_(argvars[0].vval.v_string));
|
||||
if (tv_check_for_nonempty_string_arg(argvars, 0) == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = xstrdup(_(argvars[0].vval.v_string));
|
||||
}
|
||||
|
||||
/// "has()" function
|
||||
@ -7641,7 +7636,9 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
// default is to replace the stack.
|
||||
if (argvars[2].v_type == VAR_UNKNOWN) {
|
||||
// action = 'r';
|
||||
} else if (argvars[2].v_type == VAR_STRING) {
|
||||
} else if (tv_check_for_string_arg(argvars, 2) == FAIL) {
|
||||
return;
|
||||
} else {
|
||||
const char *actstr;
|
||||
actstr = tv_get_string_chk(&argvars[2]);
|
||||
if (actstr == NULL) {
|
||||
@ -7654,9 +7651,6 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
semsg(_(e_invact2), actstr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
emsg(_(e_stringreq));
|
||||
return;
|
||||
}
|
||||
|
||||
if (set_tagstack(wp, d, action) == OK) {
|
||||
@ -8937,12 +8931,13 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
/// "timer_info([timer])" function
|
||||
static void f_timer_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
tv_list_alloc_ret(rettv, kListLenUnknown);
|
||||
|
||||
if (tv_check_for_opt_number_arg(argvars, 0) == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (argvars[0].v_type != VAR_UNKNOWN) {
|
||||
if (argvars[0].v_type != VAR_NUMBER) {
|
||||
emsg(_(e_number_exp));
|
||||
return;
|
||||
}
|
||||
tv_list_alloc_ret(rettv, 1);
|
||||
timer_T *timer = find_timer_by_nr(tv_get_number(&argvars[0]));
|
||||
if (timer != NULL && (!timer->stopped || timer->refcount > 1)) {
|
||||
add_timer_info(rettv, timer);
|
||||
@ -9008,8 +9003,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
/// "timer_stop(timerid)" function
|
||||
static void f_timer_stop(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
if (argvars[0].v_type != VAR_NUMBER) {
|
||||
emsg(_(e_number_exp));
|
||||
if (tv_check_for_number_arg(argvars, 0) == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9136,8 +9130,7 @@ static void f_trim(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_STRING) {
|
||||
semsg(_(e_invarg2), tv_get_string(&argvars[1]));
|
||||
if (tv_check_for_opt_string_arg(argvars, 1) == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,8 @@ static const char e_number_required_for_argument_nr[]
|
||||
= N_("E1210: Number required for argument %d");
|
||||
static const char e_list_required_for_argument_nr[]
|
||||
= N_("E1211: List required for argument %d");
|
||||
static const char e_bool_required_for_argument_nr[]
|
||||
= N_("E1212: Bool required for argument %d");
|
||||
static const char e_string_or_list_required_for_argument_nr[]
|
||||
= N_("E1222: String or List required for argument %d");
|
||||
static const char e_list_or_blob_required_for_argument_nr[]
|
||||
@ -4000,6 +4002,14 @@ int tv_check_for_nonempty_string_arg(const typval_T *const args, const int idx)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Check for an optional string argument at "idx"
|
||||
int tv_check_for_opt_string_arg(const typval_T *const args, const int idx)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
|
||||
{
|
||||
return (args[idx].v_type == VAR_UNKNOWN
|
||||
|| tv_check_for_string_arg(args, idx) != FAIL) ? OK : FAIL;
|
||||
}
|
||||
|
||||
/// Give an error and return FAIL unless "args[idx]" is a number.
|
||||
int tv_check_for_number_arg(const typval_T *const args, const int idx)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
|
||||
@ -4019,6 +4029,31 @@ int tv_check_for_opt_number_arg(const typval_T *const args, const int idx)
|
||||
|| tv_check_for_number_arg(args, idx) != FAIL) ? OK : FAIL;
|
||||
}
|
||||
|
||||
/// Give an error and return FAIL unless "args[idx]" is a bool.
|
||||
int tv_check_for_bool_arg(const typval_T *const args, const int idx)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
|
||||
{
|
||||
if (args[idx].v_type != VAR_BOOL
|
||||
&& !(args[idx].v_type == VAR_NUMBER
|
||||
&& (args[idx].vval.v_number == 0
|
||||
|| args[idx].vval.v_number == 1))) {
|
||||
semsg(_(e_bool_required_for_argument_nr), idx + 1);
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Check for an optional bool argument at "idx".
|
||||
/// Return FAIL if the type is wrong.
|
||||
int tv_check_for_opt_bool_arg(const typval_T *const args, const int idx)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
|
||||
{
|
||||
if (args[idx].v_type == VAR_UNKNOWN) {
|
||||
return OK;
|
||||
}
|
||||
return tv_check_for_bool_arg(args, idx);
|
||||
}
|
||||
|
||||
/// Give an error and return FAIL unless "args[idx]" is a blob.
|
||||
int tv_check_for_blob_arg(const typval_T *const args, const int idx)
|
||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
|
||||
|
@ -2406,15 +2406,12 @@ void f_sign_unplace(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
|
||||
if (argvars[0].v_type != VAR_STRING) {
|
||||
emsg(_(e_invarg));
|
||||
if (tv_check_for_string_arg(argvars, 0) == FAIL
|
||||
|| tv_check_for_opt_dict_arg(argvars, 1) == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN) {
|
||||
if (tv_check_for_dict_arg(argvars, 1) == FAIL) {
|
||||
return;
|
||||
}
|
||||
dict = argvars[1].vval.v_dict;
|
||||
}
|
||||
|
||||
|
@ -337,6 +337,16 @@ func Test_assert_with_msg()
|
||||
call remove(v:errors, 0)
|
||||
endfunc
|
||||
|
||||
func Test_override()
|
||||
throw 'Skipped: Nvim does not support test_override()'
|
||||
call test_override('char_avail', 1)
|
||||
eval 1->test_override('redraw')
|
||||
call test_override('ALL', 0)
|
||||
call assert_fails("call test_override('xxx', 1)", 'E475:')
|
||||
call assert_fails("call test_override('redraw', 'yes')", 'E474:')
|
||||
call assert_fails("call test_override('redraw', 'yes')", 'E1210:')
|
||||
endfunc
|
||||
|
||||
func Test_mouse_position()
|
||||
let save_mouse = &mouse
|
||||
set mouse=a
|
||||
|
@ -652,7 +652,7 @@ func Test_getcompletion()
|
||||
|
||||
call assert_fails("call getcompletion('\\\\@!\\\\@=', 'buffer')", 'E871:')
|
||||
call assert_fails('call getcompletion("", "burp")', 'E475:')
|
||||
call assert_fails('call getcompletion("abc", [])', 'E475:')
|
||||
call assert_fails('call getcompletion("abc", [])', 'E1174:')
|
||||
endfunc
|
||||
|
||||
" Test for getcompletion() with "fuzzy" in 'wildoptions'
|
||||
|
@ -1115,11 +1115,11 @@ func Test_charidx()
|
||||
call assert_equal(-1, charidx(a, 8, 1))
|
||||
call assert_equal(-1, charidx('', 0, 1))
|
||||
|
||||
call assert_fails('let x = charidx([], 1)', 'E474:')
|
||||
call assert_fails('let x = charidx("abc", [])', 'E474:')
|
||||
call assert_fails('let x = charidx("abc", 1, [])', 'E474:')
|
||||
call assert_fails('let x = charidx("abc", 1, -1)', 'E1023:')
|
||||
call assert_fails('let x = charidx("abc", 1, 2)', 'E1023:')
|
||||
call assert_fails('let x = charidx([], 1)', 'E1174:')
|
||||
call assert_fails('let x = charidx("abc", [])', 'E1210:')
|
||||
call assert_fails('let x = charidx("abc", 1, [])', 'E1212:')
|
||||
call assert_fails('let x = charidx("abc", 1, -1)', 'E1212:')
|
||||
call assert_fails('let x = charidx("abc", 1, 2)', 'E1212:')
|
||||
endfunc
|
||||
|
||||
func Test_count()
|
||||
@ -1605,7 +1605,7 @@ func Test_trim()
|
||||
call assert_fails('eval trim(" vim ", " ", [])', 'E745:')
|
||||
call assert_fails('eval trim(" vim ", " ", -1)', 'E475:')
|
||||
call assert_fails('eval trim(" vim ", " ", 3)', 'E475:')
|
||||
call assert_fails('eval trim(" vim ", 0)', 'E475:')
|
||||
call assert_fails('eval trim(" vim ", 0)', 'E1174:')
|
||||
|
||||
let chars = join(map(range(1, 0x20) + [0xa0], {n -> n->nr2char()}), '')
|
||||
call assert_equal("x", trim(chars . "x" . chars))
|
||||
@ -2567,7 +2567,7 @@ endfunc
|
||||
|
||||
" Test for gettext()
|
||||
func Test_gettext()
|
||||
call assert_fails('call gettext(1)', 'E475:')
|
||||
call assert_fails('call gettext(1)', 'E1174:')
|
||||
endfunc
|
||||
|
||||
func Test_builtin_check()
|
||||
|
@ -700,7 +700,7 @@ func Test_sign_group()
|
||||
call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs)
|
||||
|
||||
" Error case
|
||||
call assert_fails("call sign_unplace({})", 'E474:')
|
||||
call assert_fails("call sign_unplace({})", 'E1174:')
|
||||
|
||||
" Place a sign in the global group and try to delete it using a group
|
||||
call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10}))
|
||||
|
@ -407,7 +407,7 @@ func Test_getsettagstack()
|
||||
call assert_equal(-1, settagstack(100, {'items' : []}))
|
||||
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' : []}, 10)", 'E1174:')
|
||||
call assert_fails("call settagstack(1, {'items' : []}, 'b')", 'E962:')
|
||||
call assert_equal(-1, settagstack(0, v:_null_dict))
|
||||
|
||||
|
@ -93,7 +93,7 @@ func Test_timer_info()
|
||||
call timer_stop(id)
|
||||
call assert_equal([], timer_info(id))
|
||||
|
||||
call assert_fails('call timer_info("abc")', 'E39:')
|
||||
call assert_fails('call timer_info("abc")', 'E1210:')
|
||||
|
||||
" check repeat count inside the callback
|
||||
let g:timer_repeat = []
|
||||
@ -236,7 +236,7 @@ func Test_timer_errors()
|
||||
|
||||
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:')
|
||||
call assert_fails('call timer_stop("abc")', 'E1210:')
|
||||
endfunc
|
||||
|
||||
func FuncWithCaughtError(timer)
|
||||
|
Loading…
Reference in New Issue
Block a user