0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

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.
This commit is contained in:
Bram Moolenaar 2020-03-01 23:32:25 +01:00
parent 815eb83b09
commit 61a6d4e48b
6 changed files with 70 additions and 13 deletions

View File

@ -386,7 +386,7 @@ let s:flaky_errors_re = 'StopVimInTerminal\|VerifyScreenDump'
redir @q redir @q
silent function /^Test_ silent function /^Test_
redir END 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 there is an extra argument filter the function names against it.
if argc() > 1 if argc() > 1

View File

@ -814,4 +814,36 @@ def Test_disassemble_execute()
\, res) \, res)
enddef 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 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@ -66,6 +66,9 @@ def Test_assignment()
let party1: partial let party1: partial
let party2: partial = funcref('Test_syntax') let party2: partial = funcref('Test_syntax')
" type becomes list<any>
let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
g:newvar = 'new' g:newvar = 'new'
assert_equal('new', g:newvar) assert_equal('new', g:newvar)

View File

@ -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 static void
list_func_head(ufunc_T *fp, int indent) list_func_head(ufunc_T *fp, int indent)
@ -1912,7 +1912,10 @@ list_func_head(ufunc_T *fp, int indent)
msg_start(); msg_start();
if (indent) if (indent)
msg_puts(" "); 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_puts((char *)printable_func_name(fp));
msg_putchar('('); msg_putchar('(');
for (j = 0; j < fp->uf_args.ga_len; ++j) for (j = 0; j < fp->uf_args.ga_len; ++j)
@ -1957,7 +1960,19 @@ list_func_head(ufunc_T *fp, int indent)
} }
} }
msg_putchar(')'); 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"); msg_puts(" abort");
if (fp->uf_flags & FC_RANGE) if (fp->uf_flags & FC_RANGE)
msg_puts(" range"); msg_puts(" range");

View File

@ -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 */
/**/
346,
/**/ /**/
345, 345,
/**/ /**/

View File

@ -1443,7 +1443,7 @@ equal_type(type_T *type1, type_T *type2)
case VAR_BLOB: case VAR_BLOB:
case VAR_JOB: case VAR_JOB:
case VAR_CHANNEL: case VAR_CHANNEL:
return TRUE; // not composite is always OK break; // not composite is always OK
case VAR_LIST: case VAR_LIST:
case VAR_DICT: case VAR_DICT:
return equal_type(type1->tt_member, type2->tt_member); 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. * "type2" and "dest" may be the same.
*/ */
static void 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 (equal_type(type1, type2))
{ {
if (dest != type2) *dest = type1;
*dest = *type2;
return; return;
} }
if (type1->tt_type == type2->tt_type) if (type1->tt_type == type2->tt_type)
{ {
dest->tt_type = type1->tt_type;
if (type1->tt_type == VAR_LIST || type2->tt_type == VAR_DICT) 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; return;
} }
// TODO: VAR_FUNC and VAR_PARTIAL // TODO: VAR_FUNC and VAR_PARTIAL
*dest = type1;
} }
dest->tt_type = VAR_UNKNOWN; // "any" *dest = &t_any;
} }
char * char *
@ -1501,7 +1506,7 @@ vartype_name(vartype_T type)
case VAR_CHANNEL: return "channel"; case VAR_CHANNEL: return "channel";
case VAR_LIST: return "list"; case VAR_LIST: return "list";
case VAR_DICT: return "dict"; case VAR_DICT: return "dict";
case VAR_FUNC: return "function"; case VAR_FUNC: return "func";
case VAR_PARTIAL: return "partial"; case VAR_PARTIAL: return "partial";
} }
return "???"; return "???";
@ -3160,7 +3165,7 @@ compile_expr1(char_u **arg, cctx_T *cctx)
// If the types differ, the result has a more generic type. // If the types differ, the result has a more generic type.
type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 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 // jump here from JUMP_ALWAYS
isn = ((isn_T *)instr->ga_data) + end_idx; isn = ((isn_T *)instr->ga_data) + end_idx;