mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.0528: Vim9: function arguments insufficiently tested
Problem: Vim9: function arguments insufficiently tested. Solution: Check types. Add more tests. Fix function with varargs only.
This commit is contained in:
parent
ec5929d0fe
commit
0b76b42d0a
@ -130,6 +130,19 @@ def Test_call_def_varargs()
|
||||
assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
|
||||
enddef
|
||||
|
||||
" Only varargs
|
||||
def MyVarargsOnly(...args: list<string>): string
|
||||
return join(args, ',')
|
||||
enddef
|
||||
|
||||
def Test_call_varargs_only()
|
||||
assert_equal('', MyVarargsOnly())
|
||||
assert_equal('one', MyVarargsOnly('one'))
|
||||
assert_equal('one,two', MyVarargsOnly('one', 'two'))
|
||||
call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
|
||||
call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
|
||||
enddef
|
||||
|
||||
def Test_using_var_as_arg()
|
||||
call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
|
||||
call assert_fails('so Xdef', 'E1006:')
|
||||
|
@ -3020,7 +3020,7 @@ ex_function(exarg_T *eap)
|
||||
|
||||
if (eap->cmdidx == CMD_def)
|
||||
{
|
||||
int lnum_save = SOURCING_LNUM;
|
||||
int lnum_save = SOURCING_LNUM;
|
||||
|
||||
// error messages are for the first function line
|
||||
SOURCING_LNUM = sourcing_lnum_top;
|
||||
@ -3034,7 +3034,8 @@ ex_function(exarg_T *eap)
|
||||
// and uf_va_type.
|
||||
int len = argtypes.ga_len - (varargs ? 1 : 0);
|
||||
|
||||
fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len);
|
||||
if (len > 0)
|
||||
fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len);
|
||||
if (fp->uf_arg_types != NULL)
|
||||
{
|
||||
int i;
|
||||
|
@ -738,6 +738,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
528,
|
||||
/**/
|
||||
527,
|
||||
/**/
|
||||
|
@ -130,6 +130,8 @@ static int compile_expr1(char_u **arg, cctx_T *cctx);
|
||||
static int compile_expr2(char_u **arg, cctx_T *cctx);
|
||||
static int compile_expr3(char_u **arg, cctx_T *cctx);
|
||||
static void delete_def_function_contents(dfunc_T *dfunc);
|
||||
static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx);
|
||||
static int check_type(type_T *expected, type_T *actual, int give_msg);
|
||||
|
||||
/*
|
||||
* Lookup variable "name" in the local scope and return the index.
|
||||
@ -1240,6 +1242,32 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (ufunc->uf_dfunc_idx >= 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argcount; ++i)
|
||||
{
|
||||
type_T *expected;
|
||||
type_T *actual;
|
||||
|
||||
if (i < regular_args)
|
||||
{
|
||||
if (ufunc->uf_arg_types == NULL)
|
||||
continue;
|
||||
expected = ufunc->uf_arg_types[i];
|
||||
}
|
||||
else
|
||||
expected = ufunc->uf_va_type->tt_member;
|
||||
actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
|
||||
if (check_type(expected, actual, FALSE) == FAIL)
|
||||
{
|
||||
arg_type_mismatch(expected, actual, i + 1);
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Turn varargs into a list.
|
||||
if (ufunc->uf_va_name != NULL)
|
||||
{
|
||||
@ -2403,6 +2431,18 @@ type_mismatch(type_T *expected, type_T *actual)
|
||||
vim_free(tofree2);
|
||||
}
|
||||
|
||||
static void
|
||||
arg_type_mismatch(type_T *expected, type_T *actual, int argidx)
|
||||
{
|
||||
char *tofree1, *tofree2;
|
||||
|
||||
semsg(_("E1013: argument %d: type mismatch, expected %s but got %s"),
|
||||
argidx,
|
||||
type_name(expected, &tofree1), type_name(actual, &tofree2));
|
||||
vim_free(tofree1);
|
||||
vim_free(tofree2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the expected and actual types match.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user