From 61a6d4e48b4778bdbc741af8ac59519b70f65db8 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 1 Mar 2020 23:32:25 +0100 Subject: patch 8.2.0346: Vim9: finding common list type not tested Problem: Vim9: finding common list type not tested. Solution: Add more tests. Fix listing function. Fix overwriting type. --- src/testdir/runtest.vim | 2 +- src/testdir/test_vim9_disassemble.vim | 32 ++++++++++++++++++++++++++++++++ src/testdir/test_vim9_script.vim | 3 +++ src/userfunc.c | 21 ++++++++++++++++++--- src/version.c | 2 ++ src/vim9compile.c | 23 ++++++++++++++--------- 6 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/testdir/runtest.vim b/src/testdir/runtest.vim index f0cc1abff3..d8a1cf730a 100644 --- a/src/testdir/runtest.vim +++ b/src/testdir/runtest.vim @@ -386,7 +386,7 @@ let s:flaky_errors_re = 'StopVimInTerminal\|VerifyScreenDump' redir @q silent function /^Test_ redir END -let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g')) +let s:tests = split(substitute(@q, '\(function\|def\) \(\k*()\)', '\2', 'g')) " If there is an extra argument filter the function names against it. if argc() > 1 diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 7875e847e7..5ba18dd5c3 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -814,4 +814,36 @@ def Test_disassemble_execute() \, res) enddef +def SomeStringArg(arg: string) + echo arg +enddef + +def SomeAnyArg(arg: any) + echo arg +enddef + +def SomeStringArgAndReturn(arg: string): string + return arg +enddef + +def Test_display_func() + let res1 = execute('function SomeStringArg') + assert_match('.* def SomeStringArg(arg: string).*' + \ .. ' echo arg.*' + \ .. ' enddef' + \, res1) + + let res2 = execute('function SomeAnyArg') + assert_match('.* def SomeAnyArg(arg: any).*' + \ .. ' echo arg.*' + \ .. ' enddef' + \, res2) + + let res3 = execute('function SomeStringArgAndReturn') + assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' + \ .. ' return arg.*' + \ .. ' enddef' + \, res3) +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index c01ab83164..d5e42e8dc5 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -66,6 +66,9 @@ def Test_assignment() let party1: partial let party2: partial = funcref('Test_syntax') + " type becomes list + let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] + g:newvar = 'new' assert_equal('new', g:newvar) diff --git a/src/userfunc.c b/src/userfunc.c index 9ff78c29b5..c6c6cec3cb 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1902,7 +1902,7 @@ printable_func_name(ufunc_T *fp) } /* - * List the head of the function: "name(arg1, arg2)". + * List the head of the function: "function name(arg1, arg2)". */ static void list_func_head(ufunc_T *fp, int indent) @@ -1912,7 +1912,10 @@ list_func_head(ufunc_T *fp, int indent) msg_start(); if (indent) msg_puts(" "); - msg_puts("function "); + if (fp->uf_dfunc_idx >= 0) + msg_puts("def "); + else + msg_puts("function "); msg_puts((char *)printable_func_name(fp)); msg_putchar('('); for (j = 0; j < fp->uf_args.ga_len; ++j) @@ -1957,7 +1960,19 @@ list_func_head(ufunc_T *fp, int indent) } } msg_putchar(')'); - if (fp->uf_flags & FC_ABORT) + + if (fp->uf_dfunc_idx >= 0) + { + if (fp->uf_ret_type != &t_void) + { + char *tofree; + + msg_puts(": "); + msg_puts(type_name(fp->uf_ret_type, &tofree)); + vim_free(tofree); + } + } + else if (fp->uf_flags & FC_ABORT) msg_puts(" abort"); if (fp->uf_flags & FC_RANGE) msg_puts(" range"); diff --git a/src/version.c b/src/version.c index 6205a56490..f2f3cd7dfe 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 346, /**/ 345, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 158770c3a4..5d8dc90025 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1443,7 +1443,7 @@ equal_type(type_T *type1, type_T *type2) case VAR_BLOB: case VAR_JOB: case VAR_CHANNEL: - return TRUE; // not composite is always OK + break; // not composite is always OK case VAR_LIST: case VAR_DICT: return equal_type(type1->tt_member, type2->tt_member); @@ -1461,27 +1461,32 @@ equal_type(type_T *type1, type_T *type2) * "type2" and "dest" may be the same. */ static void -common_type(type_T *type1, type_T *type2, type_T *dest) +common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_list) { if (equal_type(type1, type2)) { - if (dest != type2) - *dest = *type2; + *dest = type1; return; } if (type1->tt_type == type2->tt_type) { - dest->tt_type = type1->tt_type; if (type1->tt_type == VAR_LIST || type2->tt_type == VAR_DICT) { - common_type(type1->tt_member, type2->tt_member, dest->tt_member); + type_T *common; + + common_type(type1->tt_member, type2->tt_member, &common, type_list); + if (type1->tt_type == VAR_LIST) + *dest = get_list_type(common, type_list); + else + *dest = get_dict_type(common, type_list); return; } // TODO: VAR_FUNC and VAR_PARTIAL + *dest = type1; } - dest->tt_type = VAR_UNKNOWN; // "any" + *dest = &t_any; } char * @@ -1501,7 +1506,7 @@ vartype_name(vartype_T type) case VAR_CHANNEL: return "channel"; case VAR_LIST: return "list"; case VAR_DICT: return "dict"; - case VAR_FUNC: return "function"; + case VAR_FUNC: return "func"; case VAR_PARTIAL: return "partial"; } return "???"; @@ -3160,7 +3165,7 @@ compile_expr1(char_u **arg, cctx_T *cctx) // If the types differ, the result has a more generic type. type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - common_type(type1, type2, type2); + common_type(type1, type2, &type2, cctx->ctx_type_list); // jump here from JUMP_ALWAYS isn = ((isn_T *)instr->ga_data) + end_idx; -- cgit v1.2.3