mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.0527: Vim9: function types insufficiently tested
Problem: Vim9: function types insufficiently tested. Solution: Add more tests. Fix white space check. Add "test_vim9" target.
This commit is contained in:
@@ -2301,7 +2301,7 @@ test1 \
|
|||||||
# export TEST_FILTER=Test_terminal_wipe_buffer
|
# export TEST_FILTER=Test_terminal_wipe_buffer
|
||||||
# A partial match also works:
|
# A partial match also works:
|
||||||
# export TEST_FILTER=wipe_buffer
|
# export TEST_FILTER=wipe_buffer
|
||||||
$(NEW_TESTS):
|
$(NEW_TESTS) test_vim9:
|
||||||
cd testdir; $(MAKE) $@ VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
cd testdir; $(MAKE) $@ VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||||
|
|
||||||
newtests:
|
newtests:
|
||||||
|
@@ -43,6 +43,19 @@ SCRIPTS_WIN32 =
|
|||||||
# Tests for the GUI.
|
# Tests for the GUI.
|
||||||
SCRIPTS_GUI =
|
SCRIPTS_GUI =
|
||||||
|
|
||||||
|
# Tests for Vim9 script.
|
||||||
|
TEST_VIM9 = \
|
||||||
|
test_vim9_disassemble \
|
||||||
|
test_vim9_expr \
|
||||||
|
test_vim9_func \
|
||||||
|
test_vim9_script
|
||||||
|
|
||||||
|
TEST_VIM9_RES = \
|
||||||
|
test_vim9_disassemble.res \
|
||||||
|
test_vim9_expr.res \
|
||||||
|
test_vim9_func.res \
|
||||||
|
test_vim9_script.res
|
||||||
|
|
||||||
# Individual tests, including the ones part of test_alot.
|
# Individual tests, including the ones part of test_alot.
|
||||||
# Please keep sorted up to test_alot.
|
# Please keep sorted up to test_alot.
|
||||||
NEW_TESTS = \
|
NEW_TESTS = \
|
||||||
@@ -272,10 +285,7 @@ NEW_TESTS = \
|
|||||||
test_utf8 \
|
test_utf8 \
|
||||||
test_utf8_comparisons \
|
test_utf8_comparisons \
|
||||||
test_vartabs \
|
test_vartabs \
|
||||||
test_vim9_disassemble \
|
$(TEST_VIM9) \
|
||||||
test_vim9_expr \
|
|
||||||
test_vim9_func \
|
|
||||||
test_vim9_script \
|
|
||||||
test_viminfo \
|
test_viminfo \
|
||||||
test_vimscript \
|
test_vimscript \
|
||||||
test_virtualedit \
|
test_virtualedit \
|
||||||
@@ -482,10 +492,7 @@ NEW_TESTS_RES = \
|
|||||||
test_user_func.res \
|
test_user_func.res \
|
||||||
test_usercommands.res \
|
test_usercommands.res \
|
||||||
test_vartabs.res \
|
test_vartabs.res \
|
||||||
test_vim9_disassemble.res \
|
$(TEST_VIM9_RES) \
|
||||||
test_vim9_expr.res \
|
|
||||||
test_vim9_func.res \
|
|
||||||
test_vim9_script.res \
|
|
||||||
test_viminfo.res \
|
test_viminfo.res \
|
||||||
test_vimscript.res \
|
test_vimscript.res \
|
||||||
test_virtualedit.res \
|
test_virtualedit.res \
|
||||||
|
@@ -79,6 +79,16 @@ $(NEW_TESTS):
|
|||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Run only tests specific for Vim9 script
|
||||||
|
test_vim9:
|
||||||
|
rm -f test_vim9_*.res test.log messages
|
||||||
|
@MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $(TEST_VIM9_RES) VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE)
|
||||||
|
@cat messages
|
||||||
|
@MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile report VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE)
|
||||||
|
@if test -f test.log; then \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
RM_ON_RUN = test.out X* viminfo
|
RM_ON_RUN = test.out X* viminfo
|
||||||
RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim test.ok benchmark.out
|
RM_ON_START = tiny.vim small.vim mbyte.vim mzscheme.vim test.ok benchmark.out
|
||||||
RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in
|
RUN_VIM = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim $(NO_INITS) -s dotest.in
|
||||||
|
@@ -373,6 +373,11 @@ def FuncNoArgRetNumber(): number
|
|||||||
return 1234
|
return 1234
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def FuncNoArgRetString(): string
|
||||||
|
funcResult = 45
|
||||||
|
return 'text'
|
||||||
|
enddef
|
||||||
|
|
||||||
def FuncOneArgNoRet(arg: number)
|
def FuncOneArgNoRet(arg: number)
|
||||||
funcResult = arg
|
funcResult = arg
|
||||||
enddef
|
enddef
|
||||||
@@ -382,6 +387,10 @@ def FuncOneArgRetNumber(arg: number): number
|
|||||||
return arg
|
return arg
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def FuncOneArgRetString(arg: string): string
|
||||||
|
return arg
|
||||||
|
enddef
|
||||||
|
|
||||||
def FuncOneArgRetAny(arg: any): any
|
def FuncOneArgRetAny(arg: any): any
|
||||||
return arg
|
return arg
|
||||||
enddef
|
enddef
|
||||||
@@ -415,6 +424,32 @@ def Test_func_type()
|
|||||||
assert_equal(13, funcResult)
|
assert_equal(13, funcResult)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_func_type_part()
|
||||||
|
let RefVoid: func: void
|
||||||
|
RefVoid = FuncNoArgNoRet
|
||||||
|
RefVoid = FuncOneArgNoRet
|
||||||
|
CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
|
||||||
|
CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
|
||||||
|
|
||||||
|
let RefAny: func(): any
|
||||||
|
RefAny = FuncNoArgRetNumber
|
||||||
|
RefAny = FuncNoArgRetString
|
||||||
|
CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()')
|
||||||
|
CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)')
|
||||||
|
|
||||||
|
let RefNr: func: number
|
||||||
|
RefNr = FuncNoArgRetNumber
|
||||||
|
RefNr = FuncOneArgRetNumber
|
||||||
|
CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()')
|
||||||
|
CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
|
||||||
|
|
||||||
|
let RefStr: func: string
|
||||||
|
RefStr = FuncNoArgRetString
|
||||||
|
RefStr = FuncOneArgRetString
|
||||||
|
CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()')
|
||||||
|
CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number')
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_func_type_fails()
|
def Test_func_type_fails()
|
||||||
CheckDefFailure(['let ref1: func()'], 'E704:')
|
CheckDefFailure(['let ref1: func()'], 'E704:')
|
||||||
|
|
||||||
|
@@ -738,6 +738,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
527,
|
||||||
/**/
|
/**/
|
||||||
526,
|
526,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -314,6 +314,11 @@ get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
|
|||||||
// recognize commonly used types
|
// recognize commonly used types
|
||||||
if (argcount <= 0)
|
if (argcount <= 0)
|
||||||
{
|
{
|
||||||
|
if (ret_type == &t_unknown)
|
||||||
|
{
|
||||||
|
// (argcount == 0) is not possible
|
||||||
|
return &t_func_unknown;
|
||||||
|
}
|
||||||
if (ret_type == &t_void)
|
if (ret_type == &t_void)
|
||||||
{
|
{
|
||||||
if (argcount == 0)
|
if (argcount == 0)
|
||||||
@@ -350,6 +355,7 @@ get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
|
|||||||
return &t_any;
|
return &t_any;
|
||||||
type->tt_type = VAR_FUNC;
|
type->tt_type = VAR_FUNC;
|
||||||
type->tt_member = ret_type;
|
type->tt_member = ret_type;
|
||||||
|
type->tt_argcount = argcount;
|
||||||
type->tt_args = NULL;
|
type->tt_args = NULL;
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@@ -1589,7 +1595,7 @@ parse_type(char_u **arg, garray_T *type_gap)
|
|||||||
if (len == 4 && STRNCMP(*arg, "func", len) == 0)
|
if (len == 4 && STRNCMP(*arg, "func", len) == 0)
|
||||||
{
|
{
|
||||||
type_T *type;
|
type_T *type;
|
||||||
type_T *ret_type = &t_any;
|
type_T *ret_type = &t_unknown;
|
||||||
int argcount = -1;
|
int argcount = -1;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
int first_optional = -1;
|
int first_optional = -1;
|
||||||
@@ -1657,7 +1663,7 @@ parse_type(char_u **arg, garray_T *type_gap)
|
|||||||
{
|
{
|
||||||
// parse return type
|
// parse return type
|
||||||
++*arg;
|
++*arg;
|
||||||
if (!VIM_ISWHITE(*p))
|
if (!VIM_ISWHITE(**arg))
|
||||||
semsg(_(e_white_after), ":");
|
semsg(_(e_white_after), ":");
|
||||||
*arg = skipwhite(*arg);
|
*arg = skipwhite(*arg);
|
||||||
ret_type = parse_type(arg, type_gap);
|
ret_type = parse_type(arg, type_gap);
|
||||||
@@ -2405,7 +2411,10 @@ check_type(type_T *expected, type_T *actual, int give_msg)
|
|||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
if (expected->tt_type != VAR_UNKNOWN && expected->tt_type != VAR_ANY)
|
// When expected is "unknown" we accept any actual type.
|
||||||
|
// When expected is "any" we accept any actual type except "void".
|
||||||
|
if (expected->tt_type != VAR_UNKNOWN
|
||||||
|
&& (expected->tt_type != VAR_ANY || actual->tt_type == VAR_VOID))
|
||||||
{
|
{
|
||||||
if (expected->tt_type != actual->tt_type)
|
if (expected->tt_type != actual->tt_type)
|
||||||
{
|
{
|
||||||
@@ -2421,8 +2430,7 @@ check_type(type_T *expected, type_T *actual, int give_msg)
|
|||||||
}
|
}
|
||||||
else if (expected->tt_type == VAR_FUNC)
|
else if (expected->tt_type == VAR_FUNC)
|
||||||
{
|
{
|
||||||
if (expected->tt_member != &t_any
|
if (expected->tt_member != &t_unknown)
|
||||||
&& expected->tt_member != &t_unknown)
|
|
||||||
ret = check_type(expected->tt_member, actual->tt_member, FALSE);
|
ret = check_type(expected->tt_member, actual->tt_member, FALSE);
|
||||||
if (ret == OK && expected->tt_argcount != -1
|
if (ret == OK && expected->tt_argcount != -1
|
||||||
&& (actual->tt_argcount < expected->tt_min_argcount
|
&& (actual->tt_argcount < expected->tt_min_argcount
|
||||||
@@ -4044,6 +4052,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
if (r == FAIL)
|
if (r == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
|
|
||||||
|
if (cctx->ctx_skip != TRUE)
|
||||||
|
{
|
||||||
stack = &cctx->ctx_type_stack;
|
stack = &cctx->ctx_type_stack;
|
||||||
stacktype = stack->ga_len == 0 ? &t_void
|
stacktype = stack->ga_len == 0 ? &t_void
|
||||||
: ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
: ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
@@ -4075,6 +4085,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
else if (*p != '=' && check_type(type, stacktype, TRUE) == FAIL)
|
else if (*p != '=' && check_type(type, stacktype, TRUE) == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (cmdidx == CMD_const)
|
else if (cmdidx == CMD_const)
|
||||||
{
|
{
|
||||||
emsg(_("E1021: const requires a value"));
|
emsg(_("E1021: const requires a value"));
|
||||||
|
Reference in New Issue
Block a user