Skip to content

Commit 5deeb3f

Browse files
committed
patch 8.2.0512: Vim9: no optional arguments in func type
Problem: Vim9: no optional arguments in func type. Solution: Check for question mark after type. Find function reference without function().
1 parent d7ffc0b commit 5deeb3f

13 files changed

Lines changed: 733 additions & 459 deletions

src/globals.h

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -379,39 +379,39 @@ EXTERN sctx_T current_sctx INIT4(0, 0, 0, 0);
379379

380380

381381
// Commonly used types.
382-
EXTERN type_T t_any INIT5(VAR_UNKNOWN, 0, 0, NULL, NULL);
383-
EXTERN type_T t_void INIT5(VAR_VOID, 0, 0, NULL, NULL);
384-
EXTERN type_T t_bool INIT5(VAR_BOOL, 0, 0, NULL, NULL);
385-
EXTERN type_T t_special INIT5(VAR_SPECIAL, 0, 0, NULL, NULL);
386-
EXTERN type_T t_number INIT5(VAR_NUMBER, 0, 0, NULL, NULL);
387-
EXTERN type_T t_float INIT5(VAR_FLOAT, 0, 0, NULL, NULL);
388-
EXTERN type_T t_string INIT5(VAR_STRING, 0, 0, NULL, NULL);
389-
EXTERN type_T t_blob INIT5(VAR_BLOB, 0, 0, NULL, NULL);
390-
EXTERN type_T t_job INIT5(VAR_JOB, 0, 0, NULL, NULL);
391-
EXTERN type_T t_channel INIT5(VAR_CHANNEL, 0, 0, NULL, NULL);
392-
393-
EXTERN type_T t_func_void INIT5(VAR_FUNC, -1, 0, &t_void, NULL);
394-
EXTERN type_T t_func_any INIT5(VAR_FUNC, -1, 0, &t_any, NULL);
395-
EXTERN type_T t_func_number INIT5(VAR_FUNC, -1, 0, &t_number, NULL);
396-
EXTERN type_T t_func_string INIT5(VAR_FUNC, -1, 0, &t_string, NULL);
397-
EXTERN type_T t_func_0_void INIT5(VAR_FUNC, 0, 0, &t_void, NULL);
398-
EXTERN type_T t_func_0_any INIT5(VAR_FUNC, 0, 0, &t_any, NULL);
399-
EXTERN type_T t_func_0_number INIT5(VAR_FUNC, 0, 0, &t_number, NULL);
400-
EXTERN type_T t_func_0_string INIT5(VAR_FUNC, 0, 0, &t_string, NULL);
401-
402-
EXTERN type_T t_list_any INIT5(VAR_LIST, 0, 0, &t_any, NULL);
403-
EXTERN type_T t_dict_any INIT5(VAR_DICT, 0, 0, &t_any, NULL);
404-
EXTERN type_T t_list_empty INIT5(VAR_LIST, 0, 0, &t_void, NULL);
405-
EXTERN type_T t_dict_empty INIT5(VAR_DICT, 0, 0, &t_void, NULL);
406-
407-
EXTERN type_T t_list_bool INIT5(VAR_LIST, 0, 0, &t_bool, NULL);
408-
EXTERN type_T t_list_number INIT5(VAR_LIST, 0, 0, &t_number, NULL);
409-
EXTERN type_T t_list_string INIT5(VAR_LIST, 0, 0, &t_string, NULL);
410-
EXTERN type_T t_list_dict_any INIT5(VAR_LIST, 0, 0, &t_dict_any, NULL);
411-
412-
EXTERN type_T t_dict_bool INIT5(VAR_DICT, 0, 0, &t_bool, NULL);
413-
EXTERN type_T t_dict_number INIT5(VAR_DICT, 0, 0, &t_number, NULL);
414-
EXTERN type_T t_dict_string INIT5(VAR_DICT, 0, 0, &t_string, NULL);
382+
EXTERN type_T t_any INIT6(VAR_UNKNOWN, 0, 0, 0, NULL, NULL);
383+
EXTERN type_T t_void INIT6(VAR_VOID, 0, 0, 0, NULL, NULL);
384+
EXTERN type_T t_bool INIT6(VAR_BOOL, 0, 0, 0, NULL, NULL);
385+
EXTERN type_T t_special INIT6(VAR_SPECIAL, 0, 0, 0, NULL, NULL);
386+
EXTERN type_T t_number INIT6(VAR_NUMBER, 0, 0, 0, NULL, NULL);
387+
EXTERN type_T t_float INIT6(VAR_FLOAT, 0, 0, 0, NULL, NULL);
388+
EXTERN type_T t_string INIT6(VAR_STRING, 0, 0, 0, NULL, NULL);
389+
EXTERN type_T t_blob INIT6(VAR_BLOB, 0, 0, 0, NULL, NULL);
390+
EXTERN type_T t_job INIT6(VAR_JOB, 0, 0, 0, NULL, NULL);
391+
EXTERN type_T t_channel INIT6(VAR_CHANNEL, 0, 0, 0, NULL, NULL);
392+
393+
EXTERN type_T t_func_void INIT6(VAR_FUNC, -1, 0, 0, &t_void, NULL);
394+
EXTERN type_T t_func_any INIT6(VAR_FUNC, -1, 0, 0, &t_any, NULL);
395+
EXTERN type_T t_func_number INIT6(VAR_FUNC, -1, 0, 0, &t_number, NULL);
396+
EXTERN type_T t_func_string INIT6(VAR_FUNC, -1, 0, 0, &t_string, NULL);
397+
EXTERN type_T t_func_0_void INIT6(VAR_FUNC, 0, 0, 0, &t_void, NULL);
398+
EXTERN type_T t_func_0_any INIT6(VAR_FUNC, 0, 0, 0, &t_any, NULL);
399+
EXTERN type_T t_func_0_number INIT6(VAR_FUNC, 0, 0, 0, &t_number, NULL);
400+
EXTERN type_T t_func_0_string INIT6(VAR_FUNC, 0, 0, 0, &t_string, NULL);
401+
402+
EXTERN type_T t_list_any INIT6(VAR_LIST, 0, 0, 0, &t_any, NULL);
403+
EXTERN type_T t_dict_any INIT6(VAR_DICT, 0, 0, 0, &t_any, NULL);
404+
EXTERN type_T t_list_empty INIT6(VAR_LIST, 0, 0, 0, &t_void, NULL);
405+
EXTERN type_T t_dict_empty INIT6(VAR_DICT, 0, 0, 0, &t_void, NULL);
406+
407+
EXTERN type_T t_list_bool INIT6(VAR_LIST, 0, 0, 0, &t_bool, NULL);
408+
EXTERN type_T t_list_number INIT6(VAR_LIST, 0, 0, 0, &t_number, NULL);
409+
EXTERN type_T t_list_string INIT6(VAR_LIST, 0, 0, 0, &t_string, NULL);
410+
EXTERN type_T t_list_dict_any INIT6(VAR_LIST, 0, 0, 0, &t_dict_any, NULL);
411+
412+
EXTERN type_T t_dict_bool INIT6(VAR_DICT, 0, 0, 0, &t_bool, NULL);
413+
EXTERN type_T t_dict_number INIT6(VAR_DICT, 0, 0, 0, &t_number, NULL);
414+
EXTERN type_T t_dict_string INIT6(VAR_DICT, 0, 0, 0, &t_string, NULL);
415415

416416

417417
#endif

src/structs.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,10 +1341,11 @@ typedef enum
13411341
typedef struct type_S type_T;
13421342
struct type_S {
13431343
vartype_T tt_type;
1344-
short tt_argcount; // for func, partial, -1 for unknown
1345-
short tt_flags; // TTFLAG_ values
1344+
char tt_argcount; // for func, -1 for unknown
1345+
char tt_min_argcount; // number of non-optional arguments
1346+
char tt_flags; // TTFLAG_ values
13461347
type_T *tt_member; // for list, dict, func return type
1347-
type_T **tt_args; // func arguments, allocated
1348+
type_T **tt_args; // func argument types, allocated
13481349
};
13491350

13501351
#define TTFLAG_VARARGS 1 // func args ends with "..."
@@ -1520,7 +1521,7 @@ typedef struct
15201521
int uf_calls; // nr of active calls
15211522
int uf_cleared; // func_clear() was already called
15221523
int uf_dfunc_idx; // >= 0 for :def function only
1523-
garray_T uf_args; // arguments
1524+
garray_T uf_args; // arguments, including optional arguments
15241525
garray_T uf_def_args; // default argument expressions
15251526

15261527
// for :def (for :function uf_ret_type is NULL)
@@ -1531,6 +1532,7 @@ typedef struct
15311532
// uf_def_args; length: uf_def_args.ga_len + 1
15321533
char_u *uf_va_name; // name from "...name" or NULL
15331534
type_T *uf_va_type; // type from "...name: type" or NULL
1535+
type_T *uf_func_type; // type of the function, &t_func_any if unknown
15341536

15351537
garray_T uf_lines; // function lines
15361538
# ifdef FEAT_PROFILE

src/testdir/Make_all.mak

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ NEW_TESTS = \
274274
test_vartabs \
275275
test_vim9_disassemble \
276276
test_vim9_expr \
277+
test_vim9_func \
277278
test_vim9_script \
278279
test_viminfo \
279280
test_vimscript \
@@ -483,6 +484,7 @@ NEW_TESTS_RES = \
483484
test_vartabs.res \
484485
test_vim9_disassemble.res \
485486
test_vim9_expr.res \
487+
test_vim9_func.res \
486488
test_vim9_script.res \
487489
test_viminfo.res \
488490
test_vimscript.res \

src/testdir/test_vim9_disassemble.vim

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@ enddef
8787
def Test_disassemble_store()
8888
let res = execute('disass s:ScriptFuncStore')
8989
assert_match('<SNR>\d*_ScriptFuncStore.*'
90+
\ .. 'let localnr = 1.*'
9091
\ .. 'localnr = 2.*'
9192
\ .. ' STORE 2 in $0.*'
93+
\ .. 'let localstr = ''abc''.*'
9294
\ .. 'localstr = ''xyz''.*'
9395
\ .. ' STORE $1.*'
9496
\ .. 'v:char = ''abc''.*'
@@ -360,22 +362,22 @@ def Test_disassemble_const_expr()
360362
enddef
361363

362364
def WithFunc()
363-
let funky1: func
364-
let funky2: func = function("len")
365-
let party2: func = funcref("UserFunc")
365+
let Funky1: func
366+
let Funky2: func = function("len")
367+
let Party2: func = funcref("UserFunc")
366368
enddef
367369

368370
def Test_disassemble_function()
369371
let instr = execute('disassemble WithFunc')
370372
assert_match('WithFunc.*'
371-
\ .. 'let funky1: func.*'
373+
\ .. 'let Funky1: func.*'
372374
\ .. '0 PUSHFUNC "\[none]".*'
373375
\ .. '1 STORE $0.*'
374-
\ .. 'let funky2: func = function("len").*'
376+
\ .. 'let Funky2: func = function("len").*'
375377
\ .. '2 PUSHS "len".*'
376378
\ .. '3 BCALL function(argc 1).*'
377379
\ .. '4 STORE $1.*'
378-
\ .. 'let party2: func = funcref("UserFunc").*'
380+
\ .. 'let Party2: func = funcref("UserFunc").*'
379381
\ .. '\d PUSHS "UserFunc".*'
380382
\ .. '\d BCALL funcref(argc 1).*'
381383
\ .. '\d STORE $2.*'

src/testdir/test_vim9_expr.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,8 @@ func Test_expr4_fails()
460460

461461
call CheckDefFailureMult(['let j: job', 'let chan: channel', 'let r = j == chan'], 'Cannot compare job with channel')
462462
call CheckDefFailureMult(['let j: job', 'let x: list<any>', 'let r = j == x'], 'Cannot compare job with list')
463-
call CheckDefFailureMult(['let j: job', 'let x: func', 'let r = j == x'], 'Cannot compare job with func')
464-
call CheckDefFailureMult(['let j: job', 'let x: func', 'let r = j == x'], 'Cannot compare job with func')
463+
call CheckDefFailureMult(['let j: job', 'let Xx: func', 'let r = j == Xx'], 'Cannot compare job with func')
464+
call CheckDefFailureMult(['let j: job', 'let Xx: func', 'let r = j == Xx'], 'Cannot compare job with func')
465465
endfunc
466466

467467
" test addition, subtraction, concatenation

0 commit comments

Comments
 (0)