blob: ecdbd5eacaa9980a75d71ad9c3811e73dc2db8ff [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" Test various aspects of the Vim9 script language.
2
3source check.vim
Bram Moolenaarad304702020-09-06 18:22:53 +02004source term_util.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02005source view_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00006import './vim9.vim' as v9
Bram Moolenaar47e7d702020-07-05 18:18:42 +02007source screendump.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02008
9func Test_def_basic()
10 def SomeFunc(): string
11 return 'yes'
12 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020013 call SomeFunc()->assert_equal('yes')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020014endfunc
15
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020016func Test_compiling_error()
17 " use a terminal to see the whole error message
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020018 CheckRunVimInTerminal
19
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020020 call TestCompilingError()
Bram Moolenaare8c46602021-04-05 22:27:37 +020021 call TestCompilingErrorInTry()
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020022endfunc
23
24def TestCompilingError()
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020025 var lines =<< trim END
26 vim9script
27 def Fails()
28 echo nothing
29 enddef
30 defcompile
31 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +010032 writefile(lines, 'XTest_compile_error', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +000033 var buf = g:RunVimInTerminal('-S XTest_compile_error',
Bram Moolenaare0de1712020-12-02 17:36:54 +010034 {rows: 10, wait_for_ruler: 0})
Bram Moolenaar62aec932022-01-29 21:45:34 +000035 g:WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
36 g:Term_getlines(buf, range(1, 9))))
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020037
38 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +000039 g:StopVimInTerminal(buf)
Bram Moolenaare8c46602021-04-05 22:27:37 +020040enddef
41
42def TestCompilingErrorInTry()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010043 var dir = 'Xcompdir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +010044 mkdir(dir, 'pR')
Bram Moolenaare8c46602021-04-05 22:27:37 +020045
46 var lines =<< trim END
47 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +000048 export def OnlyCompiled()
Bram Moolenaare8c46602021-04-05 22:27:37 +020049 g:runtime = 'yes'
50 invalid
51 enddef
52 END
53 writefile(lines, dir .. '/script.vim')
54
55 lines =<< trim END
56 vim9script
57 todo
58 try
59 script#OnlyCompiled()
60 catch /nothing/
61 endtry
62 END
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010063 lines[1] = 'set rtp=' .. getcwd() .. '/Xcompdir'
Bram Moolenaarf5fec052022-09-11 11:49:22 +010064 writefile(lines, 'XTest_compile_error', 'D')
Bram Moolenaare8c46602021-04-05 22:27:37 +020065
Bram Moolenaar62aec932022-01-29 21:45:34 +000066 var buf = g:RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0})
67 g:WaitForAssert(() => assert_match('Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid',
68 g:Term_getlines(buf, range(1, 9))))
Bram Moolenaare8c46602021-04-05 22:27:37 +020069
70 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +000071 g:StopVimInTerminal(buf)
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020072enddef
73
Bram Moolenaarad6d9cc2022-08-08 21:43:11 +010074def Test_comment_error()
75 v9.CheckDefFailure(['#{ comment'], 'E1170:')
76enddef
77
Bram Moolenaarb55d6182021-06-08 22:01:53 +020078def Test_compile_error_in_called_function()
79 var lines =<< trim END
80 vim9script
81 var n: number
82 def Foo()
83 &hls = n
84 enddef
85 def Bar()
86 Foo()
87 enddef
88 silent! Foo()
89 Bar()
90 END
Bram Moolenaar62aec932022-01-29 21:45:34 +000091 v9.CheckScriptFailureList(lines, ['E1012:', 'E1191:'])
Bram Moolenaarb55d6182021-06-08 22:01:53 +020092enddef
93
Bram Moolenaar22f17a22021-06-21 20:48:58 +020094def Test_wrong_function_name()
95 var lines =<< trim END
96 vim9script
97 func _Foo()
98 echo 'foo'
99 endfunc
100 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000101 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaar22f17a22021-06-21 20:48:58 +0200102
103 lines =<< trim END
104 vim9script
105 def _Foo()
106 echo 'foo'
107 enddef
108 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000109 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaardea5ab02022-02-23 22:12:02 +0000110
111 lines =<< trim END
112 vim9script
113 var Object = {}
114 function Object.Method()
115 endfunction
116 END
117 v9.CheckScriptFailure(lines, 'E1182:')
118
119 lines =<< trim END
120 vim9script
121 var Object = {}
122 def Object.Method()
123 enddef
124 END
125 v9.CheckScriptFailure(lines, 'E1182:')
126
127 lines =<< trim END
128 vim9script
129 g:Object = {}
130 function g:Object.Method()
131 endfunction
132 END
133 v9.CheckScriptFailure(lines, 'E1182:')
134
135 lines =<< trim END
136 let s:Object = {}
137 def Define()
138 function s:Object.Method()
139 endfunction
140 enddef
141 defcompile
142 END
143 v9.CheckScriptFailure(lines, 'E1182:')
144 delfunc g:Define
145
146 lines =<< trim END
147 let s:Object = {}
148 def Define()
149 def Object.Method()
150 enddef
151 enddef
152 defcompile
153 END
154 v9.CheckScriptFailure(lines, 'E1182:')
155 delfunc g:Define
156
157 lines =<< trim END
158 let g:Object = {}
159 def Define()
160 function g:Object.Method()
161 endfunction
162 enddef
163 defcompile
164 END
165 v9.CheckScriptFailure(lines, 'E1182:')
166 delfunc g:Define
Bram Moolenaar22f17a22021-06-21 20:48:58 +0200167enddef
168
Bram Moolenaar3f45d672023-02-27 22:06:51 +0000169def Test_break_in_skipped_block()
170 var lines =<< trim END
171 vim9script
172
173 def FixStackFrame(): string
174 for _ in [2]
175 var path = 'xxx'
176 if !!path
177 if false
178 break
179 else
180 return 'foo'
181 endif
182 endif
183 endfor
184 return 'xxx'
185 enddef
186
187 disas FixStackFrame
188
189 FixStackFrame()
190 END
191 v9.CheckScriptSuccess(lines)
192enddef
193
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200194def Test_autoload_name_mismatch()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100195 var dir = 'Xnamedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100196 mkdir(dir, 'pR')
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200197
198 var lines =<< trim END
199 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000200 export def NoFunction()
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200201 # comment
202 g:runtime = 'yes'
203 enddef
204 END
205 writefile(lines, dir .. '/script.vim')
206
207 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100208 exe 'set rtp=' .. getcwd() .. '/Xnamedir'
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200209 lines =<< trim END
210 call script#Function()
211 END
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000212 v9.CheckScriptFailure(lines, 'E117:', 1)
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200213
214 &rtp = save_rtp
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200215enddef
216
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200217def Test_autoload_names()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100218 var dir = 'Xandir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100219 mkdir(dir, 'pR')
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200220
221 var lines =<< trim END
222 func foobar#function()
223 return 'yes'
224 endfunc
225 let foobar#var = 'no'
226 END
227 writefile(lines, dir .. '/foobar.vim')
228
229 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100230 exe 'set rtp=' .. getcwd() .. '/Xandir'
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200231
232 lines =<< trim END
233 assert_equal('yes', foobar#function())
234 var Function = foobar#function
235 assert_equal('yes', Function())
236
237 assert_equal('no', foobar#var)
238 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000239 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200240
241 &rtp = save_rtp
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200242enddef
243
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200244def Test_autoload_error_in_script()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100245 var dir = 'Xaedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100246 mkdir(dir, 'pR')
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200247
248 var lines =<< trim END
249 func scripterror#function()
250 let g:called_function = 'yes'
251 endfunc
252 let 0 = 1
253 END
254 writefile(lines, dir .. '/scripterror.vim')
255
256 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100257 exe 'set rtp=' .. getcwd() .. '/Xaedir'
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200258
259 g:called_function = 'no'
260 # The error in the autoload script cannot be checked with assert_fails(), use
261 # CheckDefSuccess() instead of CheckDefFailure()
262 try
Bram Moolenaar62aec932022-01-29 21:45:34 +0000263 v9.CheckDefSuccess(['scripterror#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200264 catch
265 assert_match('E121: Undefined variable: 0', v:exception)
266 endtry
267 assert_equal('no', g:called_function)
268
269 lines =<< trim END
270 func scriptcaught#function()
271 let g:called_function = 'yes'
272 endfunc
273 try
274 let 0 = 1
275 catch
276 let g:caught = v:exception
277 endtry
278 END
279 writefile(lines, dir .. '/scriptcaught.vim')
280
281 g:called_function = 'no'
Bram Moolenaar62aec932022-01-29 21:45:34 +0000282 v9.CheckDefSuccess(['scriptcaught#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200283 assert_match('E121: Undefined variable: 0', g:caught)
284 assert_equal('yes', g:called_function)
285
286 &rtp = save_rtp
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200287enddef
288
Bram Moolenaar62aec932022-01-29 21:45:34 +0000289def s:CallRecursive(n: number): number
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100290 return CallRecursive(n + 1)
291enddef
292
Bram Moolenaar62aec932022-01-29 21:45:34 +0000293def s:CallMapRecursive(l: list<number>): number
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100294 return map(l, (_, v) => CallMapRecursive([v]))[0]
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100295enddef
296
297def Test_funcdepth_error()
298 set maxfuncdepth=10
299
300 var caught = false
301 try
302 CallRecursive(1)
303 catch /E132:/
304 caught = true
305 endtry
306 assert_true(caught)
307
308 caught = false
309 try
310 CallMapRecursive([1])
311 catch /E132:/
312 caught = true
313 endtry
314 assert_true(caught)
315
316 set maxfuncdepth&
317enddef
318
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100319def Test_endfunc_enddef()
320 var lines =<< trim END
321 def Test()
322 echo 'test'
323 endfunc
324 enddef
325 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000326 v9.CheckScriptFailure(lines, 'E1151:', 3)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100327
328 lines =<< trim END
329 def Test()
330 func Nested()
331 echo 'test'
332 enddef
333 enddef
334 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000335 v9.CheckScriptFailure(lines, 'E1152:', 4)
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100336
337 lines =<< trim END
338 def Ok()
339 echo 'hello'
340 enddef | echo 'there'
341 def Bad()
342 echo 'hello'
343 enddef there
344 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000345 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100346enddef
347
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100348def Test_missing_endfunc_enddef()
349 var lines =<< trim END
350 vim9script
351 def Test()
352 echo 'test'
353 endef
354 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000355 v9.CheckScriptFailure(lines, 'E1057:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100356
357 lines =<< trim END
358 vim9script
359 func Some()
360 echo 'test'
361 enfffunc
362 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000363 v9.CheckScriptFailure(lines, 'E126:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100364enddef
365
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100366def Test_white_space_before_paren()
367 var lines =<< trim END
368 vim9script
369 def Test ()
370 echo 'test'
371 enddef
372 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000373 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100374
375 lines =<< trim END
376 vim9script
377 func Test ()
378 echo 'test'
379 endfunc
380 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000381 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100382
383 lines =<< trim END
384 def Test ()
385 echo 'test'
386 enddef
387 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000388 v9.CheckScriptFailure(lines, 'E1068:', 1)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100389
390 lines =<< trim END
391 func Test ()
392 echo 'test'
393 endfunc
394 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000395 v9.CheckScriptSuccess(lines)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100396enddef
397
Bram Moolenaar832ea892021-01-08 21:55:26 +0100398def Test_enddef_dict_key()
399 var d = {
400 enddef: 'x',
401 endfunc: 'y',
402 }
403 assert_equal({enddef: 'x', endfunc: 'y'}, d)
404enddef
405
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200406def ReturnString(): string
407 return 'string'
408enddef
409
410def ReturnNumber(): number
411 return 123
412enddef
413
414let g:notNumber = 'string'
415
416def ReturnGlobal(): number
417 return g:notNumber
418enddef
419
420def Test_return_something()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000421 g:ReturnString()->assert_equal('string')
422 g:ReturnNumber()->assert_equal(123)
Bram Moolenaar848fadd2022-01-30 15:28:30 +0000423 assert_fails('g:ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaaref7aadb2022-01-18 18:46:07 +0000424
425 var lines =<< trim END
426 vim9script
427
428 def Msg()
429 echomsg 'in Msg()...'
430 enddef
431
432 def Func()
433 return Msg()
434 enddef
435 defcompile
436 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000437 v9.CheckScriptFailure(lines, 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200438enddef
439
Bram Moolenaare32e5162021-01-21 20:21:29 +0100440def Test_check_argument_type()
441 var lines =<< trim END
442 vim9script
443 def Val(a: number, b: number): number
444 return 0
445 enddef
446 def Func()
447 var x: any = true
448 Val(0, x)
449 enddef
450 disass Func
451 Func()
452 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000453 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
Bram Moolenaar56310d32022-12-27 17:25:05 +0000454
455 lines =<< trim END
456 vim9script
457
458 def Foobar(Fn: func(any, ?string): any)
459 enddef
460
461 Foobar((t) => 0)
462 END
463 v9.CheckScriptSuccess(lines)
Bram Moolenaare32e5162021-01-21 20:21:29 +0100464enddef
465
Bram Moolenaarefd88552020-06-18 20:50:10 +0200466def Test_missing_return()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000467 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200468 ' if g:cond',
469 ' echo "no return"',
470 ' else',
471 ' return 0',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100472 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200473 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000474 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200475 ' if g:cond',
476 ' return 1',
477 ' else',
478 ' echo "no return"',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100479 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200480 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000481 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200482 ' if g:cond',
483 ' return 1',
484 ' else',
485 ' return 2',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100486 ' endif',
487 ' return 3',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200488 'enddef'], 'E1095:')
489enddef
490
Bram Moolenaarcf2610c2023-05-14 19:59:59 +0100491def Test_not_missing_return()
492 var lines =<< trim END
493 def Funky(): number
494 if false
495 return 0
496 endif
497 throw 'Error'
498 enddef
499 defcompile
500 END
501 v9.CheckScriptSuccess(lines)
502enddef
503
Bram Moolenaar403dc312020-10-17 19:29:51 +0200504def Test_return_bool()
505 var lines =<< trim END
506 vim9script
507 def MenuFilter(id: number, key: string): bool
508 return popup_filter_menu(id, key)
509 enddef
510 def YesnoFilter(id: number, key: string): bool
511 return popup_filter_yesno(id, key)
512 enddef
513 defcompile
514 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000515 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200516enddef
517
mityu500c4442022-12-02 18:12:05 +0000518def Test_return_void_comment_follows()
519 var lines =<< trim END
520 vim9script
521 def ReturnCommentFollows(): void
522 return # Some comment
523 enddef
524 defcompile
525 END
526 v9.CheckScriptSuccess(lines)
527enddef
528
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200529let s:nothing = 0
530def ReturnNothing()
531 s:nothing = 1
532 if true
533 return
534 endif
535 s:nothing = 2
536enddef
537
538def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000539 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200540 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200541enddef
542
Bram Moolenaar648ea762021-01-15 19:04:32 +0100543def Test_return_invalid()
544 var lines =<< trim END
545 vim9script
546 def Func(): invalid
547 return xxx
548 enddef
549 defcompile
550 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000551 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100552
553 lines =<< trim END
554 vim9script
555 def Test(Fun: func(number): number): list<number>
556 return map([1, 2, 3], (_, i) => Fun(i))
557 enddef
558 defcompile
559 def Inc(nr: number): nr
560 return nr + 2
561 enddef
562 echo Test(Inc)
563 END
564 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000565 v9.CheckScriptFailure(lines, 'E1010:')
566 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100567enddef
568
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200569def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000570 # This used to fail but now the actual list type is checked, and since it has
571 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200572 var lines =<< trim END
573 vim9script
574 def Func(): list<string>
575 var l: list<any>
576 l->add('string')
577 return l
578 enddef
579 echo Func()
580 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000581 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000582
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200583 lines =<< trim END
584 vim9script
585 def Func(): list<string>
586 var l: list<any>
587 l += ['string']
588 return l
589 enddef
590 echo Func()
591 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000592 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200593enddef
594
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000595def Test_return_any_two_types()
596 var lines =<< trim END
597 vim9script
598
599 def G(Fn: func(string): any)
600 g:result = Fn("hello")
601 enddef
602
603 def F(a: number, b: string): any
604 echo b
605 if a > 0
606 return 1
607 else
608 return []
609 endif
610 enddef
611
612 G(function(F, [1]))
613 END
614 v9.CheckScriptSuccess(lines)
615 assert_equal(1, g:result)
616 unlet g:result
617enddef
618
Bram Moolenaar62aec932022-01-29 21:45:34 +0000619func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200620 let g:counter += 1
621endfunc
622
623def Test_call_ufunc_count()
624 g:counter = 1
625 Increment()
626 Increment()
627 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200628 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200629 g:counter->assert_equal(4)
630 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200631 unlet g:counter
632enddef
633
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000634def Test_call_ufunc_failure()
635 var lines =<< trim END
636 vim9script
637 def Tryit()
638 g:Global(1, 2, 3)
639 enddef
640
641 func g:Global(a, b, c)
642 echo a:a a:b a:c
643 endfunc
644
645 defcompile
646
647 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000648 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000649 endfunc
650 Tryit()
651 END
652 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
653 delfunc g:Global
654
655 lines =<< trim END
656 vim9script
657
658 g:Ref = function('len')
659 def Tryit()
660 g:Ref('x')
661 enddef
662
663 defcompile
664
665 g:Ref = function('add')
666 Tryit()
667 END
668 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
669 unlet g:Ref
670enddef
671
Bram Moolenaar62aec932022-01-29 21:45:34 +0000672def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200673 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200674 for s in rest
675 res ..= ',' .. s
676 endfor
677 return res
678enddef
679
680def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200681 MyVarargs('one')->assert_equal('one')
682 MyVarargs('one', 'two')->assert_equal('one,two')
683 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200684enddef
685
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200686def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000687 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200688enddef
689
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200690def MyDefaultArgs(name = 'string'): string
691 return name
692enddef
693
Bram Moolenaar62aec932022-01-29 21:45:34 +0000694def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200695 return second ? name : 'none'
696enddef
697
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200698
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200699def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000700 g:MyDefaultArgs()->assert_equal('string')
701 g:MyDefaultArgs(v:none)->assert_equal('string')
702 g:MyDefaultArgs('one')->assert_equal('one')
703 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200704
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200705 MyDefaultSecond('test')->assert_equal('test')
706 MyDefaultSecond('test', true)->assert_equal('test')
707 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200708
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200709 var lines =<< trim END
710 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
711 return name .. aa .. bb
712 enddef
713
714 MyDefaultThird('->')->assert_equal('->aabb')
715 MyDefaultThird('->', v:none)->assert_equal('->aabb')
716 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
717 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
718 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
719 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
720 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200721
722 def DefArg(mandatory: any, optional = mandatory): string
723 return mandatory .. optional
724 enddef
725 DefArg(1234)->assert_equal('12341234')
726 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200727 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000728 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200729
Bram Moolenaar62aec932022-01-29 21:45:34 +0000730 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100731 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000732 v9.CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100733 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000734 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100735
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200736 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100737 vim9script
738 def Func(a = b == 0 ? 1 : 2, b = 0)
739 enddef
740 defcompile
741 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000742 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000743
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000744 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000745 lines =<< trim END
746 vim9script
747 var a: any
748 def Func(arg: string = a)
749 echo arg
750 enddef
751 defcompile
752 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000753 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
754 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000755
756 # using global variable does not require type cast
757 lines =<< trim END
758 vim9script
759 def Func(arg: string = g:str)
760 echo arg
761 enddef
762 g:str = 'works'
763 Func()
764 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000765 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200766enddef
767
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100768def Test_using_vnone_default()
769 var lines =<< trim END
770 vim9script
771
772 def F(a: string = v:none)
773 if a isnot v:none
774 var b = a
775 endif
776 enddef
777 F()
778 END
779 v9.CheckScriptSuccess(lines)
780
Bram Moolenaar2ba51232023-05-15 16:22:38 +0100781 lines =<< trim END
782 vim9script
783
784 export def Floats(x: float, y = 2.0, z = 5.0)
785 g:result = printf("%.2f %.2f %.2f", x, y, z)
786 enddef
787 END
788 writefile(lines, 'Xlib.vim', 'D')
789
790 # test using a function reference in script-local variable
791 lines =<< trim END
792 vim9script
793
794 import './Xlib.vim'
795 const Floatfunc = Xlib.Floats
796 Floatfunc(1.0, v:none, 3.0)
797 END
798 v9.CheckScriptSuccess(lines)
799 assert_equal('1.00 2.00 3.00', g:result)
800 unlet g:result
801
802 # test calling the imported function
803 lines =<< trim END
804 vim9script
805
806 import './Xlib.vim'
807 Xlib.Floats(1.0, v:none, 3.0)
808 END
809 v9.CheckScriptSuccess(lines)
810 assert_equal('1.00 2.00 3.00', g:result)
811 unlet g:result
812
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100813 # TODO: this should give an error for using a missing argument
814 # lines =<< trim END
815 # vim9script
816
817 # def F(a: string = v:none)
818 # var b = a
819 # enddef
820 # F()
821 # END
822 # v9.CheckScriptFailure(lines, 'E99:')
823enddef
824
Bram Moolenaar47bba532023-01-20 18:49:46 +0000825def Test_convert_number_to_float()
826 var lines =<< trim END
827 vim9script
828 def Foo(a: float, b: float): float
829 return a + b
830 enddef
831
832 assert_equal(5.3, Foo(3.3, 2))
833 END
834 v9.CheckScriptSuccess(lines)
835enddef
836
Bram Moolenaar62aec932022-01-29 21:45:34 +0000837def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100838 a: number, #comment
839 b: bool, # comment
840 c: string) #comment
841 assert_equal(4, a)
842 assert_equal(true, b)
843 assert_equal('yes', c)
844enddef
845
846def Test_func_with_comments()
847 FuncWithComment(4, true, 'yes')
848
849 var lines =<< trim END
850 def Func(# comment
851 arg: string)
852 enddef
853 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000854 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100855
856 lines =<< trim END
857 def Func(
858 arg: string# comment
859 )
860 enddef
861 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000862 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100863
864 lines =<< trim END
865 def Func(
866 arg: string
867 )# comment
868 enddef
869 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000870 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100871enddef
872
Bram Moolenaar04b12692020-05-04 23:24:44 +0200873def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000874 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200875 return 'nested ' .. arg
876 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000877 NestedDef(':def')->assert_equal('nested :def')
878
879 func NestedFunc(arg)
880 return 'nested ' .. a:arg
881 endfunc
882 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200883
Bram Moolenaar62aec932022-01-29 21:45:34 +0000884 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
885 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200886
Bram Moolenaar62aec932022-01-29 21:45:34 +0000887 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
888 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200889
Bram Moolenaar54021752020-12-06 18:50:36 +0100890 var lines =<< trim END
891 def Outer()
892 def Inner()
893 # comment
894 enddef
895 def Inner()
896 enddef
897 enddef
898 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000899 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100900
901 lines =<< trim END
902 def Outer()
903 def Inner()
904 # comment
905 enddef
906 def! Inner()
907 enddef
908 enddef
909 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000910 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100911
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000912 lines =<< trim END
913 vim9script
914 def Outer()
915 def Inner()
916 g:result = 'ok'
917 enddef
918 Inner()
919 enddef
920 Outer()
921 Inner()
922 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000923 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000924 assert_equal('ok', g:result)
925 unlet g:result
926
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000927 lines =<< trim END
928 vim9script
929 def Outer()
930 def _Inner()
931 echo 'bad'
932 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000933 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000934 enddef
935 defcompile
936 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000937 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000938
939 lines =<< trim END
940 vim9script
941 def Outer()
942 def g:inner()
943 echo 'bad'
944 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000945 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000946 enddef
947 defcompile
948 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000949 v9.CheckScriptFailure(lines, 'E1267:')
950
951 lines =<< trim END
952 vim9script
953 def g:_Func()
954 echo 'bad'
955 enddef
956 END
957 v9.CheckScriptFailure(lines, 'E1267:')
958
959 lines =<< trim END
960 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000961 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +0000962 echo 'bad'
963 enddef
964 END
965 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000966
Bram Moolenaar54021752020-12-06 18:50:36 +0100967 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +0100968 lines =<< trim END
969 vim9script
970 var thecount = 0
971 if true
972 def Test(): number
973 def TheFunc(): number
974 thecount += 1
975 return thecount
976 enddef
977 return TheFunc()
978 enddef
979 endif
980 defcompile
981 assert_equal(1, Test())
982 assert_equal(2, Test())
983 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000984 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +0100985
986 # also works when "thecount" is inside the "if" block
987 lines =<< trim END
988 vim9script
989 if true
990 var thecount = 0
991 def Test(): number
992 def TheFunc(): number
993 thecount += 1
994 return thecount
995 enddef
996 return TheFunc()
997 enddef
998 endif
999 defcompile
1000 assert_equal(1, Test())
1001 assert_equal(2, Test())
1002 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001003 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001004
Bram Moolenaara915fa02022-03-23 11:29:15 +00001005 # nested function with recursive call
1006 lines =<< trim END
1007 vim9script
1008
1009 def MyFunc(): number
1010 def Fib(n: number): number
1011 if n < 2
1012 return 1
1013 endif
1014 return Fib(n - 2) + Fib(n - 1)
1015 enddef
1016
1017 return Fib(5)
1018 enddef
1019
1020 assert_equal(8, MyFunc())
1021 END
1022 v9.CheckScriptSuccess(lines)
1023
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001024 lines =<< trim END
1025 vim9script
1026 def Outer()
1027 def Inner()
1028 echo 'hello'
1029 enddef burp
1030 enddef
1031 defcompile
1032 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001033 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001034enddef
1035
Bram Moolenaar1889f492022-08-16 19:34:44 +01001036def Test_nested_function_fails()
1037 var lines =<< trim END
1038 def T()
1039 def Func(g: string):string
1040 enddef
1041 Func()
1042 enddef
1043 silent! defcompile
1044 END
1045 v9.CheckScriptFailure(lines, 'E1069:')
1046enddef
1047
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001048def Test_not_nested_function()
1049 echo printf('%d',
1050 function('len')('xxx'))
1051enddef
1052
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001053func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001054 call MyDefaultArgs()->assert_equal('string')
1055 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001056 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001057endfunc
1058
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001059def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001060 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001061 vim9script
1062 def Outer()
1063 def g:Inner(): string
1064 return 'inner'
1065 enddef
1066 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001067 defcompile
1068 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001069 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001070 delfunc g:Inner
1071 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001072 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001073 delfunc g:Inner
1074 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001075 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001076 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001077 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001078 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001079
1080 lines =<< trim END
1081 vim9script
1082 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001083 func g:Inner()
1084 return 'inner'
1085 endfunc
1086 enddef
1087 defcompile
1088 Outer()
1089 g:Inner()->assert_equal('inner')
1090 delfunc g:Inner
1091 Outer()
1092 g:Inner()->assert_equal('inner')
1093 delfunc g:Inner
1094 Outer()
1095 g:Inner()->assert_equal('inner')
1096 delfunc g:Inner
1097 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001098 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001099
1100 lines =<< trim END
1101 vim9script
1102 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001103 def g:Inner(): string
1104 return 'inner'
1105 enddef
1106 enddef
1107 defcompile
1108 Outer()
1109 Outer()
1110 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001111 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001112 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001113
1114 lines =<< trim END
1115 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001116 def Outer()
1117 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001118 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001119 enddef
1120 g:Inner()
1121 enddef
1122 Outer()
1123 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001124 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001125 delfunc g:Inner
1126
1127 lines =<< trim END
1128 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001129 def Func()
1130 echo 'script'
1131 enddef
1132 def Outer()
1133 def Func()
1134 echo 'inner'
1135 enddef
1136 enddef
1137 defcompile
1138 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001139 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001140
1141 lines =<< trim END
1142 vim9script
1143 def Func()
1144 echo 'script'
1145 enddef
1146 def Func()
1147 echo 'script'
1148 enddef
1149 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001150 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001151enddef
1152
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001153def DefListAll()
1154 def
1155enddef
1156
1157def DefListOne()
1158 def DefListOne
1159enddef
1160
1161def DefListMatches()
1162 def /DefList
1163enddef
1164
1165def Test_nested_def_list()
1166 var funcs = split(execute('call DefListAll()'), "\n")
1167 assert_true(len(funcs) > 10)
1168 assert_true(funcs->index('def DefListAll()') >= 0)
1169
1170 funcs = split(execute('call DefListOne()'), "\n")
1171 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1172
1173 funcs = split(execute('call DefListMatches()'), "\n")
1174 assert_true(len(funcs) >= 3)
1175 assert_true(funcs->index('def DefListAll()') >= 0)
1176 assert_true(funcs->index('def DefListOne()') >= 0)
1177 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001178
1179 var lines =<< trim END
1180 vim9script
1181 def Func()
1182 def +Func+
1183 enddef
1184 defcompile
1185 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001186 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001187enddef
1188
Bram Moolenaare08be092022-02-17 13:08:26 +00001189def Test_global_function_not_found()
1190 var lines =<< trim END
1191 g:Ref = 123
1192 call g:Ref()
1193 END
1194 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1195enddef
1196
Bram Moolenaar333894b2020-08-01 18:53:07 +02001197def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001198 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001199 vim9script
1200 def g:Func(): string
1201 return 'global'
1202 enddef
1203 def Func(): string
1204 return 'local'
1205 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001206 g:Func()->assert_equal('global')
1207 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001208 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001209 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001210 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001211
1212 lines =<< trim END
1213 vim9script
1214 def g:Funcy()
1215 echo 'funcy'
1216 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001217 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001218 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001219 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001220enddef
1221
Bram Moolenaar0f769812020-09-12 18:32:34 +02001222def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001223 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001224 vim9script
1225 def g:Gfunc(): string
1226 return 'global'
1227 enddef
1228 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001229 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001230 return Gfunc('testing')
1231 enddef
1232 g:Gfunc()->assert_equal('global')
1233 AnotherFunc()->assert_equal(7)
1234 delfunc g:Gfunc
1235 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001236 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001237
1238 lines =<< trim END
1239 vim9script
1240 def g:Func(): string
1241 return 'global'
1242 enddef
1243 def AnotherFunc()
1244 g:Func = function('len')
1245 enddef
1246 AnotherFunc()
1247 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001248 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001249 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001250
Bram Moolenaar62aec932022-01-29 21:45:34 +00001251 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001252 lines =<< trim END
1253 vim9script
1254 def g:Func(): string
1255 return 'global'
1256 enddef
1257 def AnotherFunc(): string
1258 return Func()
1259 enddef
1260 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001261 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001262 v9.CheckScriptFailure(lines, 'E117:')
1263 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001264
1265 lines =<< trim END
1266 vim9script
1267 def g:Func(): string
1268 return 'global'
1269 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001270 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001271 delfunc g:Func
1272 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001273 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001274
1275 # This does not shadow "i" which is visible only inside the for loop
1276 lines =<< trim END
1277 vim9script
1278
1279 def Foo(i: number)
1280 echo i
1281 enddef
1282
1283 for i in range(3)
1284 # Foo() is compiled here
1285 Foo(i)
1286 endfor
1287 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001288 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001289enddef
1290
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001291func TakesOneArg(arg)
1292 echo a:arg
1293endfunc
1294
1295def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001296 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1297 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1298 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1299 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001300
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001301 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001302 vim9script
1303 def Func(s: string)
1304 echo s
1305 enddef
1306 Func([])
1307 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001308 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001309
Bram Moolenaar9a015112021-12-31 14:06:45 +00001310 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001311 lines =<< trim END
1312 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001313 var name = 'piet'
1314 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001315 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001316 enddef
1317 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001318 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001319
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001320 # same, inside the same block
1321 lines =<< trim END
1322 vim9script
1323 if true
1324 var name = 'piet'
1325 def FuncOne(name: string)
1326 echo name
1327 enddef
1328 endif
1329 END
1330 v9.CheckScriptFailure(lines, 'E1168:')
1331
1332 # variable in other block is OK
1333 lines =<< trim END
1334 vim9script
1335 if true
1336 var name = 'piet'
1337 endif
1338 def FuncOne(name: string)
1339 echo name
1340 enddef
1341 END
1342 v9.CheckScriptSuccess(lines)
1343
Bram Moolenaardce24412022-02-08 20:35:30 +00001344 # with another variable in another block
1345 lines =<< trim END
1346 vim9script
1347 if true
1348 var name = 'piet'
1349 # define a function so that the variable isn't cleared
1350 def GetItem(): string
1351 return item
1352 enddef
1353 endif
1354 if true
1355 var name = 'peter'
1356 def FuncOne(name: string)
1357 echo name
1358 enddef
1359 endif
1360 END
1361 v9.CheckScriptFailure(lines, 'E1168:')
1362
1363 # only variable in another block is OK
1364 lines =<< trim END
1365 vim9script
1366 if true
1367 var name = 'piet'
1368 # define a function so that the variable isn't cleared
1369 def GetItem(): string
1370 return item
1371 enddef
1372 endif
1373 if true
1374 def FuncOne(name: string)
1375 echo name
1376 enddef
1377 endif
1378 END
1379 v9.CheckScriptSuccess(lines)
1380
Bram Moolenaar9a015112021-12-31 14:06:45 +00001381 # argument name declared later is only found when compiling
1382 lines =<< trim END
1383 vim9script
1384 def FuncOne(name: string)
1385 echo nr
1386 enddef
1387 var name = 'piet'
1388 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001389 v9.CheckScriptSuccess(lines)
1390 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001391
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001392 lines =<< trim END
1393 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001394 def FuncOne(nr: number)
1395 echo nr
1396 enddef
1397 def FuncTwo()
1398 FuncOne()
1399 enddef
1400 defcompile
1401 END
1402 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001403 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001404 try
1405 source Xscript
1406 catch
1407 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1408 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1409 didCatch = true
1410 endtry
1411 assert_true(didCatch)
1412
1413 lines =<< trim END
1414 vim9script
1415 def FuncOne(nr: number)
1416 echo nr
1417 enddef
1418 def FuncTwo()
1419 FuncOne(1, 2)
1420 enddef
1421 defcompile
1422 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001423 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001424 didCatch = false
1425 try
1426 source Xscript
1427 catch
1428 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1429 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1430 didCatch = true
1431 endtry
1432 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001433enddef
1434
Bram Moolenaar50824712020-12-20 21:10:17 +01001435def Test_call_funcref_wrong_args()
1436 var head =<< trim END
1437 vim9script
1438 def Func3(a1: string, a2: number, a3: list<number>)
1439 echo a1 .. a2 .. a3[0]
1440 enddef
1441 def Testme()
1442 var funcMap: dict<func> = {func: Func3}
1443 END
1444 var tail =<< trim END
1445 enddef
1446 Testme()
1447 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001448 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001449
Bram Moolenaar62aec932022-01-29 21:45:34 +00001450 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1451 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001452
1453 var lines =<< trim END
1454 vim9script
1455 var Ref: func(number): any
1456 Ref = (j) => !j
1457 echo Ref(false)
1458 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001459 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001460
1461 lines =<< trim END
1462 vim9script
1463 var Ref: func(number): any
1464 Ref = (j) => !j
1465 call Ref(false)
1466 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001467 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001468enddef
1469
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001470def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001471 var lines =<< trim END
1472 var Callback = (..._) => 'anything'
1473 assert_equal('anything', Callback())
1474 assert_equal('anything', Callback(1))
1475 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001476
1477 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001478 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001479 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001480
Bram Moolenaar62aec932022-01-29 21:45:34 +00001481 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001482 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001483
Bram Moolenaar2a389082021-04-09 20:24:31 +02001484 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001485 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001486 echo Ref(1, 'x')
1487 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001488 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001489
1490 lines =<< trim END
1491 var Ref: func(job, string, number)
1492 Ref = (x, y) => 0
1493 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001494 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001495
1496 lines =<< trim END
1497 var Ref: func(job, string)
1498 Ref = (x, y, z) => 0
1499 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001500 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001501
1502 lines =<< trim END
1503 var one = 1
1504 var l = [1, 2, 3]
1505 echo map(l, (one) => one)
1506 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001507 v9.CheckDefFailure(lines, 'E1167:')
1508 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001509
1510 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001511 var Ref: func(any, ?any): bool
1512 Ref = (_, y = 1) => false
1513 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001514 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001515
1516 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001517 var a = 0
1518 var b = (a == 0 ? 1 : 2)
1519 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001520 var txt = 'a'
1521 b = (txt =~ 'x' ? 1 : 2)
1522 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001523 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001524 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001525
1526 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001527 def ShadowLocal()
1528 var one = 1
1529 var l = [1, 2, 3]
1530 echo map(l, (one) => one)
1531 enddef
1532 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001533 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001534
1535 lines =<< trim END
1536 def Shadowarg(one: number)
1537 var l = [1, 2, 3]
1538 echo map(l, (one) => one)
1539 enddef
1540 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001541 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001542
1543 lines =<< trim END
1544 echo ((a) => a)('aa', 'bb')
1545 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001546 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001547
1548 lines =<< trim END
1549 echo 'aa'->((a) => a)('bb')
1550 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001551 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1552 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001553enddef
1554
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001555def Test_lambda_line_nr()
1556 var lines =<< trim END
1557 vim9script
1558 # comment
1559 # comment
1560 var id = timer_start(1'000, (_) => 0)
1561 var out = execute('verbose ' .. timer_info(id)[0].callback
1562 ->string()
1563 ->substitute("('\\|')", ' ', 'g'))
1564 assert_match('Last set from .* line 4', out)
1565 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001566 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001567enddef
1568
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001569def FilterWithCond(x: string, Cond: func(string): bool): bool
1570 return Cond(x)
1571enddef
1572
Bram Moolenaar0346b792021-01-31 22:18:29 +01001573def Test_lambda_return_type()
1574 var lines =<< trim END
1575 var Ref = (): => 123
1576 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001577 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001578
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001579 # no space before the return type
1580 lines =<< trim END
1581 var Ref = (x):number => x + 1
1582 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001583 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001584
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001585 # this works
1586 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001587 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001588 endfor
1589
1590 # this fails
1591 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001592 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001593 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001594 v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
Bram Moolenaara9931532021-06-12 15:58:16 +02001595
1596 lines =<< trim END
1597 var Lambda1 = (x) => {
1598 return x
1599 }
1600 assert_equal('asdf', Lambda1('asdf'))
1601 var Lambda2 = (x): string => {
1602 return x
1603 }
1604 assert_equal('foo', Lambda2('foo'))
1605 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001606 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001607
1608 lines =<< trim END
1609 var Lambda = (x): string => {
1610 return x
1611 }
1612 echo Lambda(['foo'])
1613 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001614 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001615enddef
1616
Bram Moolenaar709664c2020-12-12 14:33:41 +01001617def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001618 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001619 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001620 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001621enddef
1622
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001623def Test_lambda_invalid_block()
1624 var lines =<< trim END
1625 timer_start(0, (_) => { # echo
1626 echo 'yes'
1627 })
1628 END
1629 v9.CheckDefAndScriptSuccess(lines)
1630
1631 lines =<< trim END
1632 timer_start(0, (_) => { " echo
1633 echo 'yes'
1634 })
1635 END
1636 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1637
1638 lines =<< trim END
1639 timer_start(0, (_) => { | echo
1640 echo 'yes'
1641 })
1642 END
1643 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1644enddef
1645
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001646def Test_lambda_with_following_cmd()
1647 var lines =<< trim END
1648 set ts=2
1649 var Lambda = () => {
1650 set ts=4
1651 } | set ts=3
1652 assert_equal(3, &ts)
1653 Lambda()
1654 assert_equal(4, &ts)
1655 END
1656 v9.CheckDefAndScriptSuccess(lines)
1657 set ts=8
1658enddef
1659
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001660def Test_pass_legacy_lambda_to_def_func()
1661 var lines =<< trim END
1662 vim9script
1663 func Foo()
1664 eval s:Bar({x -> 0})
1665 endfunc
1666 def Bar(y: any)
1667 enddef
1668 Foo()
1669 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001670 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001671
1672 lines =<< trim END
1673 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001674 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001675 enddef
1676 legacy call g:TestFunc({-> 0})
1677 delfunc g:TestFunc
1678
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001679 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001680 enddef
1681 legacy call g:TestFunc({nr -> 0})
1682 delfunc g:TestFunc
1683 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001684 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001685enddef
1686
Bram Moolenaar844fb642021-10-23 13:32:30 +01001687def Test_lambda_in_reduce_line_break()
1688 # this was using freed memory
1689 var lines =<< trim END
1690 vim9script
1691 const result: dict<number> =
1692 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1693 ->reduce((acc, val) => {
1694 if has_key(acc, val)
1695 acc[val] += 1
1696 return acc
1697 else
1698 acc[val] = 1
1699 return acc
1700 endif
1701 }, {})
1702 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1703 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001704 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001705enddef
1706
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001707def Test_set_opfunc_to_lambda()
1708 var lines =<< trim END
1709 vim9script
1710 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1711 def CountSpaces(type = ''): string
1712 if type == ''
1713 &operatorfunc = (t) => CountSpaces(t)
1714 return 'g@'
1715 endif
1716 normal! '[V']y
1717 g:result = getreg('"')->count(' ')
1718 return ''
1719 enddef
1720 new
1721 'a b c d e'->setline(1)
1722 feedkeys("\<F4>", 'x')
1723 assert_equal(4, g:result)
1724 bwipe!
1725 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001726 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001727enddef
1728
Bram Moolenaaref082e12021-12-12 21:02:03 +00001729def Test_set_opfunc_to_global_function()
1730 var lines =<< trim END
1731 vim9script
1732 def g:CountSpaces(type = ''): string
1733 normal! '[V']y
1734 g:result = getreg('"')->count(' ')
1735 return ''
1736 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001737 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001738 &operatorfunc = g:CountSpaces
1739 new
1740 'a b c d e'->setline(1)
1741 feedkeys("g@_", 'x')
1742 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001743
1744 &operatorfunc = ''
1745 g:result = 0
1746 # global function works in :def function
1747 def Func()
1748 &operatorfunc = g:CountSpaces
1749 enddef
1750 Func()
1751 feedkeys("g@_", 'x')
1752 assert_equal(4, g:result)
1753
Bram Moolenaaref082e12021-12-12 21:02:03 +00001754 bwipe!
1755 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001756 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001757 &operatorfunc = ''
1758enddef
1759
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001760def Test_use_script_func_name_with_prefix()
1761 var lines =<< trim END
1762 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001763 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001764 return 'it'
1765 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001766 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001767 assert_equal('it', Fn())
1768 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001769 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001770enddef
1771
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001772def Test_lambda_type_allocated()
1773 # Check that unreferencing a partial using a lambda can use the variable type
1774 # after the lambda has been freed and does not leak memory.
1775 var lines =<< trim END
1776 vim9script
1777
1778 func MyomniFunc1(val, findstart, base)
1779 return a:findstart ? 0 : []
1780 endfunc
1781
1782 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1783 &omnifunc = Lambda
1784 Lambda = (a, b) => MyomniFunc1(20, a, b)
1785 &omnifunc = string(Lambda)
1786 Lambda = (a, b) => strlen(a)
1787 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001788 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001789enddef
1790
Bram Moolenaara7583c42022-05-07 21:14:05 +01001791def Test_define_lambda_in_execute()
1792 var lines =<< trim [CODE]
1793 vim9script
1794
1795 def BuildFuncMultiLine(): func
1796 var x =<< trim END
1797 g:SomeRandomFunc = (d: dict<any>) => {
1798 return d.k1 + d.k2
1799 }
1800 END
1801 execute(x)
1802 return g:SomeRandomFunc
1803 enddef
1804 var ResultPlus = BuildFuncMultiLine()
1805 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1806 [CODE]
1807 v9.CheckScriptSuccess(lines)
1808 unlet g:SomeRandomFunc
1809enddef
1810
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001811" Default arg and varargs
1812def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001813 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001814 for s in rest
1815 res ..= ',' .. s
1816 endfor
1817 return res
1818enddef
1819
1820def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001821 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1822 g:MyDefVarargs('one')->assert_equal('one,foo')
1823 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1824 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1825 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001826 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001827 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001828 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001829
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001830 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001831 vim9script
1832 def Func(...l: list<string>)
1833 echo l
1834 enddef
1835 Func('a', 'b', 'c')
1836 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001837 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001838
1839 lines =<< trim END
1840 vim9script
1841 def Func(...l: list<string>)
1842 echo l
1843 enddef
1844 Func()
1845 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001846 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001847
1848 lines =<< trim END
1849 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001850 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001851 echo l
1852 enddef
1853 Func(0)
1854 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001855 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001856
1857 lines =<< trim END
1858 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001859 def Func(...l: any)
1860 echo l
1861 enddef
1862 Func(0)
1863 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001864 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001865
1866 lines =<< trim END
1867 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001868 def Func(..._l: list<string>)
1869 echo _l
1870 enddef
1871 Func('a', 'b', 'c')
1872 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001873 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001874
1875 lines =<< trim END
1876 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001877 def Func(...l: list<string>)
1878 echo l
1879 enddef
1880 Func(1, 2, 3)
1881 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001882 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001883
1884 lines =<< trim END
1885 vim9script
1886 def Func(...l: list<string>)
1887 echo l
1888 enddef
1889 Func('a', 9)
1890 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001891 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001892
1893 lines =<< trim END
1894 vim9script
1895 def Func(...l: list<string>)
1896 echo l
1897 enddef
1898 Func(1, 'a')
1899 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001900 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001901
1902 lines =<< trim END
1903 vim9script
1904 def Func( # some comment
1905 ...l = []
1906 )
1907 echo l
1908 enddef
1909 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001910 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001911
1912 lines =<< trim END
1913 vim9script
1914 def DoIt()
1915 g:Later('')
1916 enddef
1917 defcompile
1918 def g:Later(...l: list<number>)
1919 enddef
1920 DoIt()
1921 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001922 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001923enddef
1924
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001925let s:value = ''
1926
1927def FuncOneDefArg(opt = 'text')
1928 s:value = opt
1929enddef
1930
1931def FuncTwoDefArg(nr = 123, opt = 'text'): string
1932 return nr .. opt
1933enddef
1934
1935def FuncVarargs(...arg: list<string>): string
1936 return join(arg, ',')
1937enddef
1938
1939def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001940 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001941 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001942 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001943 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001944 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001945 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001946
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001947 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001948 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001949 RefDef2Arg()->assert_equal('123text')
1950 RefDef2Arg(99)->assert_equal('99text')
1951 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001952
Bram Moolenaar62aec932022-01-29 21:45:34 +00001953 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
1954 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001955
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001956 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001957 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001958 RefVarargs()->assert_equal('')
1959 RefVarargs('one')->assert_equal('one')
1960 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001961
Bram Moolenaar62aec932022-01-29 21:45:34 +00001962 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
1963 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001964enddef
1965
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001966" Only varargs
1967def MyVarargsOnly(...args: list<string>): string
1968 return join(args, ',')
1969enddef
1970
1971def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001972 g:MyVarargsOnly()->assert_equal('')
1973 g:MyVarargsOnly('one')->assert_equal('one')
1974 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
1975 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
1976 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001977enddef
1978
Bram Moolenaar36818a92023-01-03 12:33:26 +00001979def Test_varargs_mismatch()
1980 var lines =<< trim END
1981 vim9script
1982
1983 def Map(Fn: func(...any): number): number
1984 return Fn('12')
1985 enddef
1986
1987 var res = Map((v) => str2nr(v))
1988 assert_equal(12, res)
1989 END
1990 v9.CheckScriptSuccess(lines)
1991enddef
1992
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001993def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00001994 var lines =<< trim END
1995 def Func(x: number)
1996 var x = 234
1997 enddef
1998 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001999 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002000
2001 lines =<< trim END
2002 def Func(Ref: number)
2003 def Ref()
2004 enddef
2005 enddef
2006 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002007 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002008enddef
2009
Bram Moolenaar62aec932022-01-29 21:45:34 +00002010def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002011 arg['key'] = 'value'
2012enddef
2013
Bram Moolenaar62aec932022-01-29 21:45:34 +00002014def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002015 arg[0] = 'value'
2016enddef
2017
2018def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002019 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002020 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002021 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002022 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002023 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002024 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002025 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002026
Bram Moolenaar62aec932022-01-29 21:45:34 +00002027 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002028 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002029enddef
2030
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002031" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002032def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002033 return firstline .. lastline
2034enddef
2035
2036def Test_argument_names()
2037 assert_equal('OK', WithReservedNames('O', 'K'))
2038enddef
2039
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002040def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002041 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002042 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002043enddef
2044
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002045func DefinedLater(arg)
2046 return a:arg
2047endfunc
2048
2049def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002050 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002051 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002052 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002053
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002054 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002055 vim9script
2056 def RetNumber(): number
2057 return 123
2058 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002059 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002060 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002061 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002062 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002063
2064 lines =<< trim END
2065 vim9script
2066 def RetNumber(): number
2067 return 123
2068 enddef
2069 def Bar(F: func: number): number
2070 return F()
2071 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002072 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002073 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002074 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002075 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002076
2077 lines =<< trim END
2078 vim9script
2079 def UseNumber(nr: number)
2080 echo nr
2081 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002082 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002083 Funcref(123)
2084 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002085 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002086
2087 lines =<< trim END
2088 vim9script
2089 def UseNumber(nr: number)
2090 echo nr
2091 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002092 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002093 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002094 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002095
2096 lines =<< trim END
2097 vim9script
2098 def EchoNr(nr = 34)
2099 g:echo = nr
2100 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002101 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002102 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002103 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002104 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002105 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002106 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002107 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002108
2109 lines =<< trim END
2110 vim9script
2111 def EchoList(...l: list<number>)
2112 g:echo = l
2113 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002114 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002115 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002116 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002117 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002118 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002119 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002120 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002121
2122 lines =<< trim END
2123 vim9script
2124 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2125 g:optarg = opt
2126 g:listarg = l
2127 return nr
2128 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002129 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002130 Funcref(10)->assert_equal(10)
2131 g:optarg->assert_equal(12)
2132 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002133
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002134 Funcref(11, 22)->assert_equal(11)
2135 g:optarg->assert_equal(22)
2136 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002137
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002138 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2139 g:optarg->assert_equal(18)
2140 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002141 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002142 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002143
2144 lines =<< trim END
2145 function s:func(num)
2146 return a:num * 2
2147 endfunction
2148
2149 def s:CallFuncref()
2150 var Funcref = function('s:func')
2151 Funcref(3)->assert_equal(6)
2152 enddef
2153 call s:CallFuncref()
2154 END
2155 v9.CheckScriptSuccess(lines)
2156
2157 lines =<< trim END
2158 function s:func(num)
2159 return a:num * 2
2160 endfunction
2161
2162 def s:CallFuncref()
2163 var Funcref = function(s:func)
2164 Funcref(3)->assert_equal(6)
2165 enddef
2166 call s:CallFuncref()
2167 END
2168 v9.CheckScriptSuccess(lines)
2169
2170 lines =<< trim END
2171 function s:func(num)
2172 return a:num * 2
2173 endfunction
2174
2175 def s:CallFuncref()
2176 var Funcref = s:func
2177 Funcref(3)->assert_equal(6)
2178 enddef
2179 call s:CallFuncref()
2180 END
2181 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002182enddef
2183
2184let SomeFunc = function('len')
2185let NotAFunc = 'text'
2186
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002187def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002188 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002189 var Ref1: func(bool): string
2190 var Ref2: func(bool): number
2191 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002192 Ref3 = g:cond ? Ref1 : Ref2
2193
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002194 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002195 var Refa1: func(bool): number
2196 var Refa2: func(bool, number): number
2197 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002198 Refa3 = g:cond ? Refa1 : Refa2
2199
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002200 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002201 var Refb1: func(bool, string): number
2202 var Refb2: func(string, number): number
2203 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002204 Refb3 = g:cond ? Refb1 : Refb2
2205enddef
2206
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002207def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002208 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002209enddef
2210
2211def DefinedEvenLater(arg: string): string
2212 return arg
2213enddef
2214
2215def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002216 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002217 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002218enddef
2219
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002220def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002221 var lines =<< trim END
2222 vim9script
2223 # Define an outer function
2224 def FirstFunction()
2225 # Define an inner function
2226 def SecondFunction()
2227 # the function has a body, a double free is detected.
2228 AAAAA
2229
2230 # enddef followed by | or } followed by # one or more characters
2231 enddef|BBBB
2232 enddef
2233
2234 # Compile all functions
2235 defcompile
2236 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002237 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002238enddef
2239
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002240def Test_nested_function_with_args_split()
2241 var lines =<< trim END
2242 vim9script
2243 def FirstFunction()
2244 def SecondFunction(
2245 )
2246 # had a double free if the right parenthesis of the nested function is
2247 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002248
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002249 enddef|BBBB
2250 enddef
2251 # Compile all functions
2252 defcompile
2253 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002254 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002255
2256 lines =<< trim END
2257 vim9script
2258 def FirstFunction()
2259 func SecondFunction()
2260 endfunc|BBBB
2261 enddef
2262 defcompile
2263 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002264 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002265enddef
2266
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002267def Test_error_in_function_args()
2268 var lines =<< trim END
2269 def FirstFunction()
2270 def SecondFunction(J =
2271 # Nois
2272 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002273
2274 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002275 enddef
2276 # Compile all functions
2277 defcompile
2278 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002279 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002280enddef
2281
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002282def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002283 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002284 'def Func(): number',
2285 'return "a"',
2286 'enddef',
2287 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002288 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002289 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002290 'def Func(): string',
2291 'return 1',
2292 'enddef',
2293 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002294 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002295 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002296 'def Func(): void',
2297 'return "a"',
2298 'enddef',
2299 'defcompile'],
2300 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002301 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002302 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002303 'def Func()',
2304 'return "a"',
2305 'enddef',
2306 'defcompile'],
2307 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002308 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002309
Bram Moolenaar62aec932022-01-29 21:45:34 +00002310 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002311 'def Func(): number',
2312 'return',
2313 'enddef',
2314 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002315 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002316
Bram Moolenaar62aec932022-01-29 21:45:34 +00002317 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002318 'def Func():number',
2319 'return 123',
2320 'enddef',
2321 'defcompile'], 'E1069:')
2322 delfunc! g:Func
2323
Bram Moolenaar62aec932022-01-29 21:45:34 +00002324 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002325 'def Func() :number',
2326 'return 123',
2327 'enddef',
2328 'defcompile'], 'E1059:')
2329 delfunc! g:Func
2330
Bram Moolenaar62aec932022-01-29 21:45:34 +00002331 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002332 'def Func() : number',
2333 'return 123',
2334 'enddef',
2335 'defcompile'], 'E1059:')
2336 delfunc! g:Func
2337
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002338 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002339 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002340 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002341 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002342 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002343 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002344
Bram Moolenaar62aec932022-01-29 21:45:34 +00002345 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002346 'vim9script',
2347 'def FuncB()',
2348 ' return 123',
2349 'enddef',
2350 'def FuncA()',
2351 ' FuncB()',
2352 'enddef',
2353 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002354enddef
2355
2356def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002357 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002358 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2359 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2360 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2361 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2362 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002363enddef
2364
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002365def Test_white_space_before_comma()
2366 var lines =<< trim END
2367 vim9script
2368 def Func(a: number , b: number)
2369 enddef
2370 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002371 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002372 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002373enddef
2374
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002375def Test_white_space_after_comma()
2376 var lines =<< trim END
2377 vim9script
2378 def Func(a: number,b: number)
2379 enddef
2380 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002381 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002382
2383 # OK in legacy function
2384 lines =<< trim END
2385 vim9script
2386 func Func(a,b)
2387 endfunc
2388 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002389 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002390enddef
2391
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002392def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002393 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002394 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002395 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002396 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002397 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002398 enddef
2399 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002400 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002401
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002402 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002403 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002404 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002405
Bram Moolenaar67979662020-06-20 22:50:47 +02002406 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002407 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002408 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002409
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002410 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002411 def ListFunc(arg: list<number>)
2412 listvar = arg
2413 enddef
2414 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002415 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002416
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002417 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002418 def DictFunc(arg: dict<number>)
2419 dictvar = arg
2420 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002421 {a: 1, b: 2}->DictFunc()
2422 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002423 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002424 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002425 enddef
2426 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002427 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002428
Bram Moolenaare0de1712020-12-02 17:36:54 +01002429 {a: 3, b: 4}->DictFunc()
2430 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002431
2432 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002433 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002434 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002435 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002436
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002437 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002438 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002439 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002440 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002441 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002442 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002443
2444 def UseString()
2445 'xyork'->MyFunc()
2446 enddef
2447 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002448 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002449
Bram Moolenaar10409562020-07-29 20:00:38 +02002450 def UseString2()
2451 "knife"->MyFunc()
2452 enddef
2453 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002454 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002455
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002456 # prepending a colon makes it a mark
2457 new
2458 setline(1, ['aaa', 'bbb', 'ccc'])
2459 normal! 3Gmt1G
2460 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002461 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002462 bwipe!
2463
Bram Moolenaare6b53242020-07-01 17:28:33 +02002464 MyFunc(
2465 'continued'
2466 )
2467 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002468 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002469 )
2470
2471 call MyFunc(
2472 'more'
2473 ..
2474 'lines'
2475 )
2476 assert_equal(
2477 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002478 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002479 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002480 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002481 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002482enddef
2483
2484def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002485 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002486 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002487 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002488 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002489 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002490 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002491 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002492 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002493 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002494enddef
2495
Bram Moolenaar65b95452020-07-19 14:03:09 +02002496def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002497 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002498 vim9script
2499 def MyFunc(arg: string)
2500 echo arg
2501 enddef
2502 MyFunc(1234)
2503 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002504 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002505enddef
2506
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002507def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002508 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002509 vim9script
2510 const var = ''
2511 def MyFunc(arg: string)
2512 var = 'asdf'
2513 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002514 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002515 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002516 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002517 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002518
2519 lines =<< trim END
2520 const g:Aconst = 77
2521 def Change()
2522 # comment
2523 g:Aconst = 99
2524 enddef
2525 call Change()
2526 unlet g:Aconst
2527 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002528 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002529enddef
2530
2531" Test that inside :function a Python function can be defined, :def is not
2532" recognized.
2533func Test_function_python()
2534 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002535 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002536 execute py "<< EOF"
2537def do_something():
2538 return 1
2539EOF
2540endfunc
2541
2542def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002543 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002544 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002545 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002546 echo 'hello'
2547 enddef
2548
2549 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002550 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002551 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002552 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002553
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002554 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002555 CallGoneSoon()
2556 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002557 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002558 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2559 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002560enddef
2561
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002562func Test_free_dict_while_in_funcstack()
2563 " relies on the sleep command
2564 CheckUnix
2565 call Run_Test_free_dict_while_in_funcstack()
2566endfunc
2567
2568def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002569 # this was freeing the TermRun() default argument dictionary while it was
2570 # still referenced in a funcstack_T
2571 var lines =<< trim END
2572 vim9script
2573
2574 &updatetime = 400
2575 def TermRun(_ = {})
2576 def Post()
2577 enddef
2578 def Exec()
2579 term_start('sleep 1', {
2580 term_finish: 'close',
2581 exit_cb: (_, _) => Post(),
2582 })
2583 enddef
2584 Exec()
2585 enddef
2586 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2587 timer_start(100, (_) => feedkeys("\<F4>"))
2588 timer_start(1000, (_) => feedkeys("\<F4>"))
2589 sleep 1500m
2590 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002591 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002592 nunmap <F4>
2593 set updatetime&
2594enddef
2595
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002596def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002597 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002598 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002599 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002600 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002601 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002602 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002603 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002604 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002605 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002606
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002607 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002608 g:Func1()->assert_equal('Func1')
2609 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002610
2611 delfunc! Func0
2612 delfunc! Func1
2613 delfunc! Func2
2614enddef
2615
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002616def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002617 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002618 vim9script
2619 func Func(arg)
2620 echo a:arg
2621 endfunc
2622 Func('text')
2623 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002624 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002625 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002626enddef
2627
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002628let s:funcResult = 0
2629
2630def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002631 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002632enddef
2633
2634def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002635 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002636 return 1234
2637enddef
2638
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002639def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002640 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002641 return 'text'
2642enddef
2643
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002644def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002645 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002646enddef
2647
2648def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002649 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002650 return arg
2651enddef
2652
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002653def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002654 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002655enddef
2656
Bram Moolenaar62aec932022-01-29 21:45:34 +00002657def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002658 return arg
2659enddef
2660
Bram Moolenaar62aec932022-01-29 21:45:34 +00002661def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002662 return arg
2663enddef
2664
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002665def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002666 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002667 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002668 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002669 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002670 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002671
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002672 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002673 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002674 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002675 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002676 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002677
Bram Moolenaar53900992020-08-22 19:02:02 +02002678 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002679 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002680 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002681 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002682
Bram Moolenaar53900992020-08-22 19:02:02 +02002683 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002684 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002685 Ref2()->assert_equal(1234)
2686 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002687
Bram Moolenaar53900992020-08-22 19:02:02 +02002688 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002689 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002690 Ref2(13)->assert_equal(13)
2691 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002692enddef
2693
Bram Moolenaar9978d472020-07-05 16:01:56 +02002694def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002695 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002696 for n in repeat([1], 3)
2697 res += n
2698 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002699 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002700
2701 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002702 for n in repeat(0z01, 3)->blob2list()
2703 res += n
2704 endfor
2705 res->assert_equal(3)
2706
2707 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002708 for n in add([1, 2], 3)
2709 res += n
2710 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002711 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002712enddef
2713
Bram Moolenaar846178a2020-07-05 17:04:13 +02002714def Test_argv_return_type()
2715 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002716 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002717 for name in argv()
2718 res ..= name
2719 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002720 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002721enddef
2722
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002723def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002724 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002725 RefVoid = g:FuncNoArgNoRet
2726 RefVoid = g:FuncOneArgNoRet
2727 v9.CheckDefFailure(['var RefVoid: func: void', 'RefVoid = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002728 v9.CheckDefFailure(['var RefVoid: func: void', 'RefVoid = g:FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002729
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002730 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002731 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002732 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002733 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2734 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002735
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002736 var RefAnyNoArgs: func: any = RefAny
2737
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002738 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002739 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002740 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002741 v9.CheckDefFailure(['var RefNr: func: number', 'RefNr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002742 v9.CheckDefFailure(['var RefNr: func: number', 'RefNr = g:FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002743
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002744 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002745 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002746 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002747 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2748 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002749enddef
2750
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002751def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002752 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002753
Bram Moolenaar62aec932022-01-29 21:45:34 +00002754 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2755 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002756 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002757 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2758 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
2759 v9.CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002760
Bram Moolenaar62aec932022-01-29 21:45:34 +00002761 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2762 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2763 v9.CheckDefFailure(['var RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:')
2764 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002765enddef
2766
Bram Moolenaar89228602020-04-05 22:14:54 +02002767def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002768 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002769 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002770 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002771
2772 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002773 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002774
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002775 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002776 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002777 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002778
Bram Moolenaar62aec932022-01-29 21:45:34 +00002779 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002780enddef
2781
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002782def Test_func_common_type()
2783 def FuncOne(n: number): number
2784 return n
2785 enddef
2786 def FuncTwo(s: string): number
2787 return len(s)
2788 enddef
2789 def FuncThree(n: number, s: string): number
2790 return n + len(s)
2791 enddef
2792 var list = [FuncOne, FuncTwo, FuncThree]
2793 assert_equal(8, list[0](8))
2794 assert_equal(4, list[1]('word'))
2795 assert_equal(7, list[2](3, 'word'))
2796enddef
2797
Bram Moolenaar62aec932022-01-29 21:45:34 +00002798def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002799 arg1: string,
2800 arg2 = 1234,
2801 ...rest: list<string>
2802 ): string
2803 return arg1 .. arg2 .. join(rest, '-')
2804enddef
2805
Bram Moolenaar2c330432020-04-13 14:41:35 +02002806def MultiLineComment(
2807 arg1: string, # comment
2808 arg2 = 1234, # comment
2809 ...rest: list<string> # comment
2810 ): string # comment
2811 return arg1 .. arg2 .. join(rest, '-')
2812enddef
2813
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002814def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002815 MultiLine('text')->assert_equal('text1234')
2816 MultiLine('text', 777)->assert_equal('text777')
2817 MultiLine('text', 777, 'one')->assert_equal('text777one')
2818 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002819enddef
2820
Bram Moolenaar23e03252020-04-12 22:22:31 +02002821func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002822 call s:MultiLine('text')->assert_equal('text1234')
2823 call s:MultiLine('text', 777)->assert_equal('text777')
2824 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2825 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002826endfunc
2827
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002828
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002829" When using CheckScriptFailure() for the below test, E1010 is generated instead
2830" of E1056.
2831func Test_E1056_1059()
2832 let caught_1056 = 0
2833 try
2834 def F():
2835 return 1
2836 enddef
2837 catch /E1056:/
2838 let caught_1056 = 1
2839 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002840 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002841
2842 let caught_1059 = 0
2843 try
2844 def F5(items : list)
2845 echo 'a'
2846 enddef
2847 catch /E1059:/
2848 let caught_1059 = 1
2849 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002850 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002851endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002852
Bram Moolenaar015f4262020-05-05 21:25:22 +02002853func DelMe()
2854 echo 'DelMe'
2855endfunc
2856
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002857def Test_error_reporting()
2858 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002859 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002860 " comment
2861 def Func()
2862 # comment
2863 # comment
2864 invalid
2865 enddef
2866 defcompile
2867 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002868 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002869 try
2870 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002871 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002872 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002873 v:exception->assert_match('Invalid command: invalid')
2874 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002875 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002876 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002877
2878 # comment lines after the start of the function
2879 lines =<< trim END
2880 " comment
2881 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002882 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002883 # comment
2884 # comment
2885 invalid
2886 enddef
2887 defcompile
2888 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002889 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002890 try
2891 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002892 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002893 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002894 v:exception->assert_match('Invalid command: invalid')
2895 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002896 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002897 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002898
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002899 lines =<< trim END
2900 vim9script
2901 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002902 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002903 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002904 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002905 enddef
2906 defcompile
2907 Func()
2908 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002909 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002910 try
2911 source Xdef
2912 assert_report('should have failed')
2913 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002914 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002915 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002916 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002917enddef
2918
Bram Moolenaar015f4262020-05-05 21:25:22 +02002919def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002920 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002921 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002922 'delfunc g:DelMe',
2923 'echo RefMe()'], 'E117:')
2924enddef
2925
2926def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002927 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002928 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002929 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002930enddef
2931
Bram Moolenaar62aec932022-01-29 21:45:34 +00002932def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002933 return Ref('more')
2934enddef
2935
2936def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002937 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002938 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002939enddef
2940
Bram Moolenaar62aec932022-01-29 21:45:34 +00002941def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002942 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002943 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002944enddef
2945
2946def Test_closure_ref_after_return()
2947 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002948 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002949 unlet g:Ref
2950enddef
2951
Bram Moolenaar62aec932022-01-29 21:45:34 +00002952def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002953 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002954 g:Extend = (s) => local->add(s)
2955 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002956enddef
2957
2958def Test_closure_two_refs()
2959 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002960 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002961 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002962 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002963 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002964 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002965
2966 unlet g:Extend
2967 unlet g:Read
2968enddef
2969
Bram Moolenaar62aec932022-01-29 21:45:34 +00002970def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002971 return join(Ref(), ' ')
2972enddef
2973
Bram Moolenaar62aec932022-01-29 21:45:34 +00002974def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002975 Ref(add)
2976enddef
2977
2978def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002979 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002980 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002981 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002982 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002983 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002984 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002985
2986 unlet g:Extend
2987 unlet g:Read
2988enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002989
Bram Moolenaar62aec932022-01-29 21:45:34 +00002990def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002991 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002992 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002993enddef
2994
Bram Moolenaar62aec932022-01-29 21:45:34 +00002995def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002996 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002997 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002998enddef
2999
3000def Test_closure_using_argument()
3001 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003002 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003003
3004 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003005 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003006
3007 unlet g:UseArg
3008 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003009
3010 var lines =<< trim END
3011 vim9script
3012 def Test(Fun: func(number): number): list<number>
3013 return map([1, 2, 3], (_, i) => Fun(i))
3014 enddef
3015 def Inc(nr: number): number
3016 return nr + 2
3017 enddef
3018 assert_equal([3, 4, 5], Test(Inc))
3019 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003020 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003021enddef
3022
Bram Moolenaar62aec932022-01-29 21:45:34 +00003023def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003024 var local = 'a'
3025
3026 def Append(arg: string)
3027 local ..= arg
3028 enddef
3029 g:Append = Append
3030
3031 def Get(): string
3032 return local
3033 enddef
3034 g:Get = Get
3035enddef
3036
3037def Test_closure_append_get()
3038 MakeGetAndAppendRefs()
3039 g:Get()->assert_equal('a')
3040 g:Append('-b')
3041 g:Get()->assert_equal('a-b')
3042 g:Append('-c')
3043 g:Get()->assert_equal('a-b-c')
3044
3045 unlet g:Append
3046 unlet g:Get
3047enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003048
Bram Moolenaar04b12692020-05-04 23:24:44 +02003049def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003050 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003051 def Closure(arg: string): string
3052 return local .. arg
3053 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003054 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003055enddef
3056
Bram Moolenaar62aec932022-01-29 21:45:34 +00003057func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003058 return a:Ref('some')
3059endfunc
3060
3061def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003062 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003063 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003064 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003065enddef
3066
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003067def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003068 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003069 vim9script
3070 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003071 var name = 0
3072 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003073 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003074 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003075 enddef
3076 Func()
3077 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003078 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003079enddef
3080
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003081def Test_nested_closure_used()
3082 var lines =<< trim END
3083 vim9script
3084 def Func()
3085 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003086 var Closure = () => x
3087 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003088 enddef
3089 Func()
3090 assert_equal('hello', g:Myclosure())
3091 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003092 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003093enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003094
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003095def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003096 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003097 vim9script
3098 def FuncA()
3099 FuncB(0)
3100 enddef
3101 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003102 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003103 enddef
3104 FuncA()
3105 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003106 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003107enddef
3108
Bram Moolenaar6de22962022-09-09 21:35:36 +01003109def Run_Test_closure_in_for_loop_fails()
3110 var lines =<< trim END
3111 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003112 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003113 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003114 # time should be enough for startup to finish
3115 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003116 echo n
3117 })
3118 endfor
3119 END
3120 writefile(lines, 'XTest_closure_fails', 'D')
3121
3122 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003123 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003124 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003125
3126 # clean up
3127 g:StopVimInTerminal(buf)
3128enddef
3129
3130func Test_closure_in_for_loop_fails()
3131 CheckScreendump
3132 call Run_Test_closure_in_for_loop_fails()
3133endfunc
3134
Bram Moolenaarf112f302020-12-20 17:47:52 +01003135def Test_global_closure()
3136 var lines =<< trim END
3137 vim9script
3138 def ReverseEveryNLines(n: number, line1: number, line2: number)
3139 var mods = 'sil keepj keepp lockm '
3140 var range = ':' .. line1 .. ',' .. line2
3141 def g:Offset(): number
3142 var offset = (line('.') - line1 + 1) % n
3143 return offset != 0 ? offset : n
3144 enddef
3145 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3146 enddef
3147
3148 new
3149 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3150 ReverseEveryNLines(3, 1, 9)
3151 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003152 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003153 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3154 assert_equal(expected, getline(1, 9))
3155 bwipe!
3156enddef
3157
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003158def Test_global_closure_called_directly()
3159 var lines =<< trim END
3160 vim9script
3161 def Outer()
3162 var x = 1
3163 def g:Inner()
3164 var y = x
3165 x += 1
3166 assert_equal(1, y)
3167 enddef
3168 g:Inner()
3169 assert_equal(2, x)
3170 enddef
3171 Outer()
3172 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003173 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003174 delfunc g:Inner
3175enddef
3176
Bram Moolenaar69c76172021-12-02 16:38:52 +00003177def Test_closure_called_from_legacy()
3178 var lines =<< trim END
3179 vim9script
3180 def Func()
3181 var outer = 'foo'
3182 var F = () => {
3183 outer = 'bar'
3184 }
3185 execute printf('call %s()', string(F))
3186 enddef
3187 Func()
3188 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003189 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003190enddef
3191
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003192def Test_failure_in_called_function()
3193 # this was using the frame index as the return value
3194 var lines =<< trim END
3195 vim9script
3196 au TerminalWinOpen * eval [][0]
3197 def PopupTerm(a: any)
3198 # make sure typvals on stack are string
3199 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3200 FireEvent()
3201 enddef
3202 def FireEvent()
3203 do TerminalWinOpen
3204 enddef
3205 # use try/catch to make eval fail
3206 try
3207 call PopupTerm(0)
3208 catch
3209 endtry
3210 au! TerminalWinOpen
3211 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003212 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003213enddef
3214
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003215def Test_nested_lambda()
3216 var lines =<< trim END
3217 vim9script
3218 def Func()
3219 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003220 var Lambda1 = () => 7
3221 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003222 var res = Lambda2()
3223 assert_equal([7, 4], res)
3224 enddef
3225 Func()
3226 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003227 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003228enddef
3229
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003230def Test_double_nested_lambda()
3231 var lines =<< trim END
3232 vim9script
3233 def F(head: string): func(string): func(string): string
3234 return (sep: string): func(string): string => ((tail: string): string => {
3235 return head .. sep .. tail
3236 })
3237 enddef
3238 assert_equal('hello-there', F('hello')('-')('there'))
3239 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003240 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003241enddef
3242
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003243def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003244 var lines =<< trim END
3245 vim9script
3246 def F(text: string): func(string): func(string): string
3247 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003248 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003249 })
3250 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003251 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003252 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003253 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003254
3255 lines =<< trim END
3256 vim9script
3257 echo range(4)->mapnew((_, v) => {
3258 return range(v) ->mapnew((_, s) => {
3259 return string(s)
3260 })
3261 })
3262 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003263 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003264
3265 lines =<< trim END
3266 vim9script
3267
Bram Moolenaara749a422022-02-12 19:52:25 +00003268 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003269 range(10)
3270 ->mapnew((_, _) => ({
3271 key: range(10)->mapnew((_, _) => {
3272 return ' '
3273 }),
3274 }))
3275 enddef
3276
3277 defcomp
3278 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003279 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003280enddef
3281
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003282def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003283 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003284 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003285enddef
3286
3287def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003288 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003289enddef
3290
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003291def Test_compiling_referenced_func_no_shadow()
3292 var lines =<< trim END
3293 vim9script
3294
3295 def InitializeReply(lspserver: dict<any>)
3296 enddef
3297
3298 def ProcessReply(lspserver: dict<any>)
3299 var lsp_reply_handlers: dict<func> =
3300 { 'initialize': InitializeReply }
3301 lsp_reply_handlers['initialize'](lspserver)
3302 enddef
3303
3304 call ProcessReply({})
3305 END
3306 v9.CheckScriptSuccess(lines)
3307enddef
3308
Bram Moolenaar62aec932022-01-29 21:45:34 +00003309def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003310 var path: string = empty(dir)
3311 \ ? 'empty'
3312 \ : 'full'
3313 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003314enddef
3315
3316def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003317 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003318enddef
3319
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003320def Test_script_var_in_lambda()
3321 var lines =<< trim END
3322 vim9script
3323 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003324 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003325 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003326 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003327enddef
3328
Bram Moolenaar62aec932022-01-29 21:45:34 +00003329def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003330 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003331 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003332 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003333 ->reverse()
3334 return x
3335enddef
3336
3337def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003338 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003339
3340 var lines =<< trim END
3341 vim9script
3342 var res = [{n: 1, m: 2, s: 'xxx'}]
3343 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3344 v.n,
3345 v.m,
3346 substitute(v.s, '.*', 'yyy', '')
3347 ))
3348 assert_equal(['1:2:yyy'], res)
3349 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003350 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003351enddef
3352
Bram Moolenaarb6571982021-01-08 22:24:19 +01003353def Test_list_lambda()
3354 timer_start(1000, (_) => 0)
3355 var body = execute(timer_info()[0].callback
3356 ->string()
3357 ->substitute("('", ' ', '')
3358 ->substitute("')", '', '')
3359 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003360 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003361enddef
3362
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003363def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003364 var lines =<< trim END
3365 vim9script
3366 var flist: list<func>
3367 for i in range(10)
3368 var inloop = i
3369 flist[i] = () => inloop
3370 endfor
3371 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003372 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003373
3374 lines =<< trim END
3375 vim9script
3376 if true
3377 var outloop = 5
3378 var flist: list<func>
3379 for i in range(10)
3380 flist[i] = () => outloop
3381 endfor
3382 endif
3383 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003384 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003385
3386 lines =<< trim END
3387 vim9script
3388 if true
3389 var outloop = 5
3390 endif
3391 var flist: list<func>
3392 for i in range(10)
3393 flist[i] = () => outloop
3394 endfor
3395 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003396 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003397
3398 lines =<< trim END
3399 vim9script
3400 for i in range(10)
3401 var Ref = () => 0
3402 endfor
3403 assert_equal(0, ((i) => 0)(0))
3404 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003405 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003406enddef
3407
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003408def Test_legacy_lambda()
3409 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003410
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003411 var lines =<< trim END
3412 echo {x -> 'hello ' .. x}('foo')
3413 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003414 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003415
3416 lines =<< trim END
3417 vim9script
3418 def Func()
3419 echo (() => 'no error')()
3420 enddef
3421 legacy call s:Func()
3422 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003423 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003424enddef
3425
Bram Moolenaarce024c32021-06-26 13:00:49 +02003426def Test_legacy()
3427 var lines =<< trim END
3428 vim9script
3429 func g:LegacyFunction()
3430 let g:legacyvar = 1
3431 endfunc
3432 def Testit()
3433 legacy call g:LegacyFunction()
3434 enddef
3435 Testit()
3436 assert_equal(1, g:legacyvar)
3437 unlet g:legacyvar
3438 delfunc g:LegacyFunction
3439 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003440 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003441enddef
3442
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003443def Test_legacy_errors()
3444 for cmd in ['if', 'elseif', 'else', 'endif',
3445 'for', 'endfor', 'continue', 'break',
3446 'while', 'endwhile',
3447 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003448 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003449 endfor
3450enddef
3451
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003452def Test_call_legacy_with_dict()
3453 var lines =<< trim END
3454 vim9script
3455 func Legacy() dict
3456 let g:result = self.value
3457 endfunc
3458 def TestDirect()
3459 var d = {value: 'yes', func: Legacy}
3460 d.func()
3461 enddef
3462 TestDirect()
3463 assert_equal('yes', g:result)
3464 unlet g:result
3465
3466 def TestIndirect()
3467 var d = {value: 'foo', func: Legacy}
3468 var Fi = d.func
3469 Fi()
3470 enddef
3471 TestIndirect()
3472 assert_equal('foo', g:result)
3473 unlet g:result
3474
3475 var d = {value: 'bar', func: Legacy}
3476 d.func()
3477 assert_equal('bar', g:result)
3478 unlet g:result
3479 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003480 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003481enddef
3482
Bram Moolenaar62aec932022-01-29 21:45:34 +00003483def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003484 # closure nested inside another closure using argument
3485 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3486 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3487enddef
3488
3489def Test_nested_closure_using_argument()
3490 assert_equal(['x', 'x2'], DoFilterThis('x'))
3491enddef
3492
Bram Moolenaar0186e582021-01-10 18:33:11 +01003493def Test_triple_nested_closure()
3494 var what = 'x'
3495 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3496 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3497 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3498enddef
3499
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003500func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003501 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003502 call Run_Test_silent_echo()
3503endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003504
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003505def Run_Test_silent_echo()
3506 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003507 vim9script
3508 def EchoNothing()
3509 silent echo ''
3510 enddef
3511 defcompile
3512 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003513 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003514
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003515 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003516 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003517 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003518 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003519
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003520 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003521 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003522enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003523
Bram Moolenaar171fb922020-10-28 16:54:47 +01003524def SilentlyError()
3525 execute('silent! invalid')
3526 g:did_it = 'yes'
3527enddef
3528
Bram Moolenaar62aec932022-01-29 21:45:34 +00003529func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003530 silent! invalid
3531endfunc
3532
3533def SilentlyUserError()
3534 UserError()
3535 g:did_it = 'yes'
3536enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003537
3538" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003539func Test_ignore_silent_error()
3540 let g:did_it = 'no'
3541 call SilentlyError()
3542 call assert_equal('yes', g:did_it)
3543
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003544 let g:did_it = 'no'
3545 call SilentlyUserError()
3546 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003547
3548 unlet g:did_it
3549endfunc
3550
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003551def Test_ignore_silent_error_in_filter()
3552 var lines =<< trim END
3553 vim9script
3554 def Filter(winid: number, key: string): bool
3555 if key == 'o'
3556 silent! eval [][0]
3557 return true
3558 endif
3559 return popup_filter_menu(winid, key)
3560 enddef
3561
Bram Moolenaare0de1712020-12-02 17:36:54 +01003562 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003563 feedkeys("o\r", 'xnt')
3564 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003565 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003566enddef
3567
Bram Moolenaar62aec932022-01-29 21:45:34 +00003568def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003569 if n < 2
3570 return n
3571 else
3572 return Fibonacci(n - 1) + Fibonacci(n - 2)
3573 endif
3574enddef
3575
Bram Moolenaar985116a2020-07-12 17:31:09 +02003576def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003577 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003578enddef
3579
Bram Moolenaar62aec932022-01-29 21:45:34 +00003580def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003581 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003582 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003583 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003584 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003585 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003586enddef
3587
3588def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003589 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003590 writefile(['111'], 'XclosureDir/file1')
3591 writefile(['222'], 'XclosureDir/file2')
3592 writefile(['333'], 'XclosureDir/tdir/file3')
3593
Bram Moolenaare0de1712020-12-02 17:36:54 +01003594 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003595enddef
3596
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003597def Test_invalid_function_name()
3598 var lines =<< trim END
3599 vim9script
3600 def s: list<string>
3601 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003602 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003603
3604 lines =<< trim END
3605 vim9script
3606 def g: list<string>
3607 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003608 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003609
3610 lines =<< trim END
3611 vim9script
3612 def <SID>: list<string>
3613 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003614 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003615
3616 lines =<< trim END
3617 vim9script
3618 def F list<string>
3619 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003620 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003621enddef
3622
Bram Moolenaara90afb92020-07-15 22:38:56 +02003623def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003624 var lines =<< trim END
3625 var Xsetlist: func
3626 Xsetlist = function('setloclist', [0])
3627 Xsetlist([], ' ', {title: 'test'})
3628 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003629
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003630 Xsetlist = function('setloclist', [0, [], ' '])
3631 Xsetlist({title: 'test'})
3632 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003633
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003634 Xsetlist = function('setqflist')
3635 Xsetlist([], ' ', {title: 'test'})
3636 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003637
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003638 Xsetlist = function('setqflist', [[], ' '])
3639 Xsetlist({title: 'test'})
3640 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003641
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003642 var Len: func: number = function('len', ['word'])
3643 assert_equal(4, Len())
3644
3645 var RepeatFunc = function('repeat', ['o'])
3646 assert_equal('ooooo', RepeatFunc(5))
3647 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003648 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003649
3650 lines =<< trim END
3651 vim9script
3652 def Foo(Parser: any)
3653 enddef
3654 var Expr: func(dict<any>): dict<any>
3655 const Call = Foo(Expr)
3656 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003657 v9.CheckScriptFailure(lines, 'E1031:')
Bram Moolenaara90afb92020-07-15 22:38:56 +02003658enddef
3659
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003660def Test_partial_double_nested()
3661 var idx = 123
3662 var Get = () => idx
3663 var Ref = function(Get, [])
3664 var RefRef = function(Ref, [])
3665 assert_equal(123, RefRef())
3666enddef
3667
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003668def Test_partial_null_function()
3669 var lines =<< trim END
3670 var d: dict<func> = {f: null_function}
3671 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003672 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003673 END
3674 v9.CheckDefAndScriptSuccess(lines)
3675enddef
3676
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003677def Test_cmd_modifier()
3678 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003679 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003680enddef
3681
3682def Test_restore_modifiers()
3683 # check that when compiling a :def function command modifiers are not messed
3684 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003685 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003686 vim9script
3687 set eventignore=
3688 autocmd QuickFixCmdPost * copen
3689 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003690 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003691 enddef
3692 func Func()
3693 noautocmd call s:AutocmdsDisabled()
3694 let g:ei_after = &eventignore
3695 endfunc
3696 Func()
3697 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003698 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003699 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003700enddef
3701
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003702def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003703 eval 1 + 2
3704 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003705 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003706 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003707enddef
3708
3709def StackBot()
3710 # throw an error
3711 eval [][0]
3712enddef
3713
3714def Test_callstack_def()
3715 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003716 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003717 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003718 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003719 endtry
3720enddef
3721
Bram Moolenaare8211a32020-10-09 22:04:29 +02003722" Re-using spot for variable used in block
3723def Test_block_scoped_var()
3724 var lines =<< trim END
3725 vim9script
3726 def Func()
3727 var x = ['a', 'b', 'c']
3728 if 1
3729 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003730 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003731 endif
3732 var z = x
3733 assert_equal(['x', 'x', 'x'], z)
3734 enddef
3735 Func()
3736 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003737 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003738enddef
3739
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003740def Test_reset_did_emsg()
3741 var lines =<< trim END
3742 @s = 'blah'
3743 au BufWinLeave * #
3744 def Func()
3745 var winid = popup_create('popup', {})
3746 exe '*s'
3747 popup_close(winid)
3748 enddef
3749 Func()
3750 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003751 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003752 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003753enddef
3754
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003755def Test_did_emsg_reset()
3756 # executing an autocommand resets did_emsg, this should not result in a
3757 # builtin function considered failing
3758 var lines =<< trim END
3759 vim9script
3760 au BufWinLeave * #
3761 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003762 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003763 eval [][0]
3764 enddef
3765 nno <F3> <cmd>call <sid>Func()<cr>
3766 feedkeys("\<F3>\e", 'xt')
3767 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003768 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003769 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003770
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003771 nunmap <F3>
3772 au! BufWinLeave
3773enddef
3774
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003775def Test_abort_with_silent_call()
3776 var lines =<< trim END
3777 vim9script
3778 g:result = 'none'
3779 def Func()
3780 g:result += 3
3781 g:result = 'yes'
3782 enddef
3783 # error is silenced, but function aborts on error
3784 silent! Func()
3785 assert_equal('none', g:result)
3786 unlet g:result
3787 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003788 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003789enddef
3790
Bram Moolenaarf665e972020-12-05 19:17:16 +01003791def Test_continues_with_silent_error()
3792 var lines =<< trim END
3793 vim9script
3794 g:result = 'none'
3795 def Func()
3796 silent! g:result += 3
3797 g:result = 'yes'
3798 enddef
3799 # error is silenced, function does not abort
3800 Func()
3801 assert_equal('yes', g:result)
3802 unlet g:result
3803 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003804 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003805enddef
3806
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003807def Test_abort_even_with_silent()
3808 var lines =<< trim END
3809 vim9script
3810 g:result = 'none'
3811 def Func()
3812 eval {-> ''}() .. '' .. {}['X']
3813 g:result = 'yes'
3814 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003815 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003816 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003817 unlet g:result
3818 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003819 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003820enddef
3821
Bram Moolenaarf665e972020-12-05 19:17:16 +01003822def Test_cmdmod_silent_restored()
3823 var lines =<< trim END
3824 vim9script
3825 def Func()
3826 g:result = 'none'
3827 silent! g:result += 3
3828 g:result = 'none'
3829 g:result += 3
3830 enddef
3831 Func()
3832 END
3833 # can't use CheckScriptFailure, it ignores the :silent!
3834 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003835 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003836 var caught = 'no'
3837 try
3838 exe 'source ' .. fname
3839 catch /E1030:/
3840 caught = 'yes'
3841 assert_match('Func, line 4', v:throwpoint)
3842 endtry
3843 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003844enddef
3845
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003846def Test_cmdmod_silent_nested()
3847 var lines =<< trim END
3848 vim9script
3849 var result = ''
3850
3851 def Error()
3852 result ..= 'Eb'
3853 eval [][0]
3854 result ..= 'Ea'
3855 enddef
3856
3857 def Crash()
3858 result ..= 'Cb'
3859 sil! Error()
3860 result ..= 'Ca'
3861 enddef
3862
3863 Crash()
3864 assert_equal('CbEbEaCa', result)
3865 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003866 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003867enddef
3868
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003869def Test_dict_member_with_silent()
3870 var lines =<< trim END
3871 vim9script
3872 g:result = 'none'
3873 var d: dict<any>
3874 def Func()
3875 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003876 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003877 catch
3878 endtry
3879 enddef
3880 silent! Func()
3881 assert_equal('0', g:result)
3882 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003883 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003884 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003885enddef
3886
Bram Moolenaarf9041332021-01-21 19:41:16 +01003887def Test_skip_cmds_with_silent()
3888 var lines =<< trim END
3889 vim9script
3890
3891 def Func(b: bool)
3892 Crash()
3893 enddef
3894
3895 def Crash()
3896 sil! :/not found/d _
3897 sil! :/not found/put _
3898 enddef
3899
3900 Func(true)
3901 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003902 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003903enddef
3904
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003905def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003906 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003907 def g:Opfunc(_: any): string
3908 setline(1, 'ASDF')
3909 return ''
3910 enddef
3911 new
3912 setline(1, 'asdf')
3913 feedkeys("\<F3>$", 'x')
3914 assert_equal('ASDF', getline(1))
3915
3916 bwipe!
3917 nunmap <F3>
3918enddef
3919
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003920func Test_opfunc_error()
3921 CheckScreendump
3922 call Run_Test_opfunc_error()
3923endfunc
3924
3925def Run_Test_opfunc_error()
3926 # test that the error from Opfunc() is displayed right away
3927 var lines =<< trim END
3928 vim9script
3929
3930 def Opfunc(type: string)
3931 try
3932 eval [][0]
3933 catch /nothing/ # error not caught
3934 endtry
3935 enddef
3936 &operatorfunc = Opfunc
3937 nnoremap <expr> l <SID>L()
3938 def L(): string
3939 return 'l'
3940 enddef
3941 'x'->repeat(10)->setline(1)
3942 feedkeys('g@l', 'n')
3943 feedkeys('llll')
3944 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003945 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003946
Bram Moolenaar62aec932022-01-29 21:45:34 +00003947 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3948 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003949 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003950
3951 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003952 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003953enddef
3954
Bram Moolenaar077a4232020-12-22 18:33:27 +01003955" this was crashing on exit
3956def Test_nested_lambda_in_closure()
3957 var lines =<< trim END
3958 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003959 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003960 def Outer()
3961 def g:Inner()
3962 echo map([1, 2, 3], {_, v -> v + 1})
3963 enddef
3964 g:Inner()
3965 enddef
3966 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003967 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003968 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003969 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003970 return
3971 endif
3972 assert_equal(['Done'], readfile('XnestedDone'))
3973 delete('XnestedDone')
3974enddef
3975
Bram Moolenaar92368aa2022-02-07 17:50:39 +00003976def Test_nested_closure_funcref()
3977 var lines =<< trim END
3978 vim9script
3979 def Func()
3980 var n: number
3981 def Nested()
3982 ++n
3983 enddef
3984 Nested()
3985 g:result_one = n
3986 var Ref = function(Nested)
3987 Ref()
3988 g:result_two = n
3989 enddef
3990 Func()
3991 END
3992 v9.CheckScriptSuccess(lines)
3993 assert_equal(1, g:result_one)
3994 assert_equal(2, g:result_two)
3995 unlet g:result_one g:result_two
3996enddef
3997
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00003998def Test_nested_closure_in_dict()
3999 var lines =<< trim END
4000 vim9script
4001 def Func(): dict<any>
4002 var n: number
4003 def Inc(): number
4004 ++n
4005 return n
4006 enddef
4007 return {inc: function(Inc)}
4008 enddef
4009 disas Func
4010 var d = Func()
4011 assert_equal(1, d.inc())
4012 assert_equal(2, d.inc())
4013 END
4014 v9.CheckScriptSuccess(lines)
4015enddef
4016
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004017def Test_script_local_other_script()
4018 var lines =<< trim END
4019 function LegacyJob()
4020 let FuncRef = function('s:close_cb')
4021 endfunction
4022 function s:close_cb(...)
4023 endfunction
4024 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004025 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004026 source Xlegacy.vim
4027 g:LegacyJob()
4028 g:LegacyJob()
4029 g:LegacyJob()
4030
4031 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004032enddef
4033
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004034def Test_check_func_arg_types()
4035 var lines =<< trim END
4036 vim9script
4037 def F1(x: string): string
4038 return x
4039 enddef
4040
4041 def F2(x: number): number
4042 return x + 1
4043 enddef
4044
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004045 def G(Fg: func): dict<func>
4046 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004047 enddef
4048
4049 def H(d: dict<func>): string
4050 return d.f('a')
4051 enddef
4052 END
4053
Bram Moolenaar62aec932022-01-29 21:45:34 +00004054 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4055 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004056
4057 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004058enddef
4059
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004060def Test_call_func_with_null()
4061 var lines =<< trim END
4062 def Fstring(v: string)
4063 assert_equal(null_string, v)
4064 enddef
4065 Fstring(null_string)
4066 def Fblob(v: blob)
4067 assert_equal(null_blob, v)
4068 enddef
4069 Fblob(null_blob)
4070 def Flist(v: list<number>)
4071 assert_equal(null_list, v)
4072 enddef
4073 Flist(null_list)
4074 def Fdict(v: dict<number>)
4075 assert_equal(null_dict, v)
4076 enddef
4077 Fdict(null_dict)
4078 def Ffunc(Fv: func(number): number)
4079 assert_equal(null_function, Fv)
4080 enddef
4081 Ffunc(null_function)
4082 if has('channel')
4083 def Fchannel(v: channel)
4084 assert_equal(null_channel, v)
4085 enddef
4086 Fchannel(null_channel)
4087 def Fjob(v: job)
4088 assert_equal(null_job, v)
4089 enddef
4090 Fjob(null_job)
4091 endif
4092 END
4093 v9.CheckDefAndScriptSuccess(lines)
4094enddef
4095
4096def Test_null_default_argument()
4097 var lines =<< trim END
4098 def Fstring(v: string = null_string)
4099 assert_equal(null_string, v)
4100 enddef
4101 Fstring()
4102 def Fblob(v: blob = null_blob)
4103 assert_equal(null_blob, v)
4104 enddef
4105 Fblob()
4106 def Flist(v: list<number> = null_list)
4107 assert_equal(null_list, v)
4108 enddef
4109 Flist()
4110 def Fdict(v: dict<number> = null_dict)
4111 assert_equal(null_dict, v)
4112 enddef
4113 Fdict()
4114 def Ffunc(Fv: func(number): number = null_function)
4115 assert_equal(null_function, Fv)
4116 enddef
4117 Ffunc()
4118 if has('channel')
4119 def Fchannel(v: channel = null_channel)
4120 assert_equal(null_channel, v)
4121 enddef
4122 Fchannel()
4123 def Fjob(v: job = null_job)
4124 assert_equal(null_job, v)
4125 enddef
4126 Fjob()
4127 endif
4128 END
4129 v9.CheckDefAndScriptSuccess(lines)
4130enddef
4131
4132def Test_null_return()
4133 var lines =<< trim END
4134 def Fstring(): string
4135 return null_string
4136 enddef
4137 assert_equal(null_string, Fstring())
4138 def Fblob(): blob
4139 return null_blob
4140 enddef
4141 assert_equal(null_blob, Fblob())
4142 def Flist(): list<number>
4143 return null_list
4144 enddef
4145 assert_equal(null_list, Flist())
4146 def Fdict(): dict<number>
4147 return null_dict
4148 enddef
4149 assert_equal(null_dict, Fdict())
4150 def Ffunc(): func(number): number
4151 return null_function
4152 enddef
4153 assert_equal(null_function, Ffunc())
4154 if has('channel')
4155 def Fchannel(): channel
4156 return null_channel
4157 enddef
4158 assert_equal(null_channel, Fchannel())
4159 def Fjob(): job
4160 return null_job
4161 enddef
4162 assert_equal(null_job, Fjob())
4163 endif
4164 END
4165 v9.CheckDefAndScriptSuccess(lines)
4166enddef
4167
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004168def Test_list_any_type_checked()
4169 var lines =<< trim END
4170 vim9script
4171 def Foo()
4172 --decl--
4173 Bar(l)
4174 enddef
4175 def Bar(ll: list<dict<any>>)
4176 enddef
4177 Foo()
4178 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004179 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004180 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004181 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004182 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004183 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004184
4185 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004186 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004187enddef
4188
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004189def Test_compile_error()
4190 var lines =<< trim END
4191 def g:Broken()
4192 echo 'a' + {}
4193 enddef
4194 call g:Broken()
4195 END
4196 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004197 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004198
4199 # Second call won't try compiling again
4200 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004201 delfunc g:Broken
4202
4203 # No error when compiling with :silent!
4204 lines =<< trim END
4205 def g:Broken()
4206 echo 'a' + []
4207 enddef
4208 silent! defcompile
4209 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004210 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004211
4212 # Calling the function won't try compiling again
4213 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4214 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004215enddef
4216
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004217def Test_ignored_argument()
4218 var lines =<< trim END
4219 vim9script
4220 def Ignore(_, _): string
4221 return 'yes'
4222 enddef
4223 assert_equal('yes', Ignore(1, 2))
4224
4225 func Ok(_)
4226 return a:_
4227 endfunc
4228 assert_equal('ok', Ok('ok'))
4229
4230 func Oktoo()
4231 let _ = 'too'
4232 return _
4233 endfunc
4234 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004235
4236 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004237 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004238 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004239
4240 lines =<< trim END
4241 def Ignore(_: string): string
4242 return _
4243 enddef
4244 defcompile
4245 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004246 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004247
4248 lines =<< trim END
4249 var _ = 1
4250 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004251 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004252
4253 lines =<< trim END
4254 var x = _
4255 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004256 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004257enddef
4258
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004259def Test_too_many_arguments()
4260 var lines =<< trim END
4261 echo [0, 1, 2]->map(() => 123)
4262 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004263 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004264
4265 lines =<< trim END
4266 echo [0, 1, 2]->map((_) => 123)
4267 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004268 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004269
4270 lines =<< trim END
4271 vim9script
4272 def OneArgument(arg: string)
4273 echo arg
4274 enddef
4275 var Ref = OneArgument
4276 Ref('a', 'b')
4277 END
4278 v9.CheckScriptFailure(lines, 'E118:')
4279enddef
4280
4281def Test_funcref_with_base()
4282 var lines =<< trim END
4283 vim9script
4284 def TwoArguments(str: string, nr: number)
4285 echo str nr
4286 enddef
4287 var Ref = TwoArguments
4288 Ref('a', 12)
4289 'b'->Ref(34)
4290 END
4291 v9.CheckScriptSuccess(lines)
4292
4293 lines =<< trim END
4294 vim9script
4295 def TwoArguments(str: string, nr: number)
4296 echo str nr
4297 enddef
4298 var Ref = TwoArguments
4299 'a'->Ref('b')
4300 END
4301 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4302
4303 lines =<< trim END
4304 vim9script
4305 def TwoArguments(str: string, nr: number)
4306 echo str nr
4307 enddef
4308 var Ref = TwoArguments
4309 123->Ref(456)
4310 END
4311 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4312
4313 lines =<< trim END
4314 vim9script
4315 def TwoArguments(nr: number, str: string)
4316 echo str nr
4317 enddef
4318 var Ref = TwoArguments
4319 123->Ref('b')
4320 def AndNowCompiled()
4321 456->Ref('x')
4322 enddef
4323 AndNowCompiled()
4324 END
4325 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004326enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004327
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004328def Test_closing_brace_at_start_of_line()
4329 var lines =<< trim END
4330 def Func()
4331 enddef
4332 Func(
4333 )
4334 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004335 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004336enddef
4337
Bram Moolenaar62aec932022-01-29 21:45:34 +00004338func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004339 let g:mydict = {}
4340 func g:mydict.afunc()
4341 let g:result = self.key
4342 endfunc
4343endfunc
4344
4345def Test_numbered_function_reference()
4346 CreateMydict()
4347 var output = execute('legacy func g:mydict.afunc')
4348 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4349 execute 'function(' .. funcName .. ', [], {key: 42})()'
4350 # check that the function still exists
4351 assert_equal(output, execute('legacy func g:mydict.afunc'))
4352 unlet g:mydict
4353enddef
4354
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004355def Test_numbered_function_call()
4356 var lines =<< trim END
4357 let s:legacyscript = {}
4358 func s:legacyscript.Helper() abort
4359 return "Success"
4360 endfunc
4361 let g:legacyscript = deepcopy(s:legacyscript)
4362
4363 let g:legacy_result = eval("g:legacyscript.Helper()")
4364 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4365 END
4366 v9.CheckScriptSuccess(lines)
4367 assert_equal('Success', g:legacy_result)
4368 assert_equal('Success', g:vim9_result)
4369
4370 unlet g:legacy_result
4371 unlet g:vim9_result
4372enddef
4373
Bram Moolenaard3a11782022-01-05 16:50:40 +00004374def Test_go_beyond_end_of_cmd()
4375 # this was reading the byte after the end of the line
4376 var lines =<< trim END
4377 def F()
4378 cal
4379 enddef
4380 defcompile
4381 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004382 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004383enddef
4384
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004385" Test for memory allocation failure when defining a new lambda
4386func Test_lambda_allocation_failure()
4387 new
4388 let lines =<< trim END
4389 vim9script
4390 g:Xlambda = (x): number => {
4391 return x + 1
4392 }
4393 END
4394 call setline(1, lines)
4395 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4396 call assert_fails('source', 'E342:')
4397 call assert_false(exists('g:Xlambda'))
4398 bw!
4399endfunc
4400
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004401def Test_lambda_argument_type_check()
4402 var lines =<< trim END
4403 vim9script
4404
4405 def Scan(ll: list<any>): func(func(any))
4406 return (Emit: func(any)) => {
4407 for e in ll
4408 Emit(e)
4409 endfor
4410 }
4411 enddef
4412
4413 def Sum(Cont: func(func(any))): any
4414 var sum = 0.0
4415 Cont((v: float) => { # <== NOTE: the lambda expects a float
4416 sum += v
4417 })
4418 return sum
4419 enddef
4420
Bram Moolenaar47bba532023-01-20 18:49:46 +00004421 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004422 echo Scan(ml)->Sum()
4423 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004424 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004425enddef
4426
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004427def Test_multiple_funcref()
4428 # This was using a NULL pointer
4429 var lines =<< trim END
4430 vim9script
4431 def A(F: func, ...args: list<any>): func
4432 return funcref(F, args)
4433 enddef
4434
4435 def B(F: func): func
4436 return funcref(A, [F])
4437 enddef
4438
4439 def Test(n: number)
4440 enddef
4441
4442 const X = B(Test)
4443 X(1)
4444 END
4445 v9.CheckScriptSuccess(lines)
4446
4447 # slightly different case
4448 lines =<< trim END
4449 vim9script
4450
4451 def A(F: func, ...args: list<any>): any
4452 return call(F, args)
4453 enddef
4454
4455 def B(F: func): func
4456 return funcref(A, [F])
4457 enddef
4458
4459 def Test(n: number)
4460 enddef
4461
4462 const X = B(Test)
4463 X(1)
4464 END
4465 v9.CheckScriptSuccess(lines)
4466enddef
4467
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004468def Test_cexpr_errmsg_line_number()
4469 var lines =<< trim END
4470 vim9script
4471 def Func()
4472 var qfl = {}
4473 cexpr qfl
4474 enddef
4475 Func()
4476 END
4477 v9.CheckScriptFailure(lines, 'E777', 2)
4478enddef
4479
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004480def AddDefer(s: string)
4481 g:deferred->extend([s])
4482enddef
4483
4484def DeferTwo()
4485 g:deferred->extend(['in Two'])
4486 for n in range(3)
4487 defer g:AddDefer('two' .. n)
4488 endfor
4489 g:deferred->extend(['end Two'])
4490enddef
4491
4492def DeferOne()
4493 g:deferred->extend(['in One'])
4494 defer g:AddDefer('one')
4495 g:DeferTwo()
4496 g:deferred->extend(['end One'])
4497
4498 writefile(['text'], 'XdeferFile')
4499 defer delete('XdeferFile')
4500enddef
4501
4502def Test_defer()
4503 g:deferred = []
4504 g:DeferOne()
4505 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4506 unlet g:deferred
4507 assert_equal('', glob('XdeferFile'))
4508enddef
4509
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004510def Test_invalid_redir()
4511 var lines =<< trim END
4512 def Tone()
4513 if 1
4514 redi =>@�0
4515 redi END
4516 endif
4517 enddef
4518 defcompile
4519 END
4520 v9.CheckScriptFailure(lines, 'E354:')
4521 delfunc g:Tone
4522
4523 # this was reading past the end of the line
4524 lines =<< trim END
4525 def Ttwo()
4526 if 0
4527 redi =>@�0
4528 redi END
4529 endif
4530 enddef
4531 defcompile
4532 END
4533 v9.CheckScriptFailure(lines, 'E354:')
4534 delfunc g:Ttwo
4535enddef
4536
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004537func Test_keytyped_in_nested_function()
4538 CheckRunVimInTerminal
4539
4540 call Run_Test_keytyped_in_nested_function()
4541endfunc
4542
4543def Run_Test_keytyped_in_nested_function()
4544 var lines =<< trim END
4545 vim9script
4546 autocmd CmdlineEnter * sample#Init()
4547
4548 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4549 END
4550 writefile(lines, 'Xkeytyped', 'D')
4551
4552 var dir = 'Xrtpdir/autoload'
4553 mkdir(dir, 'pR')
4554
4555 lines =<< trim END
4556 vim9script
4557 export def Init(): void
4558 cnoremap <expr>" <SID>Quote('"')
4559 enddef
4560 def Quote(str: string): string
4561 def InPair(): number
4562 return 0
4563 enddef
4564 return str
4565 enddef
4566 END
4567 writefile(lines, dir .. '/sample.vim')
4568
4569 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4570
4571 term_sendkeys(buf, ':"')
4572 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4573
4574 # clean up
4575 term_sendkeys(buf, "\<Esc>")
4576 g:StopVimInTerminal(buf)
4577enddef
4578
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004579" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004580if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004581 def Test_python3_command()
4582 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004583 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004584 assert_equal('yes', g:done)
4585 unlet g:done
4586 enddef
4587
Bram Moolenaar20677332021-06-06 17:02:53 +02004588 def Test_python3_heredoc()
4589 py3 << trim EOF
4590 import vim
4591 vim.vars['didit'] = 'yes'
4592 EOF
4593 assert_equal('yes', g:didit)
4594
4595 python3 << trim EOF
4596 import vim
4597 vim.vars['didit'] = 'again'
4598 EOF
4599 assert_equal('again', g:didit)
4600 enddef
4601endif
4602
Bram Moolenaar20677332021-06-06 17:02:53 +02004603if has('lua')
4604 def Test_lua_heredoc()
4605 g:d = {}
4606 lua << trim EOF
4607 x = vim.eval('g:d')
4608 x['key'] = 'val'
4609 EOF
4610 assert_equal('val', g:d.key)
4611 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004612
4613 def Test_lua_heredoc_fails()
4614 var lines = [
4615 'vim9script',
4616 'def ExeLua()',
4617 'lua << trim EOLUA',
4618 "x = vim.eval('g:nodict')",
4619 'EOLUA',
4620 'enddef',
4621 'ExeLua()',
4622 ]
4623 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4624 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004625endif
4626
Bram Moolenaard881d152022-05-13 13:50:36 +01004627if has('perl')
4628 def Test_perl_heredoc_nested()
4629 var lines =<< trim END
4630 vim9script
4631 def F(): string
4632 def G(): string
4633 perl << EOF
4634 EOF
4635 return 'done'
4636 enddef
4637 return G()
4638 enddef
4639 assert_equal('done', F())
4640 END
4641 v9.CheckScriptSuccess(lines)
4642 enddef
4643endif
4644
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004645
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004646" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker