blob: ffb8de48dd0b0645ce7694bfa1782a1f0cef2020 [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
781 # TODO: this should give an error for using a missing argument
782 # lines =<< trim END
783 # vim9script
784
785 # def F(a: string = v:none)
786 # var b = a
787 # enddef
788 # F()
789 # END
790 # v9.CheckScriptFailure(lines, 'E99:')
791enddef
792
Bram Moolenaar47bba532023-01-20 18:49:46 +0000793def Test_convert_number_to_float()
794 var lines =<< trim END
795 vim9script
796 def Foo(a: float, b: float): float
797 return a + b
798 enddef
799
800 assert_equal(5.3, Foo(3.3, 2))
801 END
802 v9.CheckScriptSuccess(lines)
803enddef
804
Bram Moolenaar62aec932022-01-29 21:45:34 +0000805def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100806 a: number, #comment
807 b: bool, # comment
808 c: string) #comment
809 assert_equal(4, a)
810 assert_equal(true, b)
811 assert_equal('yes', c)
812enddef
813
814def Test_func_with_comments()
815 FuncWithComment(4, true, 'yes')
816
817 var lines =<< trim END
818 def Func(# comment
819 arg: string)
820 enddef
821 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000822 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100823
824 lines =<< trim END
825 def Func(
826 arg: string# comment
827 )
828 enddef
829 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000830 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100831
832 lines =<< trim END
833 def Func(
834 arg: string
835 )# comment
836 enddef
837 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000838 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100839enddef
840
Bram Moolenaar04b12692020-05-04 23:24:44 +0200841def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000842 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200843 return 'nested ' .. arg
844 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000845 NestedDef(':def')->assert_equal('nested :def')
846
847 func NestedFunc(arg)
848 return 'nested ' .. a:arg
849 endfunc
850 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200851
Bram Moolenaar62aec932022-01-29 21:45:34 +0000852 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
853 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200854
Bram Moolenaar62aec932022-01-29 21:45:34 +0000855 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
856 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200857
Bram Moolenaar54021752020-12-06 18:50:36 +0100858 var lines =<< trim END
859 def Outer()
860 def Inner()
861 # comment
862 enddef
863 def Inner()
864 enddef
865 enddef
866 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000867 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100868
869 lines =<< trim END
870 def Outer()
871 def Inner()
872 # comment
873 enddef
874 def! Inner()
875 enddef
876 enddef
877 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000878 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100879
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000880 lines =<< trim END
881 vim9script
882 def Outer()
883 def Inner()
884 g:result = 'ok'
885 enddef
886 Inner()
887 enddef
888 Outer()
889 Inner()
890 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000891 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000892 assert_equal('ok', g:result)
893 unlet g:result
894
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000895 lines =<< trim END
896 vim9script
897 def Outer()
898 def _Inner()
899 echo 'bad'
900 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000901 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000902 enddef
903 defcompile
904 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000905 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000906
907 lines =<< trim END
908 vim9script
909 def Outer()
910 def g:inner()
911 echo 'bad'
912 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000913 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000914 enddef
915 defcompile
916 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000917 v9.CheckScriptFailure(lines, 'E1267:')
918
919 lines =<< trim END
920 vim9script
921 def g:_Func()
922 echo 'bad'
923 enddef
924 END
925 v9.CheckScriptFailure(lines, 'E1267:')
926
927 lines =<< trim END
928 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000929 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +0000930 echo 'bad'
931 enddef
932 END
933 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000934
Bram Moolenaar54021752020-12-06 18:50:36 +0100935 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +0100936 lines =<< trim END
937 vim9script
938 var thecount = 0
939 if true
940 def Test(): number
941 def TheFunc(): number
942 thecount += 1
943 return thecount
944 enddef
945 return TheFunc()
946 enddef
947 endif
948 defcompile
949 assert_equal(1, Test())
950 assert_equal(2, Test())
951 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000952 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +0100953
954 # also works when "thecount" is inside the "if" block
955 lines =<< trim END
956 vim9script
957 if true
958 var thecount = 0
959 def Test(): number
960 def TheFunc(): number
961 thecount += 1
962 return thecount
963 enddef
964 return TheFunc()
965 enddef
966 endif
967 defcompile
968 assert_equal(1, Test())
969 assert_equal(2, Test())
970 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000971 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200972
Bram Moolenaara915fa02022-03-23 11:29:15 +0000973 # nested function with recursive call
974 lines =<< trim END
975 vim9script
976
977 def MyFunc(): number
978 def Fib(n: number): number
979 if n < 2
980 return 1
981 endif
982 return Fib(n - 2) + Fib(n - 1)
983 enddef
984
985 return Fib(5)
986 enddef
987
988 assert_equal(8, MyFunc())
989 END
990 v9.CheckScriptSuccess(lines)
991
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200992 lines =<< trim END
993 vim9script
994 def Outer()
995 def Inner()
996 echo 'hello'
997 enddef burp
998 enddef
999 defcompile
1000 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001001 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001002enddef
1003
Bram Moolenaar1889f492022-08-16 19:34:44 +01001004def Test_nested_function_fails()
1005 var lines =<< trim END
1006 def T()
1007 def Func(g: string):string
1008 enddef
1009 Func()
1010 enddef
1011 silent! defcompile
1012 END
1013 v9.CheckScriptFailure(lines, 'E1069:')
1014enddef
1015
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001016def Test_not_nested_function()
1017 echo printf('%d',
1018 function('len')('xxx'))
1019enddef
1020
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001021func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001022 call MyDefaultArgs()->assert_equal('string')
1023 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001024 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001025endfunc
1026
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001027def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001028 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001029 vim9script
1030 def Outer()
1031 def g:Inner(): string
1032 return 'inner'
1033 enddef
1034 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001035 defcompile
1036 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001037 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001038 delfunc g:Inner
1039 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001040 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001041 delfunc g:Inner
1042 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001043 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001044 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001045 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001046 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001047
1048 lines =<< trim END
1049 vim9script
1050 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001051 func g:Inner()
1052 return 'inner'
1053 endfunc
1054 enddef
1055 defcompile
1056 Outer()
1057 g:Inner()->assert_equal('inner')
1058 delfunc g:Inner
1059 Outer()
1060 g:Inner()->assert_equal('inner')
1061 delfunc g:Inner
1062 Outer()
1063 g:Inner()->assert_equal('inner')
1064 delfunc g:Inner
1065 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001066 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001067
1068 lines =<< trim END
1069 vim9script
1070 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001071 def g:Inner(): string
1072 return 'inner'
1073 enddef
1074 enddef
1075 defcompile
1076 Outer()
1077 Outer()
1078 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001079 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001080 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001081
1082 lines =<< trim END
1083 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001084 def Outer()
1085 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001086 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001087 enddef
1088 g:Inner()
1089 enddef
1090 Outer()
1091 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001092 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001093 delfunc g:Inner
1094
1095 lines =<< trim END
1096 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001097 def Func()
1098 echo 'script'
1099 enddef
1100 def Outer()
1101 def Func()
1102 echo 'inner'
1103 enddef
1104 enddef
1105 defcompile
1106 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001107 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001108
1109 lines =<< trim END
1110 vim9script
1111 def Func()
1112 echo 'script'
1113 enddef
1114 def Func()
1115 echo 'script'
1116 enddef
1117 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001118 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001119enddef
1120
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001121def DefListAll()
1122 def
1123enddef
1124
1125def DefListOne()
1126 def DefListOne
1127enddef
1128
1129def DefListMatches()
1130 def /DefList
1131enddef
1132
1133def Test_nested_def_list()
1134 var funcs = split(execute('call DefListAll()'), "\n")
1135 assert_true(len(funcs) > 10)
1136 assert_true(funcs->index('def DefListAll()') >= 0)
1137
1138 funcs = split(execute('call DefListOne()'), "\n")
1139 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1140
1141 funcs = split(execute('call DefListMatches()'), "\n")
1142 assert_true(len(funcs) >= 3)
1143 assert_true(funcs->index('def DefListAll()') >= 0)
1144 assert_true(funcs->index('def DefListOne()') >= 0)
1145 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001146
1147 var lines =<< trim END
1148 vim9script
1149 def Func()
1150 def +Func+
1151 enddef
1152 defcompile
1153 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001154 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001155enddef
1156
Bram Moolenaare08be092022-02-17 13:08:26 +00001157def Test_global_function_not_found()
1158 var lines =<< trim END
1159 g:Ref = 123
1160 call g:Ref()
1161 END
1162 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1163enddef
1164
Bram Moolenaar333894b2020-08-01 18:53:07 +02001165def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001166 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001167 vim9script
1168 def g:Func(): string
1169 return 'global'
1170 enddef
1171 def Func(): string
1172 return 'local'
1173 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001174 g:Func()->assert_equal('global')
1175 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001176 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001177 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001178 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001179
1180 lines =<< trim END
1181 vim9script
1182 def g:Funcy()
1183 echo 'funcy'
1184 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001185 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001186 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001187 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001188enddef
1189
Bram Moolenaar0f769812020-09-12 18:32:34 +02001190def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001191 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001192 vim9script
1193 def g:Gfunc(): string
1194 return 'global'
1195 enddef
1196 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001197 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001198 return Gfunc('testing')
1199 enddef
1200 g:Gfunc()->assert_equal('global')
1201 AnotherFunc()->assert_equal(7)
1202 delfunc g:Gfunc
1203 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001204 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001205
1206 lines =<< trim END
1207 vim9script
1208 def g:Func(): string
1209 return 'global'
1210 enddef
1211 def AnotherFunc()
1212 g:Func = function('len')
1213 enddef
1214 AnotherFunc()
1215 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001216 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001217 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001218
Bram Moolenaar62aec932022-01-29 21:45:34 +00001219 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001220 lines =<< trim END
1221 vim9script
1222 def g:Func(): string
1223 return 'global'
1224 enddef
1225 def AnotherFunc(): string
1226 return Func()
1227 enddef
1228 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001229 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001230 v9.CheckScriptFailure(lines, 'E117:')
1231 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001232
1233 lines =<< trim END
1234 vim9script
1235 def g:Func(): string
1236 return 'global'
1237 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001238 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001239 delfunc g:Func
1240 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001241 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001242
1243 # This does not shadow "i" which is visible only inside the for loop
1244 lines =<< trim END
1245 vim9script
1246
1247 def Foo(i: number)
1248 echo i
1249 enddef
1250
1251 for i in range(3)
1252 # Foo() is compiled here
1253 Foo(i)
1254 endfor
1255 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001256 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001257enddef
1258
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001259func TakesOneArg(arg)
1260 echo a:arg
1261endfunc
1262
1263def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001264 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1265 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1266 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1267 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001268
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001269 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001270 vim9script
1271 def Func(s: string)
1272 echo s
1273 enddef
1274 Func([])
1275 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001276 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001277
Bram Moolenaar9a015112021-12-31 14:06:45 +00001278 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001279 lines =<< trim END
1280 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001281 var name = 'piet'
1282 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001283 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001284 enddef
1285 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001286 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001287
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001288 # same, inside the same block
1289 lines =<< trim END
1290 vim9script
1291 if true
1292 var name = 'piet'
1293 def FuncOne(name: string)
1294 echo name
1295 enddef
1296 endif
1297 END
1298 v9.CheckScriptFailure(lines, 'E1168:')
1299
1300 # variable in other block is OK
1301 lines =<< trim END
1302 vim9script
1303 if true
1304 var name = 'piet'
1305 endif
1306 def FuncOne(name: string)
1307 echo name
1308 enddef
1309 END
1310 v9.CheckScriptSuccess(lines)
1311
Bram Moolenaardce24412022-02-08 20:35:30 +00001312 # with another variable in another block
1313 lines =<< trim END
1314 vim9script
1315 if true
1316 var name = 'piet'
1317 # define a function so that the variable isn't cleared
1318 def GetItem(): string
1319 return item
1320 enddef
1321 endif
1322 if true
1323 var name = 'peter'
1324 def FuncOne(name: string)
1325 echo name
1326 enddef
1327 endif
1328 END
1329 v9.CheckScriptFailure(lines, 'E1168:')
1330
1331 # only variable in another block is OK
1332 lines =<< trim END
1333 vim9script
1334 if true
1335 var name = 'piet'
1336 # define a function so that the variable isn't cleared
1337 def GetItem(): string
1338 return item
1339 enddef
1340 endif
1341 if true
1342 def FuncOne(name: string)
1343 echo name
1344 enddef
1345 endif
1346 END
1347 v9.CheckScriptSuccess(lines)
1348
Bram Moolenaar9a015112021-12-31 14:06:45 +00001349 # argument name declared later is only found when compiling
1350 lines =<< trim END
1351 vim9script
1352 def FuncOne(name: string)
1353 echo nr
1354 enddef
1355 var name = 'piet'
1356 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001357 v9.CheckScriptSuccess(lines)
1358 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001359
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001360 lines =<< trim END
1361 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001362 def FuncOne(nr: number)
1363 echo nr
1364 enddef
1365 def FuncTwo()
1366 FuncOne()
1367 enddef
1368 defcompile
1369 END
1370 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001371 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001372 try
1373 source Xscript
1374 catch
1375 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1376 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1377 didCatch = true
1378 endtry
1379 assert_true(didCatch)
1380
1381 lines =<< trim END
1382 vim9script
1383 def FuncOne(nr: number)
1384 echo nr
1385 enddef
1386 def FuncTwo()
1387 FuncOne(1, 2)
1388 enddef
1389 defcompile
1390 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001391 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001392 didCatch = false
1393 try
1394 source Xscript
1395 catch
1396 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1397 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1398 didCatch = true
1399 endtry
1400 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001401enddef
1402
Bram Moolenaar50824712020-12-20 21:10:17 +01001403def Test_call_funcref_wrong_args()
1404 var head =<< trim END
1405 vim9script
1406 def Func3(a1: string, a2: number, a3: list<number>)
1407 echo a1 .. a2 .. a3[0]
1408 enddef
1409 def Testme()
1410 var funcMap: dict<func> = {func: Func3}
1411 END
1412 var tail =<< trim END
1413 enddef
1414 Testme()
1415 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001416 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001417
Bram Moolenaar62aec932022-01-29 21:45:34 +00001418 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1419 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001420
1421 var lines =<< trim END
1422 vim9script
1423 var Ref: func(number): any
1424 Ref = (j) => !j
1425 echo Ref(false)
1426 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001427 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001428
1429 lines =<< trim END
1430 vim9script
1431 var Ref: func(number): any
1432 Ref = (j) => !j
1433 call Ref(false)
1434 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001435 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001436enddef
1437
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001438def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001439 var lines =<< trim END
1440 var Callback = (..._) => 'anything'
1441 assert_equal('anything', Callback())
1442 assert_equal('anything', Callback(1))
1443 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001444
1445 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001446 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001447 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001448
Bram Moolenaar62aec932022-01-29 21:45:34 +00001449 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001450 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001451
Bram Moolenaar2a389082021-04-09 20:24:31 +02001452 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001453 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001454 echo Ref(1, 'x')
1455 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001456 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001457
1458 lines =<< trim END
1459 var Ref: func(job, string, number)
1460 Ref = (x, y) => 0
1461 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001462 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001463
1464 lines =<< trim END
1465 var Ref: func(job, string)
1466 Ref = (x, y, z) => 0
1467 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001468 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001469
1470 lines =<< trim END
1471 var one = 1
1472 var l = [1, 2, 3]
1473 echo map(l, (one) => one)
1474 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001475 v9.CheckDefFailure(lines, 'E1167:')
1476 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001477
1478 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001479 var Ref: func(any, ?any): bool
1480 Ref = (_, y = 1) => false
1481 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001482 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001483
1484 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001485 var a = 0
1486 var b = (a == 0 ? 1 : 2)
1487 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001488 var txt = 'a'
1489 b = (txt =~ 'x' ? 1 : 2)
1490 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001491 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001492 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001493
1494 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001495 def ShadowLocal()
1496 var one = 1
1497 var l = [1, 2, 3]
1498 echo map(l, (one) => one)
1499 enddef
1500 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001501 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001502
1503 lines =<< trim END
1504 def Shadowarg(one: number)
1505 var l = [1, 2, 3]
1506 echo map(l, (one) => one)
1507 enddef
1508 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001509 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001510
1511 lines =<< trim END
1512 echo ((a) => a)('aa', 'bb')
1513 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001514 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001515
1516 lines =<< trim END
1517 echo 'aa'->((a) => a)('bb')
1518 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001519 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1520 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001521enddef
1522
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001523def Test_lambda_line_nr()
1524 var lines =<< trim END
1525 vim9script
1526 # comment
1527 # comment
1528 var id = timer_start(1'000, (_) => 0)
1529 var out = execute('verbose ' .. timer_info(id)[0].callback
1530 ->string()
1531 ->substitute("('\\|')", ' ', 'g'))
1532 assert_match('Last set from .* line 4', out)
1533 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001534 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001535enddef
1536
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001537def FilterWithCond(x: string, Cond: func(string): bool): bool
1538 return Cond(x)
1539enddef
1540
Bram Moolenaar0346b792021-01-31 22:18:29 +01001541def Test_lambda_return_type()
1542 var lines =<< trim END
1543 var Ref = (): => 123
1544 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001545 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001546
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001547 # no space before the return type
1548 lines =<< trim END
1549 var Ref = (x):number => x + 1
1550 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001551 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001552
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001553 # this works
1554 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001555 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001556 endfor
1557
1558 # this fails
1559 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001560 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001561 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001562 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 +02001563
1564 lines =<< trim END
1565 var Lambda1 = (x) => {
1566 return x
1567 }
1568 assert_equal('asdf', Lambda1('asdf'))
1569 var Lambda2 = (x): string => {
1570 return x
1571 }
1572 assert_equal('foo', Lambda2('foo'))
1573 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001574 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001575
1576 lines =<< trim END
1577 var Lambda = (x): string => {
1578 return x
1579 }
1580 echo Lambda(['foo'])
1581 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001582 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001583enddef
1584
Bram Moolenaar709664c2020-12-12 14:33:41 +01001585def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001586 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001587 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001588 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001589enddef
1590
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001591def Test_lambda_invalid_block()
1592 var lines =<< trim END
1593 timer_start(0, (_) => { # echo
1594 echo 'yes'
1595 })
1596 END
1597 v9.CheckDefAndScriptSuccess(lines)
1598
1599 lines =<< trim END
1600 timer_start(0, (_) => { " echo
1601 echo 'yes'
1602 })
1603 END
1604 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1605
1606 lines =<< trim END
1607 timer_start(0, (_) => { | echo
1608 echo 'yes'
1609 })
1610 END
1611 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1612enddef
1613
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001614def Test_lambda_with_following_cmd()
1615 var lines =<< trim END
1616 set ts=2
1617 var Lambda = () => {
1618 set ts=4
1619 } | set ts=3
1620 assert_equal(3, &ts)
1621 Lambda()
1622 assert_equal(4, &ts)
1623 END
1624 v9.CheckDefAndScriptSuccess(lines)
1625 set ts=8
1626enddef
1627
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001628def Test_pass_legacy_lambda_to_def_func()
1629 var lines =<< trim END
1630 vim9script
1631 func Foo()
1632 eval s:Bar({x -> 0})
1633 endfunc
1634 def Bar(y: any)
1635 enddef
1636 Foo()
1637 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001638 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001639
1640 lines =<< trim END
1641 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001642 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001643 enddef
1644 legacy call g:TestFunc({-> 0})
1645 delfunc g:TestFunc
1646
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001647 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001648 enddef
1649 legacy call g:TestFunc({nr -> 0})
1650 delfunc g:TestFunc
1651 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001652 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001653enddef
1654
Bram Moolenaar844fb642021-10-23 13:32:30 +01001655def Test_lambda_in_reduce_line_break()
1656 # this was using freed memory
1657 var lines =<< trim END
1658 vim9script
1659 const result: dict<number> =
1660 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1661 ->reduce((acc, val) => {
1662 if has_key(acc, val)
1663 acc[val] += 1
1664 return acc
1665 else
1666 acc[val] = 1
1667 return acc
1668 endif
1669 }, {})
1670 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1671 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001672 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001673enddef
1674
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001675def Test_set_opfunc_to_lambda()
1676 var lines =<< trim END
1677 vim9script
1678 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1679 def CountSpaces(type = ''): string
1680 if type == ''
1681 &operatorfunc = (t) => CountSpaces(t)
1682 return 'g@'
1683 endif
1684 normal! '[V']y
1685 g:result = getreg('"')->count(' ')
1686 return ''
1687 enddef
1688 new
1689 'a b c d e'->setline(1)
1690 feedkeys("\<F4>", 'x')
1691 assert_equal(4, g:result)
1692 bwipe!
1693 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001694 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001695enddef
1696
Bram Moolenaaref082e12021-12-12 21:02:03 +00001697def Test_set_opfunc_to_global_function()
1698 var lines =<< trim END
1699 vim9script
1700 def g:CountSpaces(type = ''): string
1701 normal! '[V']y
1702 g:result = getreg('"')->count(' ')
1703 return ''
1704 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001705 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001706 &operatorfunc = g:CountSpaces
1707 new
1708 'a b c d e'->setline(1)
1709 feedkeys("g@_", 'x')
1710 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001711
1712 &operatorfunc = ''
1713 g:result = 0
1714 # global function works in :def function
1715 def Func()
1716 &operatorfunc = g:CountSpaces
1717 enddef
1718 Func()
1719 feedkeys("g@_", 'x')
1720 assert_equal(4, g:result)
1721
Bram Moolenaaref082e12021-12-12 21:02:03 +00001722 bwipe!
1723 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001724 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001725 &operatorfunc = ''
1726enddef
1727
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001728def Test_use_script_func_name_with_prefix()
1729 var lines =<< trim END
1730 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001731 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001732 return 'it'
1733 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001734 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001735 assert_equal('it', Fn())
1736 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001737 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001738enddef
1739
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001740def Test_lambda_type_allocated()
1741 # Check that unreferencing a partial using a lambda can use the variable type
1742 # after the lambda has been freed and does not leak memory.
1743 var lines =<< trim END
1744 vim9script
1745
1746 func MyomniFunc1(val, findstart, base)
1747 return a:findstart ? 0 : []
1748 endfunc
1749
1750 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1751 &omnifunc = Lambda
1752 Lambda = (a, b) => MyomniFunc1(20, a, b)
1753 &omnifunc = string(Lambda)
1754 Lambda = (a, b) => strlen(a)
1755 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001756 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001757enddef
1758
Bram Moolenaara7583c42022-05-07 21:14:05 +01001759def Test_define_lambda_in_execute()
1760 var lines =<< trim [CODE]
1761 vim9script
1762
1763 def BuildFuncMultiLine(): func
1764 var x =<< trim END
1765 g:SomeRandomFunc = (d: dict<any>) => {
1766 return d.k1 + d.k2
1767 }
1768 END
1769 execute(x)
1770 return g:SomeRandomFunc
1771 enddef
1772 var ResultPlus = BuildFuncMultiLine()
1773 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1774 [CODE]
1775 v9.CheckScriptSuccess(lines)
1776 unlet g:SomeRandomFunc
1777enddef
1778
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001779" Default arg and varargs
1780def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001781 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001782 for s in rest
1783 res ..= ',' .. s
1784 endfor
1785 return res
1786enddef
1787
1788def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001789 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1790 g:MyDefVarargs('one')->assert_equal('one,foo')
1791 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1792 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1793 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001794 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001795 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001796 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001797
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001798 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001799 vim9script
1800 def Func(...l: list<string>)
1801 echo l
1802 enddef
1803 Func('a', 'b', 'c')
1804 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001805 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001806
1807 lines =<< trim END
1808 vim9script
1809 def Func(...l: list<string>)
1810 echo l
1811 enddef
1812 Func()
1813 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001814 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001815
1816 lines =<< trim END
1817 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001818 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001819 echo l
1820 enddef
1821 Func(0)
1822 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001823 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001824
1825 lines =<< trim END
1826 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001827 def Func(...l: any)
1828 echo l
1829 enddef
1830 Func(0)
1831 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001832 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001833
1834 lines =<< trim END
1835 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001836 def Func(..._l: list<string>)
1837 echo _l
1838 enddef
1839 Func('a', 'b', 'c')
1840 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001841 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001842
1843 lines =<< trim END
1844 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001845 def Func(...l: list<string>)
1846 echo l
1847 enddef
1848 Func(1, 2, 3)
1849 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001850 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001851
1852 lines =<< trim END
1853 vim9script
1854 def Func(...l: list<string>)
1855 echo l
1856 enddef
1857 Func('a', 9)
1858 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001859 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001860
1861 lines =<< trim END
1862 vim9script
1863 def Func(...l: list<string>)
1864 echo l
1865 enddef
1866 Func(1, 'a')
1867 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001868 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001869
1870 lines =<< trim END
1871 vim9script
1872 def Func( # some comment
1873 ...l = []
1874 )
1875 echo l
1876 enddef
1877 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001878 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001879
1880 lines =<< trim END
1881 vim9script
1882 def DoIt()
1883 g:Later('')
1884 enddef
1885 defcompile
1886 def g:Later(...l: list<number>)
1887 enddef
1888 DoIt()
1889 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001890 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001891enddef
1892
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001893let s:value = ''
1894
1895def FuncOneDefArg(opt = 'text')
1896 s:value = opt
1897enddef
1898
1899def FuncTwoDefArg(nr = 123, opt = 'text'): string
1900 return nr .. opt
1901enddef
1902
1903def FuncVarargs(...arg: list<string>): string
1904 return join(arg, ',')
1905enddef
1906
1907def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001908 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001909 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001910 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001911 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001912 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001913 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001914
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001915 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001916 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001917 RefDef2Arg()->assert_equal('123text')
1918 RefDef2Arg(99)->assert_equal('99text')
1919 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001920
Bram Moolenaar62aec932022-01-29 21:45:34 +00001921 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
1922 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001923
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001924 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001925 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001926 RefVarargs()->assert_equal('')
1927 RefVarargs('one')->assert_equal('one')
1928 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001929
Bram Moolenaar62aec932022-01-29 21:45:34 +00001930 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
1931 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001932enddef
1933
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001934" Only varargs
1935def MyVarargsOnly(...args: list<string>): string
1936 return join(args, ',')
1937enddef
1938
1939def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001940 g:MyVarargsOnly()->assert_equal('')
1941 g:MyVarargsOnly('one')->assert_equal('one')
1942 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
1943 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
1944 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001945enddef
1946
Bram Moolenaar36818a92023-01-03 12:33:26 +00001947def Test_varargs_mismatch()
1948 var lines =<< trim END
1949 vim9script
1950
1951 def Map(Fn: func(...any): number): number
1952 return Fn('12')
1953 enddef
1954
1955 var res = Map((v) => str2nr(v))
1956 assert_equal(12, res)
1957 END
1958 v9.CheckScriptSuccess(lines)
1959enddef
1960
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001961def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00001962 var lines =<< trim END
1963 def Func(x: number)
1964 var x = 234
1965 enddef
1966 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001967 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00001968
1969 lines =<< trim END
1970 def Func(Ref: number)
1971 def Ref()
1972 enddef
1973 enddef
1974 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001975 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001976enddef
1977
Bram Moolenaar62aec932022-01-29 21:45:34 +00001978def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001979 arg['key'] = 'value'
1980enddef
1981
Bram Moolenaar62aec932022-01-29 21:45:34 +00001982def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001983 arg[0] = 'value'
1984enddef
1985
1986def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001987 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001988 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001989 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001990 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001991 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001992 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001993 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001994
Bram Moolenaar62aec932022-01-29 21:45:34 +00001995 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001996 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001997enddef
1998
Bram Moolenaarb816dae2020-09-20 22:04:00 +02001999" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002000def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002001 return firstline .. lastline
2002enddef
2003
2004def Test_argument_names()
2005 assert_equal('OK', WithReservedNames('O', 'K'))
2006enddef
2007
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002008def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002009 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002010 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002011enddef
2012
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002013func DefinedLater(arg)
2014 return a:arg
2015endfunc
2016
2017def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002018 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002019 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002020 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002021
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002022 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002023 vim9script
2024 def RetNumber(): number
2025 return 123
2026 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002027 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002028 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002029 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002030 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002031
2032 lines =<< trim END
2033 vim9script
2034 def RetNumber(): number
2035 return 123
2036 enddef
2037 def Bar(F: func: number): number
2038 return F()
2039 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002040 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002041 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002042 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002043 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002044
2045 lines =<< trim END
2046 vim9script
2047 def UseNumber(nr: number)
2048 echo nr
2049 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002050 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002051 Funcref(123)
2052 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002053 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002054
2055 lines =<< trim END
2056 vim9script
2057 def UseNumber(nr: number)
2058 echo nr
2059 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002060 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002061 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002062 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002063
2064 lines =<< trim END
2065 vim9script
2066 def EchoNr(nr = 34)
2067 g:echo = nr
2068 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002069 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002070 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002071 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002072 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002073 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002074 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002075 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002076
2077 lines =<< trim END
2078 vim9script
2079 def EchoList(...l: list<number>)
2080 g:echo = l
2081 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002082 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002083 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002084 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002085 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002086 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002087 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002088 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002089
2090 lines =<< trim END
2091 vim9script
2092 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2093 g:optarg = opt
2094 g:listarg = l
2095 return nr
2096 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002097 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002098 Funcref(10)->assert_equal(10)
2099 g:optarg->assert_equal(12)
2100 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002101
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002102 Funcref(11, 22)->assert_equal(11)
2103 g:optarg->assert_equal(22)
2104 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002105
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002106 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2107 g:optarg->assert_equal(18)
2108 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002109 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002110 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002111
2112 lines =<< trim END
2113 function s:func(num)
2114 return a:num * 2
2115 endfunction
2116
2117 def s:CallFuncref()
2118 var Funcref = function('s:func')
2119 Funcref(3)->assert_equal(6)
2120 enddef
2121 call s:CallFuncref()
2122 END
2123 v9.CheckScriptSuccess(lines)
2124
2125 lines =<< trim END
2126 function s:func(num)
2127 return a:num * 2
2128 endfunction
2129
2130 def s:CallFuncref()
2131 var Funcref = function(s:func)
2132 Funcref(3)->assert_equal(6)
2133 enddef
2134 call s:CallFuncref()
2135 END
2136 v9.CheckScriptSuccess(lines)
2137
2138 lines =<< trim END
2139 function s:func(num)
2140 return a:num * 2
2141 endfunction
2142
2143 def s:CallFuncref()
2144 var Funcref = s:func
2145 Funcref(3)->assert_equal(6)
2146 enddef
2147 call s:CallFuncref()
2148 END
2149 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002150enddef
2151
2152let SomeFunc = function('len')
2153let NotAFunc = 'text'
2154
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002155def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002156 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002157 var Ref1: func(bool): string
2158 var Ref2: func(bool): number
2159 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002160 Ref3 = g:cond ? Ref1 : Ref2
2161
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002162 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002163 var Refa1: func(bool): number
2164 var Refa2: func(bool, number): number
2165 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002166 Refa3 = g:cond ? Refa1 : Refa2
2167
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002168 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002169 var Refb1: func(bool, string): number
2170 var Refb2: func(string, number): number
2171 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002172 Refb3 = g:cond ? Refb1 : Refb2
2173enddef
2174
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002175def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002176 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002177enddef
2178
2179def DefinedEvenLater(arg: string): string
2180 return arg
2181enddef
2182
2183def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002184 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002185 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002186enddef
2187
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002188def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002189 var lines =<< trim END
2190 vim9script
2191 # Define an outer function
2192 def FirstFunction()
2193 # Define an inner function
2194 def SecondFunction()
2195 # the function has a body, a double free is detected.
2196 AAAAA
2197
2198 # enddef followed by | or } followed by # one or more characters
2199 enddef|BBBB
2200 enddef
2201
2202 # Compile all functions
2203 defcompile
2204 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002205 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002206enddef
2207
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002208def Test_nested_function_with_args_split()
2209 var lines =<< trim END
2210 vim9script
2211 def FirstFunction()
2212 def SecondFunction(
2213 )
2214 # had a double free if the right parenthesis of the nested function is
2215 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002216
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002217 enddef|BBBB
2218 enddef
2219 # Compile all functions
2220 defcompile
2221 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002222 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002223
2224 lines =<< trim END
2225 vim9script
2226 def FirstFunction()
2227 func SecondFunction()
2228 endfunc|BBBB
2229 enddef
2230 defcompile
2231 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002232 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002233enddef
2234
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002235def Test_error_in_function_args()
2236 var lines =<< trim END
2237 def FirstFunction()
2238 def SecondFunction(J =
2239 # Nois
2240 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002241
2242 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002243 enddef
2244 # Compile all functions
2245 defcompile
2246 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002247 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002248enddef
2249
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002250def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002251 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002252 'def Func(): number',
2253 'return "a"',
2254 'enddef',
2255 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002256 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002257 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002258 'def Func(): string',
2259 'return 1',
2260 'enddef',
2261 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002262 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002263 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002264 'def Func(): void',
2265 'return "a"',
2266 'enddef',
2267 'defcompile'],
2268 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002269 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002270 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002271 'def Func()',
2272 'return "a"',
2273 'enddef',
2274 'defcompile'],
2275 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002276 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002277
Bram Moolenaar62aec932022-01-29 21:45:34 +00002278 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002279 'def Func(): number',
2280 'return',
2281 'enddef',
2282 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002283 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002284
Bram Moolenaar62aec932022-01-29 21:45:34 +00002285 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002286 'def Func():number',
2287 'return 123',
2288 'enddef',
2289 'defcompile'], 'E1069:')
2290 delfunc! g:Func
2291
Bram Moolenaar62aec932022-01-29 21:45:34 +00002292 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002293 'def Func() :number',
2294 'return 123',
2295 'enddef',
2296 'defcompile'], 'E1059:')
2297 delfunc! g:Func
2298
Bram Moolenaar62aec932022-01-29 21:45:34 +00002299 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002300 'def Func() : number',
2301 'return 123',
2302 'enddef',
2303 'defcompile'], 'E1059:')
2304 delfunc! g:Func
2305
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002306 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002307 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002308 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002309 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002310 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002311 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002312
Bram Moolenaar62aec932022-01-29 21:45:34 +00002313 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002314 'vim9script',
2315 'def FuncB()',
2316 ' return 123',
2317 'enddef',
2318 'def FuncA()',
2319 ' FuncB()',
2320 'enddef',
2321 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002322enddef
2323
2324def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002325 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002326 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2327 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2328 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2329 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2330 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002331enddef
2332
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002333def Test_white_space_before_comma()
2334 var lines =<< trim END
2335 vim9script
2336 def Func(a: number , b: number)
2337 enddef
2338 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002339 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002340 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002341enddef
2342
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002343def Test_white_space_after_comma()
2344 var lines =<< trim END
2345 vim9script
2346 def Func(a: number,b: number)
2347 enddef
2348 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002349 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002350
2351 # OK in legacy function
2352 lines =<< trim END
2353 vim9script
2354 func Func(a,b)
2355 endfunc
2356 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002357 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002358enddef
2359
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002360def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002361 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002362 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002363 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002364 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002365 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002366 enddef
2367 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002368 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002369
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002370 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002371 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002372 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002373
Bram Moolenaar67979662020-06-20 22:50:47 +02002374 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002375 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002376 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002377
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002378 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002379 def ListFunc(arg: list<number>)
2380 listvar = arg
2381 enddef
2382 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002383 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002384
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002385 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002386 def DictFunc(arg: dict<number>)
2387 dictvar = arg
2388 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002389 {a: 1, b: 2}->DictFunc()
2390 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002391 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002392 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002393 enddef
2394 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002395 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002396
Bram Moolenaare0de1712020-12-02 17:36:54 +01002397 {a: 3, b: 4}->DictFunc()
2398 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002399
2400 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002401 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002402 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002403 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002404
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002405 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002406 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002407 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002408 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002409 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002410 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002411
2412 def UseString()
2413 'xyork'->MyFunc()
2414 enddef
2415 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002416 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002417
Bram Moolenaar10409562020-07-29 20:00:38 +02002418 def UseString2()
2419 "knife"->MyFunc()
2420 enddef
2421 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002422 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002423
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002424 # prepending a colon makes it a mark
2425 new
2426 setline(1, ['aaa', 'bbb', 'ccc'])
2427 normal! 3Gmt1G
2428 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002429 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002430 bwipe!
2431
Bram Moolenaare6b53242020-07-01 17:28:33 +02002432 MyFunc(
2433 'continued'
2434 )
2435 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002436 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002437 )
2438
2439 call MyFunc(
2440 'more'
2441 ..
2442 'lines'
2443 )
2444 assert_equal(
2445 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002446 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002447 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002448 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002449 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002450enddef
2451
2452def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002453 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002454 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002455 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002456 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002457 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002458 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002459 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002460 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002461 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002462enddef
2463
Bram Moolenaar65b95452020-07-19 14:03:09 +02002464def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002465 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002466 vim9script
2467 def MyFunc(arg: string)
2468 echo arg
2469 enddef
2470 MyFunc(1234)
2471 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002472 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002473enddef
2474
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002475def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002476 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002477 vim9script
2478 const var = ''
2479 def MyFunc(arg: string)
2480 var = 'asdf'
2481 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002482 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002483 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002484 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002485 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002486
2487 lines =<< trim END
2488 const g:Aconst = 77
2489 def Change()
2490 # comment
2491 g:Aconst = 99
2492 enddef
2493 call Change()
2494 unlet g:Aconst
2495 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002496 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002497enddef
2498
2499" Test that inside :function a Python function can be defined, :def is not
2500" recognized.
2501func Test_function_python()
2502 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002503 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002504 execute py "<< EOF"
2505def do_something():
2506 return 1
2507EOF
2508endfunc
2509
2510def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002511 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002512 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002513 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002514 echo 'hello'
2515 enddef
2516
2517 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002518 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002519 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002520 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002521
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002522 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002523 CallGoneSoon()
2524 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002525 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002526 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2527 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002528enddef
2529
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002530func Test_free_dict_while_in_funcstack()
2531 " relies on the sleep command
2532 CheckUnix
2533 call Run_Test_free_dict_while_in_funcstack()
2534endfunc
2535
2536def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002537 # this was freeing the TermRun() default argument dictionary while it was
2538 # still referenced in a funcstack_T
2539 var lines =<< trim END
2540 vim9script
2541
2542 &updatetime = 400
2543 def TermRun(_ = {})
2544 def Post()
2545 enddef
2546 def Exec()
2547 term_start('sleep 1', {
2548 term_finish: 'close',
2549 exit_cb: (_, _) => Post(),
2550 })
2551 enddef
2552 Exec()
2553 enddef
2554 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2555 timer_start(100, (_) => feedkeys("\<F4>"))
2556 timer_start(1000, (_) => feedkeys("\<F4>"))
2557 sleep 1500m
2558 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002559 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002560 nunmap <F4>
2561 set updatetime&
2562enddef
2563
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002564def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002565 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002566 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002567 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002568 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002569 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002570 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002571 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002572 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002573 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002574
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002575 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002576 g:Func1()->assert_equal('Func1')
2577 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002578
2579 delfunc! Func0
2580 delfunc! Func1
2581 delfunc! Func2
2582enddef
2583
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002584def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002585 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002586 vim9script
2587 func Func(arg)
2588 echo a:arg
2589 endfunc
2590 Func('text')
2591 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002592 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002593 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002594enddef
2595
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002596let s:funcResult = 0
2597
2598def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002599 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002600enddef
2601
2602def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002603 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002604 return 1234
2605enddef
2606
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002607def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002608 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002609 return 'text'
2610enddef
2611
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002612def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002613 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002614enddef
2615
2616def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002617 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002618 return arg
2619enddef
2620
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002621def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002622 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002623enddef
2624
Bram Moolenaar62aec932022-01-29 21:45:34 +00002625def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002626 return arg
2627enddef
2628
Bram Moolenaar62aec932022-01-29 21:45:34 +00002629def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002630 return arg
2631enddef
2632
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002633def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002634 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002635 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002636 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002637 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002638 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002639
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002640 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002641 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002642 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002643 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002644 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002645
Bram Moolenaar53900992020-08-22 19:02:02 +02002646 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002647 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002648 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002649 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002650
Bram Moolenaar53900992020-08-22 19:02:02 +02002651 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002652 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002653 Ref2()->assert_equal(1234)
2654 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002655
Bram Moolenaar53900992020-08-22 19:02:02 +02002656 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002657 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002658 Ref2(13)->assert_equal(13)
2659 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002660enddef
2661
Bram Moolenaar9978d472020-07-05 16:01:56 +02002662def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002663 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002664 for n in repeat([1], 3)
2665 res += n
2666 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002667 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002668
2669 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002670 for n in repeat(0z01, 3)->blob2list()
2671 res += n
2672 endfor
2673 res->assert_equal(3)
2674
2675 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002676 for n in add([1, 2], 3)
2677 res += n
2678 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002679 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002680enddef
2681
Bram Moolenaar846178a2020-07-05 17:04:13 +02002682def Test_argv_return_type()
2683 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002684 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002685 for name in argv()
2686 res ..= name
2687 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002688 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002689enddef
2690
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002691def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002692 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002693 RefVoid = g:FuncNoArgNoRet
2694 RefVoid = g:FuncOneArgNoRet
2695 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 +00002696 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 +02002697
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002698 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002699 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002700 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002701 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2702 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 +02002703
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002704 var RefAnyNoArgs: func: any = RefAny
2705
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002706 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002707 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002708 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002709 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 +00002710 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 +02002711
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002712 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002713 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002714 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002715 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2716 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 +02002717enddef
2718
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002719def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002720 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002721
Bram Moolenaar62aec932022-01-29 21:45:34 +00002722 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2723 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002724 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 +00002725 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2726 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
2727 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 +02002728
Bram Moolenaar62aec932022-01-29 21:45:34 +00002729 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2730 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2731 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:')
2732 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002733enddef
2734
Bram Moolenaar89228602020-04-05 22:14:54 +02002735def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002736 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002737 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002738 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002739
2740 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002741 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002742
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002743 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002744 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002745 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002746
Bram Moolenaar62aec932022-01-29 21:45:34 +00002747 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002748enddef
2749
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002750def Test_func_common_type()
2751 def FuncOne(n: number): number
2752 return n
2753 enddef
2754 def FuncTwo(s: string): number
2755 return len(s)
2756 enddef
2757 def FuncThree(n: number, s: string): number
2758 return n + len(s)
2759 enddef
2760 var list = [FuncOne, FuncTwo, FuncThree]
2761 assert_equal(8, list[0](8))
2762 assert_equal(4, list[1]('word'))
2763 assert_equal(7, list[2](3, 'word'))
2764enddef
2765
Bram Moolenaar62aec932022-01-29 21:45:34 +00002766def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002767 arg1: string,
2768 arg2 = 1234,
2769 ...rest: list<string>
2770 ): string
2771 return arg1 .. arg2 .. join(rest, '-')
2772enddef
2773
Bram Moolenaar2c330432020-04-13 14:41:35 +02002774def MultiLineComment(
2775 arg1: string, # comment
2776 arg2 = 1234, # comment
2777 ...rest: list<string> # comment
2778 ): string # comment
2779 return arg1 .. arg2 .. join(rest, '-')
2780enddef
2781
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002782def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002783 MultiLine('text')->assert_equal('text1234')
2784 MultiLine('text', 777)->assert_equal('text777')
2785 MultiLine('text', 777, 'one')->assert_equal('text777one')
2786 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002787enddef
2788
Bram Moolenaar23e03252020-04-12 22:22:31 +02002789func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002790 call s:MultiLine('text')->assert_equal('text1234')
2791 call s:MultiLine('text', 777)->assert_equal('text777')
2792 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2793 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002794endfunc
2795
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002796
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002797" When using CheckScriptFailure() for the below test, E1010 is generated instead
2798" of E1056.
2799func Test_E1056_1059()
2800 let caught_1056 = 0
2801 try
2802 def F():
2803 return 1
2804 enddef
2805 catch /E1056:/
2806 let caught_1056 = 1
2807 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002808 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002809
2810 let caught_1059 = 0
2811 try
2812 def F5(items : list)
2813 echo 'a'
2814 enddef
2815 catch /E1059:/
2816 let caught_1059 = 1
2817 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002818 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002819endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002820
Bram Moolenaar015f4262020-05-05 21:25:22 +02002821func DelMe()
2822 echo 'DelMe'
2823endfunc
2824
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002825def Test_error_reporting()
2826 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002827 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002828 " comment
2829 def Func()
2830 # comment
2831 # comment
2832 invalid
2833 enddef
2834 defcompile
2835 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002836 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002837 try
2838 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002839 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002840 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002841 v:exception->assert_match('Invalid command: invalid')
2842 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002843 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002844 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002845
2846 # comment lines after the start of the function
2847 lines =<< trim END
2848 " comment
2849 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002850 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002851 # comment
2852 # comment
2853 invalid
2854 enddef
2855 defcompile
2856 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002857 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002858 try
2859 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002860 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002861 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002862 v:exception->assert_match('Invalid command: invalid')
2863 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002864 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002865 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002866
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002867 lines =<< trim END
2868 vim9script
2869 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002870 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002871 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002872 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002873 enddef
2874 defcompile
2875 Func()
2876 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002877 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002878 try
2879 source Xdef
2880 assert_report('should have failed')
2881 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002882 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002883 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002884 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002885enddef
2886
Bram Moolenaar015f4262020-05-05 21:25:22 +02002887def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002888 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002889 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002890 'delfunc g:DelMe',
2891 'echo RefMe()'], 'E117:')
2892enddef
2893
2894def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002895 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002896 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002897 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002898enddef
2899
Bram Moolenaar62aec932022-01-29 21:45:34 +00002900def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002901 return Ref('more')
2902enddef
2903
2904def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002905 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002906 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002907enddef
2908
Bram Moolenaar62aec932022-01-29 21:45:34 +00002909def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002910 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002911 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002912enddef
2913
2914def Test_closure_ref_after_return()
2915 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002916 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002917 unlet g:Ref
2918enddef
2919
Bram Moolenaar62aec932022-01-29 21:45:34 +00002920def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002921 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002922 g:Extend = (s) => local->add(s)
2923 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002924enddef
2925
2926def Test_closure_two_refs()
2927 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002928 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002929 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002930 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002931 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002932 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002933
2934 unlet g:Extend
2935 unlet g:Read
2936enddef
2937
Bram Moolenaar62aec932022-01-29 21:45:34 +00002938def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002939 return join(Ref(), ' ')
2940enddef
2941
Bram Moolenaar62aec932022-01-29 21:45:34 +00002942def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002943 Ref(add)
2944enddef
2945
2946def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002947 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002948 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002949 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002950 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002951 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002952 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002953
2954 unlet g:Extend
2955 unlet g:Read
2956enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002957
Bram Moolenaar62aec932022-01-29 21:45:34 +00002958def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002959 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002960 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002961enddef
2962
Bram Moolenaar62aec932022-01-29 21:45:34 +00002963def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002964 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002965 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002966enddef
2967
2968def Test_closure_using_argument()
2969 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002970 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002971
2972 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002973 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002974
2975 unlet g:UseArg
2976 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01002977
2978 var lines =<< trim END
2979 vim9script
2980 def Test(Fun: func(number): number): list<number>
2981 return map([1, 2, 3], (_, i) => Fun(i))
2982 enddef
2983 def Inc(nr: number): number
2984 return nr + 2
2985 enddef
2986 assert_equal([3, 4, 5], Test(Inc))
2987 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002988 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002989enddef
2990
Bram Moolenaar62aec932022-01-29 21:45:34 +00002991def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02002992 var local = 'a'
2993
2994 def Append(arg: string)
2995 local ..= arg
2996 enddef
2997 g:Append = Append
2998
2999 def Get(): string
3000 return local
3001 enddef
3002 g:Get = Get
3003enddef
3004
3005def Test_closure_append_get()
3006 MakeGetAndAppendRefs()
3007 g:Get()->assert_equal('a')
3008 g:Append('-b')
3009 g:Get()->assert_equal('a-b')
3010 g:Append('-c')
3011 g:Get()->assert_equal('a-b-c')
3012
3013 unlet g:Append
3014 unlet g:Get
3015enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003016
Bram Moolenaar04b12692020-05-04 23:24:44 +02003017def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003018 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003019 def Closure(arg: string): string
3020 return local .. arg
3021 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003022 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003023enddef
3024
Bram Moolenaar62aec932022-01-29 21:45:34 +00003025func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003026 return a:Ref('some')
3027endfunc
3028
3029def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003030 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003031 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003032 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003033enddef
3034
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003035def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003036 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003037 vim9script
3038 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003039 var name = 0
3040 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003041 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003042 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003043 enddef
3044 Func()
3045 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003046 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003047enddef
3048
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003049def Test_nested_closure_used()
3050 var lines =<< trim END
3051 vim9script
3052 def Func()
3053 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003054 var Closure = () => x
3055 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003056 enddef
3057 Func()
3058 assert_equal('hello', g:Myclosure())
3059 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003060 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003061enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003062
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003063def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003064 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003065 vim9script
3066 def FuncA()
3067 FuncB(0)
3068 enddef
3069 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003070 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003071 enddef
3072 FuncA()
3073 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003074 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003075enddef
3076
Bram Moolenaar6de22962022-09-09 21:35:36 +01003077def Run_Test_closure_in_for_loop_fails()
3078 var lines =<< trim END
3079 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003080 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003081 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003082 # time should be enough for startup to finish
3083 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003084 echo n
3085 })
3086 endfor
3087 END
3088 writefile(lines, 'XTest_closure_fails', 'D')
3089
3090 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003091 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003092 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003093
3094 # clean up
3095 g:StopVimInTerminal(buf)
3096enddef
3097
3098func Test_closure_in_for_loop_fails()
3099 CheckScreendump
3100 call Run_Test_closure_in_for_loop_fails()
3101endfunc
3102
Bram Moolenaarf112f302020-12-20 17:47:52 +01003103def Test_global_closure()
3104 var lines =<< trim END
3105 vim9script
3106 def ReverseEveryNLines(n: number, line1: number, line2: number)
3107 var mods = 'sil keepj keepp lockm '
3108 var range = ':' .. line1 .. ',' .. line2
3109 def g:Offset(): number
3110 var offset = (line('.') - line1 + 1) % n
3111 return offset != 0 ? offset : n
3112 enddef
3113 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3114 enddef
3115
3116 new
3117 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3118 ReverseEveryNLines(3, 1, 9)
3119 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003120 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003121 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3122 assert_equal(expected, getline(1, 9))
3123 bwipe!
3124enddef
3125
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003126def Test_global_closure_called_directly()
3127 var lines =<< trim END
3128 vim9script
3129 def Outer()
3130 var x = 1
3131 def g:Inner()
3132 var y = x
3133 x += 1
3134 assert_equal(1, y)
3135 enddef
3136 g:Inner()
3137 assert_equal(2, x)
3138 enddef
3139 Outer()
3140 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003141 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003142 delfunc g:Inner
3143enddef
3144
Bram Moolenaar69c76172021-12-02 16:38:52 +00003145def Test_closure_called_from_legacy()
3146 var lines =<< trim END
3147 vim9script
3148 def Func()
3149 var outer = 'foo'
3150 var F = () => {
3151 outer = 'bar'
3152 }
3153 execute printf('call %s()', string(F))
3154 enddef
3155 Func()
3156 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003157 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003158enddef
3159
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003160def Test_failure_in_called_function()
3161 # this was using the frame index as the return value
3162 var lines =<< trim END
3163 vim9script
3164 au TerminalWinOpen * eval [][0]
3165 def PopupTerm(a: any)
3166 # make sure typvals on stack are string
3167 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3168 FireEvent()
3169 enddef
3170 def FireEvent()
3171 do TerminalWinOpen
3172 enddef
3173 # use try/catch to make eval fail
3174 try
3175 call PopupTerm(0)
3176 catch
3177 endtry
3178 au! TerminalWinOpen
3179 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003180 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003181enddef
3182
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003183def Test_nested_lambda()
3184 var lines =<< trim END
3185 vim9script
3186 def Func()
3187 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003188 var Lambda1 = () => 7
3189 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003190 var res = Lambda2()
3191 assert_equal([7, 4], res)
3192 enddef
3193 Func()
3194 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003195 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003196enddef
3197
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003198def Test_double_nested_lambda()
3199 var lines =<< trim END
3200 vim9script
3201 def F(head: string): func(string): func(string): string
3202 return (sep: string): func(string): string => ((tail: string): string => {
3203 return head .. sep .. tail
3204 })
3205 enddef
3206 assert_equal('hello-there', F('hello')('-')('there'))
3207 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003208 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003209enddef
3210
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003211def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003212 var lines =<< trim END
3213 vim9script
3214 def F(text: string): func(string): func(string): string
3215 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003216 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003217 })
3218 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003219 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003220 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003221 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003222
3223 lines =<< trim END
3224 vim9script
3225 echo range(4)->mapnew((_, v) => {
3226 return range(v) ->mapnew((_, s) => {
3227 return string(s)
3228 })
3229 })
3230 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003231 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003232
3233 lines =<< trim END
3234 vim9script
3235
Bram Moolenaara749a422022-02-12 19:52:25 +00003236 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003237 range(10)
3238 ->mapnew((_, _) => ({
3239 key: range(10)->mapnew((_, _) => {
3240 return ' '
3241 }),
3242 }))
3243 enddef
3244
3245 defcomp
3246 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003247 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003248enddef
3249
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003250def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003251 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003252 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003253enddef
3254
3255def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003256 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003257enddef
3258
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003259def Test_compiling_referenced_func_no_shadow()
3260 var lines =<< trim END
3261 vim9script
3262
3263 def InitializeReply(lspserver: dict<any>)
3264 enddef
3265
3266 def ProcessReply(lspserver: dict<any>)
3267 var lsp_reply_handlers: dict<func> =
3268 { 'initialize': InitializeReply }
3269 lsp_reply_handlers['initialize'](lspserver)
3270 enddef
3271
3272 call ProcessReply({})
3273 END
3274 v9.CheckScriptSuccess(lines)
3275enddef
3276
Bram Moolenaar62aec932022-01-29 21:45:34 +00003277def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003278 var path: string = empty(dir)
3279 \ ? 'empty'
3280 \ : 'full'
3281 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003282enddef
3283
3284def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003285 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003286enddef
3287
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003288def Test_script_var_in_lambda()
3289 var lines =<< trim END
3290 vim9script
3291 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003292 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003293 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003294 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003295enddef
3296
Bram Moolenaar62aec932022-01-29 21:45:34 +00003297def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003298 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003299 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003300 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003301 ->reverse()
3302 return x
3303enddef
3304
3305def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003306 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003307
3308 var lines =<< trim END
3309 vim9script
3310 var res = [{n: 1, m: 2, s: 'xxx'}]
3311 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3312 v.n,
3313 v.m,
3314 substitute(v.s, '.*', 'yyy', '')
3315 ))
3316 assert_equal(['1:2:yyy'], res)
3317 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003318 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003319enddef
3320
Bram Moolenaarb6571982021-01-08 22:24:19 +01003321def Test_list_lambda()
3322 timer_start(1000, (_) => 0)
3323 var body = execute(timer_info()[0].callback
3324 ->string()
3325 ->substitute("('", ' ', '')
3326 ->substitute("')", '', '')
3327 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003328 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003329enddef
3330
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003331def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003332 var lines =<< trim END
3333 vim9script
3334 var flist: list<func>
3335 for i in range(10)
3336 var inloop = i
3337 flist[i] = () => inloop
3338 endfor
3339 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003340 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003341
3342 lines =<< trim END
3343 vim9script
3344 if true
3345 var outloop = 5
3346 var flist: list<func>
3347 for i in range(10)
3348 flist[i] = () => outloop
3349 endfor
3350 endif
3351 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003352 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003353
3354 lines =<< trim END
3355 vim9script
3356 if true
3357 var outloop = 5
3358 endif
3359 var flist: list<func>
3360 for i in range(10)
3361 flist[i] = () => outloop
3362 endfor
3363 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003364 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003365
3366 lines =<< trim END
3367 vim9script
3368 for i in range(10)
3369 var Ref = () => 0
3370 endfor
3371 assert_equal(0, ((i) => 0)(0))
3372 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003373 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003374enddef
3375
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003376def Test_legacy_lambda()
3377 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003378
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003379 var lines =<< trim END
3380 echo {x -> 'hello ' .. x}('foo')
3381 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003382 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003383
3384 lines =<< trim END
3385 vim9script
3386 def Func()
3387 echo (() => 'no error')()
3388 enddef
3389 legacy call s:Func()
3390 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003391 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003392enddef
3393
Bram Moolenaarce024c32021-06-26 13:00:49 +02003394def Test_legacy()
3395 var lines =<< trim END
3396 vim9script
3397 func g:LegacyFunction()
3398 let g:legacyvar = 1
3399 endfunc
3400 def Testit()
3401 legacy call g:LegacyFunction()
3402 enddef
3403 Testit()
3404 assert_equal(1, g:legacyvar)
3405 unlet g:legacyvar
3406 delfunc g:LegacyFunction
3407 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003408 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003409enddef
3410
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003411def Test_legacy_errors()
3412 for cmd in ['if', 'elseif', 'else', 'endif',
3413 'for', 'endfor', 'continue', 'break',
3414 'while', 'endwhile',
3415 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003416 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003417 endfor
3418enddef
3419
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003420def Test_call_legacy_with_dict()
3421 var lines =<< trim END
3422 vim9script
3423 func Legacy() dict
3424 let g:result = self.value
3425 endfunc
3426 def TestDirect()
3427 var d = {value: 'yes', func: Legacy}
3428 d.func()
3429 enddef
3430 TestDirect()
3431 assert_equal('yes', g:result)
3432 unlet g:result
3433
3434 def TestIndirect()
3435 var d = {value: 'foo', func: Legacy}
3436 var Fi = d.func
3437 Fi()
3438 enddef
3439 TestIndirect()
3440 assert_equal('foo', g:result)
3441 unlet g:result
3442
3443 var d = {value: 'bar', func: Legacy}
3444 d.func()
3445 assert_equal('bar', g:result)
3446 unlet g:result
3447 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003448 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003449enddef
3450
Bram Moolenaar62aec932022-01-29 21:45:34 +00003451def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003452 # closure nested inside another closure using argument
3453 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3454 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3455enddef
3456
3457def Test_nested_closure_using_argument()
3458 assert_equal(['x', 'x2'], DoFilterThis('x'))
3459enddef
3460
Bram Moolenaar0186e582021-01-10 18:33:11 +01003461def Test_triple_nested_closure()
3462 var what = 'x'
3463 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3464 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3465 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3466enddef
3467
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003468func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003469 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003470 call Run_Test_silent_echo()
3471endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003472
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003473def Run_Test_silent_echo()
3474 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003475 vim9script
3476 def EchoNothing()
3477 silent echo ''
3478 enddef
3479 defcompile
3480 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003481 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003482
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003483 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003484 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003485 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003486 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003487
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003488 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003489 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003490enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003491
Bram Moolenaar171fb922020-10-28 16:54:47 +01003492def SilentlyError()
3493 execute('silent! invalid')
3494 g:did_it = 'yes'
3495enddef
3496
Bram Moolenaar62aec932022-01-29 21:45:34 +00003497func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003498 silent! invalid
3499endfunc
3500
3501def SilentlyUserError()
3502 UserError()
3503 g:did_it = 'yes'
3504enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003505
3506" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003507func Test_ignore_silent_error()
3508 let g:did_it = 'no'
3509 call SilentlyError()
3510 call assert_equal('yes', g:did_it)
3511
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003512 let g:did_it = 'no'
3513 call SilentlyUserError()
3514 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003515
3516 unlet g:did_it
3517endfunc
3518
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003519def Test_ignore_silent_error_in_filter()
3520 var lines =<< trim END
3521 vim9script
3522 def Filter(winid: number, key: string): bool
3523 if key == 'o'
3524 silent! eval [][0]
3525 return true
3526 endif
3527 return popup_filter_menu(winid, key)
3528 enddef
3529
Bram Moolenaare0de1712020-12-02 17:36:54 +01003530 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003531 feedkeys("o\r", 'xnt')
3532 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003533 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003534enddef
3535
Bram Moolenaar62aec932022-01-29 21:45:34 +00003536def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003537 if n < 2
3538 return n
3539 else
3540 return Fibonacci(n - 1) + Fibonacci(n - 2)
3541 endif
3542enddef
3543
Bram Moolenaar985116a2020-07-12 17:31:09 +02003544def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003545 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003546enddef
3547
Bram Moolenaar62aec932022-01-29 21:45:34 +00003548def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003549 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003550 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003551 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003552 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003553 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003554enddef
3555
3556def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003557 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003558 writefile(['111'], 'XclosureDir/file1')
3559 writefile(['222'], 'XclosureDir/file2')
3560 writefile(['333'], 'XclosureDir/tdir/file3')
3561
Bram Moolenaare0de1712020-12-02 17:36:54 +01003562 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003563enddef
3564
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003565def Test_invalid_function_name()
3566 var lines =<< trim END
3567 vim9script
3568 def s: list<string>
3569 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003570 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003571
3572 lines =<< trim END
3573 vim9script
3574 def g: list<string>
3575 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003576 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003577
3578 lines =<< trim END
3579 vim9script
3580 def <SID>: list<string>
3581 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003582 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003583
3584 lines =<< trim END
3585 vim9script
3586 def F list<string>
3587 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003588 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003589enddef
3590
Bram Moolenaara90afb92020-07-15 22:38:56 +02003591def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003592 var lines =<< trim END
3593 var Xsetlist: func
3594 Xsetlist = function('setloclist', [0])
3595 Xsetlist([], ' ', {title: 'test'})
3596 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003597
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003598 Xsetlist = function('setloclist', [0, [], ' '])
3599 Xsetlist({title: 'test'})
3600 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003601
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003602 Xsetlist = function('setqflist')
3603 Xsetlist([], ' ', {title: 'test'})
3604 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003605
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003606 Xsetlist = function('setqflist', [[], ' '])
3607 Xsetlist({title: 'test'})
3608 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003609
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003610 var Len: func: number = function('len', ['word'])
3611 assert_equal(4, Len())
3612
3613 var RepeatFunc = function('repeat', ['o'])
3614 assert_equal('ooooo', RepeatFunc(5))
3615 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003616 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003617
3618 lines =<< trim END
3619 vim9script
3620 def Foo(Parser: any)
3621 enddef
3622 var Expr: func(dict<any>): dict<any>
3623 const Call = Foo(Expr)
3624 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003625 v9.CheckScriptFailure(lines, 'E1031:')
Bram Moolenaara90afb92020-07-15 22:38:56 +02003626enddef
3627
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003628def Test_partial_double_nested()
3629 var idx = 123
3630 var Get = () => idx
3631 var Ref = function(Get, [])
3632 var RefRef = function(Ref, [])
3633 assert_equal(123, RefRef())
3634enddef
3635
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003636def Test_partial_null_function()
3637 var lines =<< trim END
3638 var d: dict<func> = {f: null_function}
3639 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003640 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003641 END
3642 v9.CheckDefAndScriptSuccess(lines)
3643enddef
3644
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003645def Test_cmd_modifier()
3646 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003647 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003648enddef
3649
3650def Test_restore_modifiers()
3651 # check that when compiling a :def function command modifiers are not messed
3652 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003653 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003654 vim9script
3655 set eventignore=
3656 autocmd QuickFixCmdPost * copen
3657 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003658 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003659 enddef
3660 func Func()
3661 noautocmd call s:AutocmdsDisabled()
3662 let g:ei_after = &eventignore
3663 endfunc
3664 Func()
3665 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003666 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003667 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003668enddef
3669
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003670def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003671 eval 1 + 2
3672 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003673 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003674 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003675enddef
3676
3677def StackBot()
3678 # throw an error
3679 eval [][0]
3680enddef
3681
3682def Test_callstack_def()
3683 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003684 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003685 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003686 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003687 endtry
3688enddef
3689
Bram Moolenaare8211a32020-10-09 22:04:29 +02003690" Re-using spot for variable used in block
3691def Test_block_scoped_var()
3692 var lines =<< trim END
3693 vim9script
3694 def Func()
3695 var x = ['a', 'b', 'c']
3696 if 1
3697 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003698 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003699 endif
3700 var z = x
3701 assert_equal(['x', 'x', 'x'], z)
3702 enddef
3703 Func()
3704 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003705 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003706enddef
3707
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003708def Test_reset_did_emsg()
3709 var lines =<< trim END
3710 @s = 'blah'
3711 au BufWinLeave * #
3712 def Func()
3713 var winid = popup_create('popup', {})
3714 exe '*s'
3715 popup_close(winid)
3716 enddef
3717 Func()
3718 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003719 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003720 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003721enddef
3722
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003723def Test_did_emsg_reset()
3724 # executing an autocommand resets did_emsg, this should not result in a
3725 # builtin function considered failing
3726 var lines =<< trim END
3727 vim9script
3728 au BufWinLeave * #
3729 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003730 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003731 eval [][0]
3732 enddef
3733 nno <F3> <cmd>call <sid>Func()<cr>
3734 feedkeys("\<F3>\e", 'xt')
3735 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003736 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003737 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003738
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003739 nunmap <F3>
3740 au! BufWinLeave
3741enddef
3742
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003743def Test_abort_with_silent_call()
3744 var lines =<< trim END
3745 vim9script
3746 g:result = 'none'
3747 def Func()
3748 g:result += 3
3749 g:result = 'yes'
3750 enddef
3751 # error is silenced, but function aborts on error
3752 silent! Func()
3753 assert_equal('none', g:result)
3754 unlet g:result
3755 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003756 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003757enddef
3758
Bram Moolenaarf665e972020-12-05 19:17:16 +01003759def Test_continues_with_silent_error()
3760 var lines =<< trim END
3761 vim9script
3762 g:result = 'none'
3763 def Func()
3764 silent! g:result += 3
3765 g:result = 'yes'
3766 enddef
3767 # error is silenced, function does not abort
3768 Func()
3769 assert_equal('yes', g:result)
3770 unlet g:result
3771 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003772 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003773enddef
3774
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003775def Test_abort_even_with_silent()
3776 var lines =<< trim END
3777 vim9script
3778 g:result = 'none'
3779 def Func()
3780 eval {-> ''}() .. '' .. {}['X']
3781 g:result = 'yes'
3782 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003783 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003784 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003785 unlet g:result
3786 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003787 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003788enddef
3789
Bram Moolenaarf665e972020-12-05 19:17:16 +01003790def Test_cmdmod_silent_restored()
3791 var lines =<< trim END
3792 vim9script
3793 def Func()
3794 g:result = 'none'
3795 silent! g:result += 3
3796 g:result = 'none'
3797 g:result += 3
3798 enddef
3799 Func()
3800 END
3801 # can't use CheckScriptFailure, it ignores the :silent!
3802 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003803 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003804 var caught = 'no'
3805 try
3806 exe 'source ' .. fname
3807 catch /E1030:/
3808 caught = 'yes'
3809 assert_match('Func, line 4', v:throwpoint)
3810 endtry
3811 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003812enddef
3813
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003814def Test_cmdmod_silent_nested()
3815 var lines =<< trim END
3816 vim9script
3817 var result = ''
3818
3819 def Error()
3820 result ..= 'Eb'
3821 eval [][0]
3822 result ..= 'Ea'
3823 enddef
3824
3825 def Crash()
3826 result ..= 'Cb'
3827 sil! Error()
3828 result ..= 'Ca'
3829 enddef
3830
3831 Crash()
3832 assert_equal('CbEbEaCa', result)
3833 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003834 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003835enddef
3836
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003837def Test_dict_member_with_silent()
3838 var lines =<< trim END
3839 vim9script
3840 g:result = 'none'
3841 var d: dict<any>
3842 def Func()
3843 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003844 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003845 catch
3846 endtry
3847 enddef
3848 silent! Func()
3849 assert_equal('0', g:result)
3850 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003851 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003852 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003853enddef
3854
Bram Moolenaarf9041332021-01-21 19:41:16 +01003855def Test_skip_cmds_with_silent()
3856 var lines =<< trim END
3857 vim9script
3858
3859 def Func(b: bool)
3860 Crash()
3861 enddef
3862
3863 def Crash()
3864 sil! :/not found/d _
3865 sil! :/not found/put _
3866 enddef
3867
3868 Func(true)
3869 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003870 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003871enddef
3872
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003873def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003874 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003875 def g:Opfunc(_: any): string
3876 setline(1, 'ASDF')
3877 return ''
3878 enddef
3879 new
3880 setline(1, 'asdf')
3881 feedkeys("\<F3>$", 'x')
3882 assert_equal('ASDF', getline(1))
3883
3884 bwipe!
3885 nunmap <F3>
3886enddef
3887
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003888func Test_opfunc_error()
3889 CheckScreendump
3890 call Run_Test_opfunc_error()
3891endfunc
3892
3893def Run_Test_opfunc_error()
3894 # test that the error from Opfunc() is displayed right away
3895 var lines =<< trim END
3896 vim9script
3897
3898 def Opfunc(type: string)
3899 try
3900 eval [][0]
3901 catch /nothing/ # error not caught
3902 endtry
3903 enddef
3904 &operatorfunc = Opfunc
3905 nnoremap <expr> l <SID>L()
3906 def L(): string
3907 return 'l'
3908 enddef
3909 'x'->repeat(10)->setline(1)
3910 feedkeys('g@l', 'n')
3911 feedkeys('llll')
3912 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003913 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003914
Bram Moolenaar62aec932022-01-29 21:45:34 +00003915 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3916 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003917 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003918
3919 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003920 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003921enddef
3922
Bram Moolenaar077a4232020-12-22 18:33:27 +01003923" this was crashing on exit
3924def Test_nested_lambda_in_closure()
3925 var lines =<< trim END
3926 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003927 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003928 def Outer()
3929 def g:Inner()
3930 echo map([1, 2, 3], {_, v -> v + 1})
3931 enddef
3932 g:Inner()
3933 enddef
3934 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003935 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003936 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003937 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003938 return
3939 endif
3940 assert_equal(['Done'], readfile('XnestedDone'))
3941 delete('XnestedDone')
3942enddef
3943
Bram Moolenaar92368aa2022-02-07 17:50:39 +00003944def Test_nested_closure_funcref()
3945 var lines =<< trim END
3946 vim9script
3947 def Func()
3948 var n: number
3949 def Nested()
3950 ++n
3951 enddef
3952 Nested()
3953 g:result_one = n
3954 var Ref = function(Nested)
3955 Ref()
3956 g:result_two = n
3957 enddef
3958 Func()
3959 END
3960 v9.CheckScriptSuccess(lines)
3961 assert_equal(1, g:result_one)
3962 assert_equal(2, g:result_two)
3963 unlet g:result_one g:result_two
3964enddef
3965
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00003966def Test_nested_closure_in_dict()
3967 var lines =<< trim END
3968 vim9script
3969 def Func(): dict<any>
3970 var n: number
3971 def Inc(): number
3972 ++n
3973 return n
3974 enddef
3975 return {inc: function(Inc)}
3976 enddef
3977 disas Func
3978 var d = Func()
3979 assert_equal(1, d.inc())
3980 assert_equal(2, d.inc())
3981 END
3982 v9.CheckScriptSuccess(lines)
3983enddef
3984
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003985def Test_script_local_other_script()
3986 var lines =<< trim END
3987 function LegacyJob()
3988 let FuncRef = function('s:close_cb')
3989 endfunction
3990 function s:close_cb(...)
3991 endfunction
3992 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003993 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003994 source Xlegacy.vim
3995 g:LegacyJob()
3996 g:LegacyJob()
3997 g:LegacyJob()
3998
3999 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004000enddef
4001
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004002def Test_check_func_arg_types()
4003 var lines =<< trim END
4004 vim9script
4005 def F1(x: string): string
4006 return x
4007 enddef
4008
4009 def F2(x: number): number
4010 return x + 1
4011 enddef
4012
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004013 def G(Fg: func): dict<func>
4014 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004015 enddef
4016
4017 def H(d: dict<func>): string
4018 return d.f('a')
4019 enddef
4020 END
4021
Bram Moolenaar62aec932022-01-29 21:45:34 +00004022 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4023 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004024
4025 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004026enddef
4027
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004028def Test_call_func_with_null()
4029 var lines =<< trim END
4030 def Fstring(v: string)
4031 assert_equal(null_string, v)
4032 enddef
4033 Fstring(null_string)
4034 def Fblob(v: blob)
4035 assert_equal(null_blob, v)
4036 enddef
4037 Fblob(null_blob)
4038 def Flist(v: list<number>)
4039 assert_equal(null_list, v)
4040 enddef
4041 Flist(null_list)
4042 def Fdict(v: dict<number>)
4043 assert_equal(null_dict, v)
4044 enddef
4045 Fdict(null_dict)
4046 def Ffunc(Fv: func(number): number)
4047 assert_equal(null_function, Fv)
4048 enddef
4049 Ffunc(null_function)
4050 if has('channel')
4051 def Fchannel(v: channel)
4052 assert_equal(null_channel, v)
4053 enddef
4054 Fchannel(null_channel)
4055 def Fjob(v: job)
4056 assert_equal(null_job, v)
4057 enddef
4058 Fjob(null_job)
4059 endif
4060 END
4061 v9.CheckDefAndScriptSuccess(lines)
4062enddef
4063
4064def Test_null_default_argument()
4065 var lines =<< trim END
4066 def Fstring(v: string = null_string)
4067 assert_equal(null_string, v)
4068 enddef
4069 Fstring()
4070 def Fblob(v: blob = null_blob)
4071 assert_equal(null_blob, v)
4072 enddef
4073 Fblob()
4074 def Flist(v: list<number> = null_list)
4075 assert_equal(null_list, v)
4076 enddef
4077 Flist()
4078 def Fdict(v: dict<number> = null_dict)
4079 assert_equal(null_dict, v)
4080 enddef
4081 Fdict()
4082 def Ffunc(Fv: func(number): number = null_function)
4083 assert_equal(null_function, Fv)
4084 enddef
4085 Ffunc()
4086 if has('channel')
4087 def Fchannel(v: channel = null_channel)
4088 assert_equal(null_channel, v)
4089 enddef
4090 Fchannel()
4091 def Fjob(v: job = null_job)
4092 assert_equal(null_job, v)
4093 enddef
4094 Fjob()
4095 endif
4096 END
4097 v9.CheckDefAndScriptSuccess(lines)
4098enddef
4099
4100def Test_null_return()
4101 var lines =<< trim END
4102 def Fstring(): string
4103 return null_string
4104 enddef
4105 assert_equal(null_string, Fstring())
4106 def Fblob(): blob
4107 return null_blob
4108 enddef
4109 assert_equal(null_blob, Fblob())
4110 def Flist(): list<number>
4111 return null_list
4112 enddef
4113 assert_equal(null_list, Flist())
4114 def Fdict(): dict<number>
4115 return null_dict
4116 enddef
4117 assert_equal(null_dict, Fdict())
4118 def Ffunc(): func(number): number
4119 return null_function
4120 enddef
4121 assert_equal(null_function, Ffunc())
4122 if has('channel')
4123 def Fchannel(): channel
4124 return null_channel
4125 enddef
4126 assert_equal(null_channel, Fchannel())
4127 def Fjob(): job
4128 return null_job
4129 enddef
4130 assert_equal(null_job, Fjob())
4131 endif
4132 END
4133 v9.CheckDefAndScriptSuccess(lines)
4134enddef
4135
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004136def Test_list_any_type_checked()
4137 var lines =<< trim END
4138 vim9script
4139 def Foo()
4140 --decl--
4141 Bar(l)
4142 enddef
4143 def Bar(ll: list<dict<any>>)
4144 enddef
4145 Foo()
4146 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004147 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004148 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004149 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004150 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004151 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004152
4153 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004154 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004155enddef
4156
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004157def Test_compile_error()
4158 var lines =<< trim END
4159 def g:Broken()
4160 echo 'a' + {}
4161 enddef
4162 call g:Broken()
4163 END
4164 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004165 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004166
4167 # Second call won't try compiling again
4168 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004169 delfunc g:Broken
4170
4171 # No error when compiling with :silent!
4172 lines =<< trim END
4173 def g:Broken()
4174 echo 'a' + []
4175 enddef
4176 silent! defcompile
4177 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004178 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004179
4180 # Calling the function won't try compiling again
4181 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4182 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004183enddef
4184
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004185def Test_ignored_argument()
4186 var lines =<< trim END
4187 vim9script
4188 def Ignore(_, _): string
4189 return 'yes'
4190 enddef
4191 assert_equal('yes', Ignore(1, 2))
4192
4193 func Ok(_)
4194 return a:_
4195 endfunc
4196 assert_equal('ok', Ok('ok'))
4197
4198 func Oktoo()
4199 let _ = 'too'
4200 return _
4201 endfunc
4202 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004203
4204 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004205 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004206 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004207
4208 lines =<< trim END
4209 def Ignore(_: string): string
4210 return _
4211 enddef
4212 defcompile
4213 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004214 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004215
4216 lines =<< trim END
4217 var _ = 1
4218 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004219 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004220
4221 lines =<< trim END
4222 var x = _
4223 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004224 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004225enddef
4226
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004227def Test_too_many_arguments()
4228 var lines =<< trim END
4229 echo [0, 1, 2]->map(() => 123)
4230 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004231 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004232
4233 lines =<< trim END
4234 echo [0, 1, 2]->map((_) => 123)
4235 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004236 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004237
4238 lines =<< trim END
4239 vim9script
4240 def OneArgument(arg: string)
4241 echo arg
4242 enddef
4243 var Ref = OneArgument
4244 Ref('a', 'b')
4245 END
4246 v9.CheckScriptFailure(lines, 'E118:')
4247enddef
4248
4249def Test_funcref_with_base()
4250 var lines =<< trim END
4251 vim9script
4252 def TwoArguments(str: string, nr: number)
4253 echo str nr
4254 enddef
4255 var Ref = TwoArguments
4256 Ref('a', 12)
4257 'b'->Ref(34)
4258 END
4259 v9.CheckScriptSuccess(lines)
4260
4261 lines =<< trim END
4262 vim9script
4263 def TwoArguments(str: string, nr: number)
4264 echo str nr
4265 enddef
4266 var Ref = TwoArguments
4267 'a'->Ref('b')
4268 END
4269 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4270
4271 lines =<< trim END
4272 vim9script
4273 def TwoArguments(str: string, nr: number)
4274 echo str nr
4275 enddef
4276 var Ref = TwoArguments
4277 123->Ref(456)
4278 END
4279 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4280
4281 lines =<< trim END
4282 vim9script
4283 def TwoArguments(nr: number, str: string)
4284 echo str nr
4285 enddef
4286 var Ref = TwoArguments
4287 123->Ref('b')
4288 def AndNowCompiled()
4289 456->Ref('x')
4290 enddef
4291 AndNowCompiled()
4292 END
4293 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004294enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004295
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004296def Test_closing_brace_at_start_of_line()
4297 var lines =<< trim END
4298 def Func()
4299 enddef
4300 Func(
4301 )
4302 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004303 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004304enddef
4305
Bram Moolenaar62aec932022-01-29 21:45:34 +00004306func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004307 let g:mydict = {}
4308 func g:mydict.afunc()
4309 let g:result = self.key
4310 endfunc
4311endfunc
4312
4313def Test_numbered_function_reference()
4314 CreateMydict()
4315 var output = execute('legacy func g:mydict.afunc')
4316 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4317 execute 'function(' .. funcName .. ', [], {key: 42})()'
4318 # check that the function still exists
4319 assert_equal(output, execute('legacy func g:mydict.afunc'))
4320 unlet g:mydict
4321enddef
4322
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004323def Test_numbered_function_call()
4324 var lines =<< trim END
4325 let s:legacyscript = {}
4326 func s:legacyscript.Helper() abort
4327 return "Success"
4328 endfunc
4329 let g:legacyscript = deepcopy(s:legacyscript)
4330
4331 let g:legacy_result = eval("g:legacyscript.Helper()")
4332 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4333 END
4334 v9.CheckScriptSuccess(lines)
4335 assert_equal('Success', g:legacy_result)
4336 assert_equal('Success', g:vim9_result)
4337
4338 unlet g:legacy_result
4339 unlet g:vim9_result
4340enddef
4341
Bram Moolenaard3a11782022-01-05 16:50:40 +00004342def Test_go_beyond_end_of_cmd()
4343 # this was reading the byte after the end of the line
4344 var lines =<< trim END
4345 def F()
4346 cal
4347 enddef
4348 defcompile
4349 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004350 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004351enddef
4352
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004353" Test for memory allocation failure when defining a new lambda
4354func Test_lambda_allocation_failure()
4355 new
4356 let lines =<< trim END
4357 vim9script
4358 g:Xlambda = (x): number => {
4359 return x + 1
4360 }
4361 END
4362 call setline(1, lines)
4363 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4364 call assert_fails('source', 'E342:')
4365 call assert_false(exists('g:Xlambda'))
4366 bw!
4367endfunc
4368
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004369def Test_lambda_argument_type_check()
4370 var lines =<< trim END
4371 vim9script
4372
4373 def Scan(ll: list<any>): func(func(any))
4374 return (Emit: func(any)) => {
4375 for e in ll
4376 Emit(e)
4377 endfor
4378 }
4379 enddef
4380
4381 def Sum(Cont: func(func(any))): any
4382 var sum = 0.0
4383 Cont((v: float) => { # <== NOTE: the lambda expects a float
4384 sum += v
4385 })
4386 return sum
4387 enddef
4388
Bram Moolenaar47bba532023-01-20 18:49:46 +00004389 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004390 echo Scan(ml)->Sum()
4391 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004392 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004393enddef
4394
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004395def Test_multiple_funcref()
4396 # This was using a NULL pointer
4397 var lines =<< trim END
4398 vim9script
4399 def A(F: func, ...args: list<any>): func
4400 return funcref(F, args)
4401 enddef
4402
4403 def B(F: func): func
4404 return funcref(A, [F])
4405 enddef
4406
4407 def Test(n: number)
4408 enddef
4409
4410 const X = B(Test)
4411 X(1)
4412 END
4413 v9.CheckScriptSuccess(lines)
4414
4415 # slightly different case
4416 lines =<< trim END
4417 vim9script
4418
4419 def A(F: func, ...args: list<any>): any
4420 return call(F, args)
4421 enddef
4422
4423 def B(F: func): func
4424 return funcref(A, [F])
4425 enddef
4426
4427 def Test(n: number)
4428 enddef
4429
4430 const X = B(Test)
4431 X(1)
4432 END
4433 v9.CheckScriptSuccess(lines)
4434enddef
4435
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004436def Test_cexpr_errmsg_line_number()
4437 var lines =<< trim END
4438 vim9script
4439 def Func()
4440 var qfl = {}
4441 cexpr qfl
4442 enddef
4443 Func()
4444 END
4445 v9.CheckScriptFailure(lines, 'E777', 2)
4446enddef
4447
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004448def AddDefer(s: string)
4449 g:deferred->extend([s])
4450enddef
4451
4452def DeferTwo()
4453 g:deferred->extend(['in Two'])
4454 for n in range(3)
4455 defer g:AddDefer('two' .. n)
4456 endfor
4457 g:deferred->extend(['end Two'])
4458enddef
4459
4460def DeferOne()
4461 g:deferred->extend(['in One'])
4462 defer g:AddDefer('one')
4463 g:DeferTwo()
4464 g:deferred->extend(['end One'])
4465
4466 writefile(['text'], 'XdeferFile')
4467 defer delete('XdeferFile')
4468enddef
4469
4470def Test_defer()
4471 g:deferred = []
4472 g:DeferOne()
4473 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4474 unlet g:deferred
4475 assert_equal('', glob('XdeferFile'))
4476enddef
4477
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004478def Test_invalid_redir()
4479 var lines =<< trim END
4480 def Tone()
4481 if 1
4482 redi =>@�0
4483 redi END
4484 endif
4485 enddef
4486 defcompile
4487 END
4488 v9.CheckScriptFailure(lines, 'E354:')
4489 delfunc g:Tone
4490
4491 # this was reading past the end of the line
4492 lines =<< trim END
4493 def Ttwo()
4494 if 0
4495 redi =>@�0
4496 redi END
4497 endif
4498 enddef
4499 defcompile
4500 END
4501 v9.CheckScriptFailure(lines, 'E354:')
4502 delfunc g:Ttwo
4503enddef
4504
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004505func Test_keytyped_in_nested_function()
4506 CheckRunVimInTerminal
4507
4508 call Run_Test_keytyped_in_nested_function()
4509endfunc
4510
4511def Run_Test_keytyped_in_nested_function()
4512 var lines =<< trim END
4513 vim9script
4514 autocmd CmdlineEnter * sample#Init()
4515
4516 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4517 END
4518 writefile(lines, 'Xkeytyped', 'D')
4519
4520 var dir = 'Xrtpdir/autoload'
4521 mkdir(dir, 'pR')
4522
4523 lines =<< trim END
4524 vim9script
4525 export def Init(): void
4526 cnoremap <expr>" <SID>Quote('"')
4527 enddef
4528 def Quote(str: string): string
4529 def InPair(): number
4530 return 0
4531 enddef
4532 return str
4533 enddef
4534 END
4535 writefile(lines, dir .. '/sample.vim')
4536
4537 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4538
4539 term_sendkeys(buf, ':"')
4540 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4541
4542 # clean up
4543 term_sendkeys(buf, "\<Esc>")
4544 g:StopVimInTerminal(buf)
4545enddef
4546
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004547" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004548if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004549 def Test_python3_command()
4550 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004551 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004552 assert_equal('yes', g:done)
4553 unlet g:done
4554 enddef
4555
Bram Moolenaar20677332021-06-06 17:02:53 +02004556 def Test_python3_heredoc()
4557 py3 << trim EOF
4558 import vim
4559 vim.vars['didit'] = 'yes'
4560 EOF
4561 assert_equal('yes', g:didit)
4562
4563 python3 << trim EOF
4564 import vim
4565 vim.vars['didit'] = 'again'
4566 EOF
4567 assert_equal('again', g:didit)
4568 enddef
4569endif
4570
Bram Moolenaar20677332021-06-06 17:02:53 +02004571if has('lua')
4572 def Test_lua_heredoc()
4573 g:d = {}
4574 lua << trim EOF
4575 x = vim.eval('g:d')
4576 x['key'] = 'val'
4577 EOF
4578 assert_equal('val', g:d.key)
4579 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004580
4581 def Test_lua_heredoc_fails()
4582 var lines = [
4583 'vim9script',
4584 'def ExeLua()',
4585 'lua << trim EOLUA',
4586 "x = vim.eval('g:nodict')",
4587 'EOLUA',
4588 'enddef',
4589 'ExeLua()',
4590 ]
4591 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4592 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004593endif
4594
Bram Moolenaard881d152022-05-13 13:50:36 +01004595if has('perl')
4596 def Test_perl_heredoc_nested()
4597 var lines =<< trim END
4598 vim9script
4599 def F(): string
4600 def G(): string
4601 perl << EOF
4602 EOF
4603 return 'done'
4604 enddef
4605 return G()
4606 enddef
4607 assert_equal('done', F())
4608 END
4609 v9.CheckScriptSuccess(lines)
4610 enddef
4611endif
4612
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004613
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004614" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker