blob: 2965afac8fa3bd4e600c669e2c21100a1a06853f [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 Moolenaar403dc312020-10-17 19:29:51 +0200491def Test_return_bool()
492 var lines =<< trim END
493 vim9script
494 def MenuFilter(id: number, key: string): bool
495 return popup_filter_menu(id, key)
496 enddef
497 def YesnoFilter(id: number, key: string): bool
498 return popup_filter_yesno(id, key)
499 enddef
500 defcompile
501 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000502 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200503enddef
504
mityu500c4442022-12-02 18:12:05 +0000505def Test_return_void_comment_follows()
506 var lines =<< trim END
507 vim9script
508 def ReturnCommentFollows(): void
509 return # Some comment
510 enddef
511 defcompile
512 END
513 v9.CheckScriptSuccess(lines)
514enddef
515
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200516let s:nothing = 0
517def ReturnNothing()
518 s:nothing = 1
519 if true
520 return
521 endif
522 s:nothing = 2
523enddef
524
525def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000526 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200527 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200528enddef
529
Bram Moolenaar648ea762021-01-15 19:04:32 +0100530def Test_return_invalid()
531 var lines =<< trim END
532 vim9script
533 def Func(): invalid
534 return xxx
535 enddef
536 defcompile
537 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000538 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100539
540 lines =<< trim END
541 vim9script
542 def Test(Fun: func(number): number): list<number>
543 return map([1, 2, 3], (_, i) => Fun(i))
544 enddef
545 defcompile
546 def Inc(nr: number): nr
547 return nr + 2
548 enddef
549 echo Test(Inc)
550 END
551 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000552 v9.CheckScriptFailure(lines, 'E1010:')
553 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100554enddef
555
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200556def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000557 # This used to fail but now the actual list type is checked, and since it has
558 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200559 var lines =<< trim END
560 vim9script
561 def Func(): list<string>
562 var l: list<any>
563 l->add('string')
564 return l
565 enddef
566 echo Func()
567 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000568 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000569
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200570 lines =<< trim END
571 vim9script
572 def Func(): list<string>
573 var l: list<any>
574 l += ['string']
575 return l
576 enddef
577 echo Func()
578 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000579 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200580enddef
581
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000582def Test_return_any_two_types()
583 var lines =<< trim END
584 vim9script
585
586 def G(Fn: func(string): any)
587 g:result = Fn("hello")
588 enddef
589
590 def F(a: number, b: string): any
591 echo b
592 if a > 0
593 return 1
594 else
595 return []
596 endif
597 enddef
598
599 G(function(F, [1]))
600 END
601 v9.CheckScriptSuccess(lines)
602 assert_equal(1, g:result)
603 unlet g:result
604enddef
605
Bram Moolenaar62aec932022-01-29 21:45:34 +0000606func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200607 let g:counter += 1
608endfunc
609
610def Test_call_ufunc_count()
611 g:counter = 1
612 Increment()
613 Increment()
614 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200615 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200616 g:counter->assert_equal(4)
617 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200618 unlet g:counter
619enddef
620
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000621def Test_call_ufunc_failure()
622 var lines =<< trim END
623 vim9script
624 def Tryit()
625 g:Global(1, 2, 3)
626 enddef
627
628 func g:Global(a, b, c)
629 echo a:a a:b a:c
630 endfunc
631
632 defcompile
633
634 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000635 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000636 endfunc
637 Tryit()
638 END
639 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
640 delfunc g:Global
641
642 lines =<< trim END
643 vim9script
644
645 g:Ref = function('len')
646 def Tryit()
647 g:Ref('x')
648 enddef
649
650 defcompile
651
652 g:Ref = function('add')
653 Tryit()
654 END
655 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
656 unlet g:Ref
657enddef
658
Bram Moolenaar62aec932022-01-29 21:45:34 +0000659def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200660 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200661 for s in rest
662 res ..= ',' .. s
663 endfor
664 return res
665enddef
666
667def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200668 MyVarargs('one')->assert_equal('one')
669 MyVarargs('one', 'two')->assert_equal('one,two')
670 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200671enddef
672
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200673def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000674 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200675enddef
676
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200677def MyDefaultArgs(name = 'string'): string
678 return name
679enddef
680
Bram Moolenaar62aec932022-01-29 21:45:34 +0000681def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200682 return second ? name : 'none'
683enddef
684
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200685
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200686def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000687 g:MyDefaultArgs()->assert_equal('string')
688 g:MyDefaultArgs(v:none)->assert_equal('string')
689 g:MyDefaultArgs('one')->assert_equal('one')
690 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200691
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200692 MyDefaultSecond('test')->assert_equal('test')
693 MyDefaultSecond('test', true)->assert_equal('test')
694 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200695
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200696 var lines =<< trim END
697 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
698 return name .. aa .. bb
699 enddef
700
701 MyDefaultThird('->')->assert_equal('->aabb')
702 MyDefaultThird('->', v:none)->assert_equal('->aabb')
703 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
704 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
705 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
706 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
707 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200708
709 def DefArg(mandatory: any, optional = mandatory): string
710 return mandatory .. optional
711 enddef
712 DefArg(1234)->assert_equal('12341234')
713 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200714 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000715 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200716
Bram Moolenaar62aec932022-01-29 21:45:34 +0000717 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100718 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000719 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 +0100720 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000721 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100722
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200723 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100724 vim9script
725 def Func(a = b == 0 ? 1 : 2, b = 0)
726 enddef
727 defcompile
728 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000729 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000730
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000731 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000732 lines =<< trim END
733 vim9script
734 var a: any
735 def Func(arg: string = a)
736 echo arg
737 enddef
738 defcompile
739 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000740 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
741 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000742
743 # using global variable does not require type cast
744 lines =<< trim END
745 vim9script
746 def Func(arg: string = g:str)
747 echo arg
748 enddef
749 g:str = 'works'
750 Func()
751 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000752 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200753enddef
754
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100755def Test_using_vnone_default()
756 var lines =<< trim END
757 vim9script
758
759 def F(a: string = v:none)
760 if a isnot v:none
761 var b = a
762 endif
763 enddef
764 F()
765 END
766 v9.CheckScriptSuccess(lines)
767
768 # TODO: this should give an error for using a missing argument
769 # lines =<< trim END
770 # vim9script
771
772 # def F(a: string = v:none)
773 # var b = a
774 # enddef
775 # F()
776 # END
777 # v9.CheckScriptFailure(lines, 'E99:')
778enddef
779
Bram Moolenaar47bba532023-01-20 18:49:46 +0000780def Test_convert_number_to_float()
781 var lines =<< trim END
782 vim9script
783 def Foo(a: float, b: float): float
784 return a + b
785 enddef
786
787 assert_equal(5.3, Foo(3.3, 2))
788 END
789 v9.CheckScriptSuccess(lines)
790enddef
791
Bram Moolenaar62aec932022-01-29 21:45:34 +0000792def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100793 a: number, #comment
794 b: bool, # comment
795 c: string) #comment
796 assert_equal(4, a)
797 assert_equal(true, b)
798 assert_equal('yes', c)
799enddef
800
801def Test_func_with_comments()
802 FuncWithComment(4, true, 'yes')
803
804 var lines =<< trim END
805 def Func(# comment
806 arg: string)
807 enddef
808 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000809 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100810
811 lines =<< trim END
812 def Func(
813 arg: string# comment
814 )
815 enddef
816 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000817 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100818
819 lines =<< trim END
820 def Func(
821 arg: string
822 )# comment
823 enddef
824 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000825 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100826enddef
827
Bram Moolenaar04b12692020-05-04 23:24:44 +0200828def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000829 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200830 return 'nested ' .. arg
831 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000832 NestedDef(':def')->assert_equal('nested :def')
833
834 func NestedFunc(arg)
835 return 'nested ' .. a:arg
836 endfunc
837 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200838
Bram Moolenaar62aec932022-01-29 21:45:34 +0000839 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
840 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200841
Bram Moolenaar62aec932022-01-29 21:45:34 +0000842 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
843 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200844
Bram Moolenaar54021752020-12-06 18:50:36 +0100845 var lines =<< trim END
846 def Outer()
847 def Inner()
848 # comment
849 enddef
850 def Inner()
851 enddef
852 enddef
853 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000854 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100855
856 lines =<< trim END
857 def Outer()
858 def Inner()
859 # comment
860 enddef
861 def! Inner()
862 enddef
863 enddef
864 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000865 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100866
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000867 lines =<< trim END
868 vim9script
869 def Outer()
870 def Inner()
871 g:result = 'ok'
872 enddef
873 Inner()
874 enddef
875 Outer()
876 Inner()
877 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000878 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000879 assert_equal('ok', g:result)
880 unlet g:result
881
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000882 lines =<< trim END
883 vim9script
884 def Outer()
885 def _Inner()
886 echo 'bad'
887 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000888 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000889 enddef
890 defcompile
891 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000892 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000893
894 lines =<< trim END
895 vim9script
896 def Outer()
897 def g:inner()
898 echo 'bad'
899 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000900 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000901 enddef
902 defcompile
903 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000904 v9.CheckScriptFailure(lines, 'E1267:')
905
906 lines =<< trim END
907 vim9script
908 def g:_Func()
909 echo 'bad'
910 enddef
911 END
912 v9.CheckScriptFailure(lines, 'E1267:')
913
914 lines =<< trim END
915 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000916 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +0000917 echo 'bad'
918 enddef
919 END
920 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000921
Bram Moolenaar54021752020-12-06 18:50:36 +0100922 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +0100923 lines =<< trim END
924 vim9script
925 var thecount = 0
926 if true
927 def Test(): number
928 def TheFunc(): number
929 thecount += 1
930 return thecount
931 enddef
932 return TheFunc()
933 enddef
934 endif
935 defcompile
936 assert_equal(1, Test())
937 assert_equal(2, Test())
938 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000939 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +0100940
941 # also works when "thecount" is inside the "if" block
942 lines =<< trim END
943 vim9script
944 if true
945 var thecount = 0
946 def Test(): number
947 def TheFunc(): number
948 thecount += 1
949 return thecount
950 enddef
951 return TheFunc()
952 enddef
953 endif
954 defcompile
955 assert_equal(1, Test())
956 assert_equal(2, Test())
957 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000958 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200959
Bram Moolenaara915fa02022-03-23 11:29:15 +0000960 # nested function with recursive call
961 lines =<< trim END
962 vim9script
963
964 def MyFunc(): number
965 def Fib(n: number): number
966 if n < 2
967 return 1
968 endif
969 return Fib(n - 2) + Fib(n - 1)
970 enddef
971
972 return Fib(5)
973 enddef
974
975 assert_equal(8, MyFunc())
976 END
977 v9.CheckScriptSuccess(lines)
978
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200979 lines =<< trim END
980 vim9script
981 def Outer()
982 def Inner()
983 echo 'hello'
984 enddef burp
985 enddef
986 defcompile
987 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000988 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200989enddef
990
Bram Moolenaar1889f492022-08-16 19:34:44 +0100991def Test_nested_function_fails()
992 var lines =<< trim END
993 def T()
994 def Func(g: string):string
995 enddef
996 Func()
997 enddef
998 silent! defcompile
999 END
1000 v9.CheckScriptFailure(lines, 'E1069:')
1001enddef
1002
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001003def Test_not_nested_function()
1004 echo printf('%d',
1005 function('len')('xxx'))
1006enddef
1007
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001008func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001009 call MyDefaultArgs()->assert_equal('string')
1010 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001011 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001012endfunc
1013
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001014def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001015 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001016 vim9script
1017 def Outer()
1018 def g:Inner(): string
1019 return 'inner'
1020 enddef
1021 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001022 defcompile
1023 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001024 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001025 delfunc g:Inner
1026 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001027 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001028 delfunc g:Inner
1029 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001030 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001031 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001032 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001033 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001034
1035 lines =<< trim END
1036 vim9script
1037 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001038 func g:Inner()
1039 return 'inner'
1040 endfunc
1041 enddef
1042 defcompile
1043 Outer()
1044 g:Inner()->assert_equal('inner')
1045 delfunc g:Inner
1046 Outer()
1047 g:Inner()->assert_equal('inner')
1048 delfunc g:Inner
1049 Outer()
1050 g:Inner()->assert_equal('inner')
1051 delfunc g:Inner
1052 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001053 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001054
1055 lines =<< trim END
1056 vim9script
1057 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001058 def g:Inner(): string
1059 return 'inner'
1060 enddef
1061 enddef
1062 defcompile
1063 Outer()
1064 Outer()
1065 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001066 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001067 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001068
1069 lines =<< trim END
1070 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001071 def Outer()
1072 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001073 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001074 enddef
1075 g:Inner()
1076 enddef
1077 Outer()
1078 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001079 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001080 delfunc g:Inner
1081
1082 lines =<< trim END
1083 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001084 def Func()
1085 echo 'script'
1086 enddef
1087 def Outer()
1088 def Func()
1089 echo 'inner'
1090 enddef
1091 enddef
1092 defcompile
1093 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001094 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001095
1096 lines =<< trim END
1097 vim9script
1098 def Func()
1099 echo 'script'
1100 enddef
1101 def Func()
1102 echo 'script'
1103 enddef
1104 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001105 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001106enddef
1107
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001108def DefListAll()
1109 def
1110enddef
1111
1112def DefListOne()
1113 def DefListOne
1114enddef
1115
1116def DefListMatches()
1117 def /DefList
1118enddef
1119
1120def Test_nested_def_list()
1121 var funcs = split(execute('call DefListAll()'), "\n")
1122 assert_true(len(funcs) > 10)
1123 assert_true(funcs->index('def DefListAll()') >= 0)
1124
1125 funcs = split(execute('call DefListOne()'), "\n")
1126 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1127
1128 funcs = split(execute('call DefListMatches()'), "\n")
1129 assert_true(len(funcs) >= 3)
1130 assert_true(funcs->index('def DefListAll()') >= 0)
1131 assert_true(funcs->index('def DefListOne()') >= 0)
1132 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001133
1134 var lines =<< trim END
1135 vim9script
1136 def Func()
1137 def +Func+
1138 enddef
1139 defcompile
1140 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001141 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001142enddef
1143
Bram Moolenaare08be092022-02-17 13:08:26 +00001144def Test_global_function_not_found()
1145 var lines =<< trim END
1146 g:Ref = 123
1147 call g:Ref()
1148 END
1149 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1150enddef
1151
Bram Moolenaar333894b2020-08-01 18:53:07 +02001152def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001153 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001154 vim9script
1155 def g:Func(): string
1156 return 'global'
1157 enddef
1158 def Func(): string
1159 return 'local'
1160 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001161 g:Func()->assert_equal('global')
1162 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001163 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001164 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001165 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001166
1167 lines =<< trim END
1168 vim9script
1169 def g:Funcy()
1170 echo 'funcy'
1171 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001172 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001173 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001174 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001175enddef
1176
Bram Moolenaar0f769812020-09-12 18:32:34 +02001177def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001178 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001179 vim9script
1180 def g:Gfunc(): string
1181 return 'global'
1182 enddef
1183 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001184 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001185 return Gfunc('testing')
1186 enddef
1187 g:Gfunc()->assert_equal('global')
1188 AnotherFunc()->assert_equal(7)
1189 delfunc g:Gfunc
1190 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001191 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001192
1193 lines =<< trim END
1194 vim9script
1195 def g:Func(): string
1196 return 'global'
1197 enddef
1198 def AnotherFunc()
1199 g:Func = function('len')
1200 enddef
1201 AnotherFunc()
1202 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001203 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001204 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001205
Bram Moolenaar62aec932022-01-29 21:45:34 +00001206 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001207 lines =<< trim END
1208 vim9script
1209 def g:Func(): string
1210 return 'global'
1211 enddef
1212 def AnotherFunc(): string
1213 return Func()
1214 enddef
1215 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001216 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001217 v9.CheckScriptFailure(lines, 'E117:')
1218 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001219
1220 lines =<< trim END
1221 vim9script
1222 def g:Func(): string
1223 return 'global'
1224 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001225 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001226 delfunc g:Func
1227 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001228 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001229
1230 # This does not shadow "i" which is visible only inside the for loop
1231 lines =<< trim END
1232 vim9script
1233
1234 def Foo(i: number)
1235 echo i
1236 enddef
1237
1238 for i in range(3)
1239 # Foo() is compiled here
1240 Foo(i)
1241 endfor
1242 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001243 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001244enddef
1245
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001246func TakesOneArg(arg)
1247 echo a:arg
1248endfunc
1249
1250def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001251 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1252 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1253 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1254 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001255
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001256 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001257 vim9script
1258 def Func(s: string)
1259 echo s
1260 enddef
1261 Func([])
1262 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001263 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001264
Bram Moolenaar9a015112021-12-31 14:06:45 +00001265 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001266 lines =<< trim END
1267 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001268 var name = 'piet'
1269 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001270 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001271 enddef
1272 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001273 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001274
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001275 # same, inside the same block
1276 lines =<< trim END
1277 vim9script
1278 if true
1279 var name = 'piet'
1280 def FuncOne(name: string)
1281 echo name
1282 enddef
1283 endif
1284 END
1285 v9.CheckScriptFailure(lines, 'E1168:')
1286
1287 # variable in other block is OK
1288 lines =<< trim END
1289 vim9script
1290 if true
1291 var name = 'piet'
1292 endif
1293 def FuncOne(name: string)
1294 echo name
1295 enddef
1296 END
1297 v9.CheckScriptSuccess(lines)
1298
Bram Moolenaardce24412022-02-08 20:35:30 +00001299 # with another variable in another block
1300 lines =<< trim END
1301 vim9script
1302 if true
1303 var name = 'piet'
1304 # define a function so that the variable isn't cleared
1305 def GetItem(): string
1306 return item
1307 enddef
1308 endif
1309 if true
1310 var name = 'peter'
1311 def FuncOne(name: string)
1312 echo name
1313 enddef
1314 endif
1315 END
1316 v9.CheckScriptFailure(lines, 'E1168:')
1317
1318 # only variable in another block is OK
1319 lines =<< trim END
1320 vim9script
1321 if true
1322 var name = 'piet'
1323 # define a function so that the variable isn't cleared
1324 def GetItem(): string
1325 return item
1326 enddef
1327 endif
1328 if true
1329 def FuncOne(name: string)
1330 echo name
1331 enddef
1332 endif
1333 END
1334 v9.CheckScriptSuccess(lines)
1335
Bram Moolenaar9a015112021-12-31 14:06:45 +00001336 # argument name declared later is only found when compiling
1337 lines =<< trim END
1338 vim9script
1339 def FuncOne(name: string)
1340 echo nr
1341 enddef
1342 var name = 'piet'
1343 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001344 v9.CheckScriptSuccess(lines)
1345 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001346
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001347 lines =<< trim END
1348 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001349 def FuncOne(nr: number)
1350 echo nr
1351 enddef
1352 def FuncTwo()
1353 FuncOne()
1354 enddef
1355 defcompile
1356 END
1357 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001358 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001359 try
1360 source Xscript
1361 catch
1362 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1363 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1364 didCatch = true
1365 endtry
1366 assert_true(didCatch)
1367
1368 lines =<< trim END
1369 vim9script
1370 def FuncOne(nr: number)
1371 echo nr
1372 enddef
1373 def FuncTwo()
1374 FuncOne(1, 2)
1375 enddef
1376 defcompile
1377 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001378 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001379 didCatch = false
1380 try
1381 source Xscript
1382 catch
1383 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1384 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1385 didCatch = true
1386 endtry
1387 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001388enddef
1389
Bram Moolenaar50824712020-12-20 21:10:17 +01001390def Test_call_funcref_wrong_args()
1391 var head =<< trim END
1392 vim9script
1393 def Func3(a1: string, a2: number, a3: list<number>)
1394 echo a1 .. a2 .. a3[0]
1395 enddef
1396 def Testme()
1397 var funcMap: dict<func> = {func: Func3}
1398 END
1399 var tail =<< trim END
1400 enddef
1401 Testme()
1402 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001403 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001404
Bram Moolenaar62aec932022-01-29 21:45:34 +00001405 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1406 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001407
1408 var lines =<< trim END
1409 vim9script
1410 var Ref: func(number): any
1411 Ref = (j) => !j
1412 echo Ref(false)
1413 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001414 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001415
1416 lines =<< trim END
1417 vim9script
1418 var Ref: func(number): any
1419 Ref = (j) => !j
1420 call Ref(false)
1421 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001422 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001423enddef
1424
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001425def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001426 var lines =<< trim END
1427 var Callback = (..._) => 'anything'
1428 assert_equal('anything', Callback())
1429 assert_equal('anything', Callback(1))
1430 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001431
1432 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001433 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001434 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001435
Bram Moolenaar62aec932022-01-29 21:45:34 +00001436 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001437 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001438
Bram Moolenaar2a389082021-04-09 20:24:31 +02001439 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001440 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001441 echo Ref(1, 'x')
1442 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001443 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001444
1445 lines =<< trim END
1446 var Ref: func(job, string, number)
1447 Ref = (x, y) => 0
1448 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001449 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001450
1451 lines =<< trim END
1452 var Ref: func(job, string)
1453 Ref = (x, y, z) => 0
1454 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001455 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001456
1457 lines =<< trim END
1458 var one = 1
1459 var l = [1, 2, 3]
1460 echo map(l, (one) => one)
1461 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001462 v9.CheckDefFailure(lines, 'E1167:')
1463 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001464
1465 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001466 var Ref: func(any, ?any): bool
1467 Ref = (_, y = 1) => false
1468 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001469 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001470
1471 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001472 var a = 0
1473 var b = (a == 0 ? 1 : 2)
1474 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001475 var txt = 'a'
1476 b = (txt =~ 'x' ? 1 : 2)
1477 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001478 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001479 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001480
1481 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001482 def ShadowLocal()
1483 var one = 1
1484 var l = [1, 2, 3]
1485 echo map(l, (one) => one)
1486 enddef
1487 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001488 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001489
1490 lines =<< trim END
1491 def Shadowarg(one: number)
1492 var l = [1, 2, 3]
1493 echo map(l, (one) => one)
1494 enddef
1495 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001496 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001497
1498 lines =<< trim END
1499 echo ((a) => a)('aa', 'bb')
1500 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001501 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001502
1503 lines =<< trim END
1504 echo 'aa'->((a) => a)('bb')
1505 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001506 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1507 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001508enddef
1509
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001510def Test_lambda_line_nr()
1511 var lines =<< trim END
1512 vim9script
1513 # comment
1514 # comment
1515 var id = timer_start(1'000, (_) => 0)
1516 var out = execute('verbose ' .. timer_info(id)[0].callback
1517 ->string()
1518 ->substitute("('\\|')", ' ', 'g'))
1519 assert_match('Last set from .* line 4', out)
1520 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001521 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001522enddef
1523
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001524def FilterWithCond(x: string, Cond: func(string): bool): bool
1525 return Cond(x)
1526enddef
1527
Bram Moolenaar0346b792021-01-31 22:18:29 +01001528def Test_lambda_return_type()
1529 var lines =<< trim END
1530 var Ref = (): => 123
1531 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001532 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001533
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001534 # no space before the return type
1535 lines =<< trim END
1536 var Ref = (x):number => x + 1
1537 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001538 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001539
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001540 # this works
1541 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001542 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001543 endfor
1544
1545 # this fails
1546 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001547 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001548 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001549 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 +02001550
1551 lines =<< trim END
1552 var Lambda1 = (x) => {
1553 return x
1554 }
1555 assert_equal('asdf', Lambda1('asdf'))
1556 var Lambda2 = (x): string => {
1557 return x
1558 }
1559 assert_equal('foo', Lambda2('foo'))
1560 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001561 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001562
1563 lines =<< trim END
1564 var Lambda = (x): string => {
1565 return x
1566 }
1567 echo Lambda(['foo'])
1568 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001569 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001570enddef
1571
Bram Moolenaar709664c2020-12-12 14:33:41 +01001572def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001573 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001574 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001575 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001576enddef
1577
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001578def Test_lambda_invalid_block()
1579 var lines =<< trim END
1580 timer_start(0, (_) => { # echo
1581 echo 'yes'
1582 })
1583 END
1584 v9.CheckDefAndScriptSuccess(lines)
1585
1586 lines =<< trim END
1587 timer_start(0, (_) => { " echo
1588 echo 'yes'
1589 })
1590 END
1591 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1592
1593 lines =<< trim END
1594 timer_start(0, (_) => { | echo
1595 echo 'yes'
1596 })
1597 END
1598 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1599enddef
1600
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001601def Test_lambda_with_following_cmd()
1602 var lines =<< trim END
1603 set ts=2
1604 var Lambda = () => {
1605 set ts=4
1606 } | set ts=3
1607 assert_equal(3, &ts)
1608 Lambda()
1609 assert_equal(4, &ts)
1610 END
1611 v9.CheckDefAndScriptSuccess(lines)
1612 set ts=8
1613enddef
1614
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001615def Test_pass_legacy_lambda_to_def_func()
1616 var lines =<< trim END
1617 vim9script
1618 func Foo()
1619 eval s:Bar({x -> 0})
1620 endfunc
1621 def Bar(y: any)
1622 enddef
1623 Foo()
1624 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001625 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001626
1627 lines =<< trim END
1628 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001629 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001630 enddef
1631 legacy call g:TestFunc({-> 0})
1632 delfunc g:TestFunc
1633
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001634 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001635 enddef
1636 legacy call g:TestFunc({nr -> 0})
1637 delfunc g:TestFunc
1638 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001639 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001640enddef
1641
Bram Moolenaar844fb642021-10-23 13:32:30 +01001642def Test_lambda_in_reduce_line_break()
1643 # this was using freed memory
1644 var lines =<< trim END
1645 vim9script
1646 const result: dict<number> =
1647 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1648 ->reduce((acc, val) => {
1649 if has_key(acc, val)
1650 acc[val] += 1
1651 return acc
1652 else
1653 acc[val] = 1
1654 return acc
1655 endif
1656 }, {})
1657 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1658 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001659 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001660enddef
1661
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001662def Test_set_opfunc_to_lambda()
1663 var lines =<< trim END
1664 vim9script
1665 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1666 def CountSpaces(type = ''): string
1667 if type == ''
1668 &operatorfunc = (t) => CountSpaces(t)
1669 return 'g@'
1670 endif
1671 normal! '[V']y
1672 g:result = getreg('"')->count(' ')
1673 return ''
1674 enddef
1675 new
1676 'a b c d e'->setline(1)
1677 feedkeys("\<F4>", 'x')
1678 assert_equal(4, g:result)
1679 bwipe!
1680 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001681 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001682enddef
1683
Bram Moolenaaref082e12021-12-12 21:02:03 +00001684def Test_set_opfunc_to_global_function()
1685 var lines =<< trim END
1686 vim9script
1687 def g:CountSpaces(type = ''): string
1688 normal! '[V']y
1689 g:result = getreg('"')->count(' ')
1690 return ''
1691 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001692 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001693 &operatorfunc = g:CountSpaces
1694 new
1695 'a b c d e'->setline(1)
1696 feedkeys("g@_", 'x')
1697 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001698
1699 &operatorfunc = ''
1700 g:result = 0
1701 # global function works in :def function
1702 def Func()
1703 &operatorfunc = g:CountSpaces
1704 enddef
1705 Func()
1706 feedkeys("g@_", 'x')
1707 assert_equal(4, g:result)
1708
Bram Moolenaaref082e12021-12-12 21:02:03 +00001709 bwipe!
1710 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001711 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001712 &operatorfunc = ''
1713enddef
1714
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001715def Test_use_script_func_name_with_prefix()
1716 var lines =<< trim END
1717 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001718 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001719 return 'it'
1720 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001721 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001722 assert_equal('it', Fn())
1723 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001724 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001725enddef
1726
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001727def Test_lambda_type_allocated()
1728 # Check that unreferencing a partial using a lambda can use the variable type
1729 # after the lambda has been freed and does not leak memory.
1730 var lines =<< trim END
1731 vim9script
1732
1733 func MyomniFunc1(val, findstart, base)
1734 return a:findstart ? 0 : []
1735 endfunc
1736
1737 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1738 &omnifunc = Lambda
1739 Lambda = (a, b) => MyomniFunc1(20, a, b)
1740 &omnifunc = string(Lambda)
1741 Lambda = (a, b) => strlen(a)
1742 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001743 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001744enddef
1745
Bram Moolenaara7583c42022-05-07 21:14:05 +01001746def Test_define_lambda_in_execute()
1747 var lines =<< trim [CODE]
1748 vim9script
1749
1750 def BuildFuncMultiLine(): func
1751 var x =<< trim END
1752 g:SomeRandomFunc = (d: dict<any>) => {
1753 return d.k1 + d.k2
1754 }
1755 END
1756 execute(x)
1757 return g:SomeRandomFunc
1758 enddef
1759 var ResultPlus = BuildFuncMultiLine()
1760 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1761 [CODE]
1762 v9.CheckScriptSuccess(lines)
1763 unlet g:SomeRandomFunc
1764enddef
1765
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001766" Default arg and varargs
1767def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001768 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001769 for s in rest
1770 res ..= ',' .. s
1771 endfor
1772 return res
1773enddef
1774
1775def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001776 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1777 g:MyDefVarargs('one')->assert_equal('one,foo')
1778 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1779 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1780 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001781 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001782 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001783 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001784
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001785 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001786 vim9script
1787 def Func(...l: list<string>)
1788 echo l
1789 enddef
1790 Func('a', 'b', 'c')
1791 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001792 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001793
1794 lines =<< trim END
1795 vim9script
1796 def Func(...l: list<string>)
1797 echo l
1798 enddef
1799 Func()
1800 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001801 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001802
1803 lines =<< trim END
1804 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001805 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001806 echo l
1807 enddef
1808 Func(0)
1809 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001810 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001811
1812 lines =<< trim END
1813 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001814 def Func(...l: any)
1815 echo l
1816 enddef
1817 Func(0)
1818 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001819 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001820
1821 lines =<< trim END
1822 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001823 def Func(..._l: list<string>)
1824 echo _l
1825 enddef
1826 Func('a', 'b', 'c')
1827 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001828 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001829
1830 lines =<< trim END
1831 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001832 def Func(...l: list<string>)
1833 echo l
1834 enddef
1835 Func(1, 2, 3)
1836 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001837 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001838
1839 lines =<< trim END
1840 vim9script
1841 def Func(...l: list<string>)
1842 echo l
1843 enddef
1844 Func('a', 9)
1845 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001846 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001847
1848 lines =<< trim END
1849 vim9script
1850 def Func(...l: list<string>)
1851 echo l
1852 enddef
1853 Func(1, 'a')
1854 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001855 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001856
1857 lines =<< trim END
1858 vim9script
1859 def Func( # some comment
1860 ...l = []
1861 )
1862 echo l
1863 enddef
1864 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001865 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001866
1867 lines =<< trim END
1868 vim9script
1869 def DoIt()
1870 g:Later('')
1871 enddef
1872 defcompile
1873 def g:Later(...l: list<number>)
1874 enddef
1875 DoIt()
1876 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001877 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001878enddef
1879
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001880let s:value = ''
1881
1882def FuncOneDefArg(opt = 'text')
1883 s:value = opt
1884enddef
1885
1886def FuncTwoDefArg(nr = 123, opt = 'text'): string
1887 return nr .. opt
1888enddef
1889
1890def FuncVarargs(...arg: list<string>): string
1891 return join(arg, ',')
1892enddef
1893
1894def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001895 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001896 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001897 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001898 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001899 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001900 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001901
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001902 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001903 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001904 RefDef2Arg()->assert_equal('123text')
1905 RefDef2Arg(99)->assert_equal('99text')
1906 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001907
Bram Moolenaar62aec932022-01-29 21:45:34 +00001908 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
1909 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001910
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001911 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001912 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001913 RefVarargs()->assert_equal('')
1914 RefVarargs('one')->assert_equal('one')
1915 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001916
Bram Moolenaar62aec932022-01-29 21:45:34 +00001917 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
1918 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001919enddef
1920
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001921" Only varargs
1922def MyVarargsOnly(...args: list<string>): string
1923 return join(args, ',')
1924enddef
1925
1926def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001927 g:MyVarargsOnly()->assert_equal('')
1928 g:MyVarargsOnly('one')->assert_equal('one')
1929 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
1930 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
1931 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001932enddef
1933
Bram Moolenaar36818a92023-01-03 12:33:26 +00001934def Test_varargs_mismatch()
1935 var lines =<< trim END
1936 vim9script
1937
1938 def Map(Fn: func(...any): number): number
1939 return Fn('12')
1940 enddef
1941
1942 var res = Map((v) => str2nr(v))
1943 assert_equal(12, res)
1944 END
1945 v9.CheckScriptSuccess(lines)
1946enddef
1947
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001948def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00001949 var lines =<< trim END
1950 def Func(x: number)
1951 var x = 234
1952 enddef
1953 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001954 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00001955
1956 lines =<< trim END
1957 def Func(Ref: number)
1958 def Ref()
1959 enddef
1960 enddef
1961 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001962 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001963enddef
1964
Bram Moolenaar62aec932022-01-29 21:45:34 +00001965def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001966 arg['key'] = 'value'
1967enddef
1968
Bram Moolenaar62aec932022-01-29 21:45:34 +00001969def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001970 arg[0] = 'value'
1971enddef
1972
1973def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001974 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001975 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001976 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001977 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001978 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001979 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001980 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001981
Bram Moolenaar62aec932022-01-29 21:45:34 +00001982 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001983 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001984enddef
1985
Bram Moolenaarb816dae2020-09-20 22:04:00 +02001986" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00001987def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02001988 return firstline .. lastline
1989enddef
1990
1991def Test_argument_names()
1992 assert_equal('OK', WithReservedNames('O', 'K'))
1993enddef
1994
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001995def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001996 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001997 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001998enddef
1999
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002000func DefinedLater(arg)
2001 return a:arg
2002endfunc
2003
2004def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002005 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002006 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002007 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002008
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002009 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002010 vim9script
2011 def RetNumber(): number
2012 return 123
2013 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002014 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002015 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002016 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002017 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002018
2019 lines =<< trim END
2020 vim9script
2021 def RetNumber(): number
2022 return 123
2023 enddef
2024 def Bar(F: func: number): number
2025 return F()
2026 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002027 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002028 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002029 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002030 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002031
2032 lines =<< trim END
2033 vim9script
2034 def UseNumber(nr: number)
2035 echo nr
2036 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002037 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002038 Funcref(123)
2039 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002040 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002041
2042 lines =<< trim END
2043 vim9script
2044 def UseNumber(nr: number)
2045 echo nr
2046 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002047 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002048 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002049 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002050
2051 lines =<< trim END
2052 vim9script
2053 def EchoNr(nr = 34)
2054 g:echo = nr
2055 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002056 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002057 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002058 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002059 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002060 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002061 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002062 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002063
2064 lines =<< trim END
2065 vim9script
2066 def EchoList(...l: list<number>)
2067 g:echo = l
2068 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002069 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002070 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002071 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002072 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002073 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002074 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002075 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002076
2077 lines =<< trim END
2078 vim9script
2079 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2080 g:optarg = opt
2081 g:listarg = l
2082 return nr
2083 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002084 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002085 Funcref(10)->assert_equal(10)
2086 g:optarg->assert_equal(12)
2087 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002088
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002089 Funcref(11, 22)->assert_equal(11)
2090 g:optarg->assert_equal(22)
2091 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002092
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002093 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2094 g:optarg->assert_equal(18)
2095 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002096 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002097 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002098
2099 lines =<< trim END
2100 function s:func(num)
2101 return a:num * 2
2102 endfunction
2103
2104 def s:CallFuncref()
2105 var Funcref = function('s:func')
2106 Funcref(3)->assert_equal(6)
2107 enddef
2108 call s:CallFuncref()
2109 END
2110 v9.CheckScriptSuccess(lines)
2111
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 = s:func
2132 Funcref(3)->assert_equal(6)
2133 enddef
2134 call s:CallFuncref()
2135 END
2136 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002137enddef
2138
2139let SomeFunc = function('len')
2140let NotAFunc = 'text'
2141
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002142def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002143 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002144 var Ref1: func(bool): string
2145 var Ref2: func(bool): number
2146 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002147 Ref3 = g:cond ? Ref1 : Ref2
2148
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002149 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002150 var Refa1: func(bool): number
2151 var Refa2: func(bool, number): number
2152 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002153 Refa3 = g:cond ? Refa1 : Refa2
2154
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002155 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002156 var Refb1: func(bool, string): number
2157 var Refb2: func(string, number): number
2158 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002159 Refb3 = g:cond ? Refb1 : Refb2
2160enddef
2161
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002162def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002163 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002164enddef
2165
2166def DefinedEvenLater(arg: string): string
2167 return arg
2168enddef
2169
2170def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002171 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002172 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002173enddef
2174
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002175def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002176 var lines =<< trim END
2177 vim9script
2178 # Define an outer function
2179 def FirstFunction()
2180 # Define an inner function
2181 def SecondFunction()
2182 # the function has a body, a double free is detected.
2183 AAAAA
2184
2185 # enddef followed by | or } followed by # one or more characters
2186 enddef|BBBB
2187 enddef
2188
2189 # Compile all functions
2190 defcompile
2191 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002192 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002193enddef
2194
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002195def Test_nested_function_with_args_split()
2196 var lines =<< trim END
2197 vim9script
2198 def FirstFunction()
2199 def SecondFunction(
2200 )
2201 # had a double free if the right parenthesis of the nested function is
2202 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002203
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002204 enddef|BBBB
2205 enddef
2206 # Compile all functions
2207 defcompile
2208 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002209 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002210
2211 lines =<< trim END
2212 vim9script
2213 def FirstFunction()
2214 func SecondFunction()
2215 endfunc|BBBB
2216 enddef
2217 defcompile
2218 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002219 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002220enddef
2221
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002222def Test_error_in_function_args()
2223 var lines =<< trim END
2224 def FirstFunction()
2225 def SecondFunction(J =
2226 # Nois
2227 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002228
2229 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002230 enddef
2231 # Compile all functions
2232 defcompile
2233 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002234 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002235enddef
2236
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002237def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002238 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002239 'def Func(): number',
2240 'return "a"',
2241 'enddef',
2242 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002243 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002244 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002245 'def Func(): string',
2246 'return 1',
2247 'enddef',
2248 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002249 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002250 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002251 'def Func(): void',
2252 'return "a"',
2253 'enddef',
2254 'defcompile'],
2255 'E1096: Returning a value in a function without a return type')
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()',
2259 'return "a"',
2260 'enddef',
2261 'defcompile'],
2262 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002263 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002264
Bram Moolenaar62aec932022-01-29 21:45:34 +00002265 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002266 'def Func(): number',
2267 'return',
2268 'enddef',
2269 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002270 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002271
Bram Moolenaar62aec932022-01-29 21:45:34 +00002272 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002273 'def Func():number',
2274 'return 123',
2275 'enddef',
2276 'defcompile'], 'E1069:')
2277 delfunc! g:Func
2278
Bram Moolenaar62aec932022-01-29 21:45:34 +00002279 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002280 'def Func() :number',
2281 'return 123',
2282 'enddef',
2283 'defcompile'], 'E1059:')
2284 delfunc! g:Func
2285
Bram Moolenaar62aec932022-01-29 21:45:34 +00002286 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002287 'def Func() : number',
2288 'return 123',
2289 'enddef',
2290 'defcompile'], 'E1059:')
2291 delfunc! g:Func
2292
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002293 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002294 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002295 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002296 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002297 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002298 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002299
Bram Moolenaar62aec932022-01-29 21:45:34 +00002300 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002301 'vim9script',
2302 'def FuncB()',
2303 ' return 123',
2304 'enddef',
2305 'def FuncA()',
2306 ' FuncB()',
2307 'enddef',
2308 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002309enddef
2310
2311def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002312 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002313 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2314 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2315 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2316 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2317 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002318enddef
2319
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002320def Test_white_space_before_comma()
2321 var lines =<< trim END
2322 vim9script
2323 def Func(a: number , b: number)
2324 enddef
2325 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002326 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002327 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002328enddef
2329
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002330def Test_white_space_after_comma()
2331 var lines =<< trim END
2332 vim9script
2333 def Func(a: number,b: number)
2334 enddef
2335 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002336 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002337
2338 # OK in legacy function
2339 lines =<< trim END
2340 vim9script
2341 func Func(a,b)
2342 endfunc
2343 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002344 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002345enddef
2346
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002347def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002348 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002349 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002350 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002351 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002352 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002353 enddef
2354 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002355 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002356
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002357 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002358 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002359 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002360
Bram Moolenaar67979662020-06-20 22:50:47 +02002361 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002362 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002363 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002364
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002365 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002366 def ListFunc(arg: list<number>)
2367 listvar = arg
2368 enddef
2369 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002370 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002371
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002372 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002373 def DictFunc(arg: dict<number>)
2374 dictvar = arg
2375 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002376 {a: 1, b: 2}->DictFunc()
2377 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002378 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002379 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002380 enddef
2381 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002382 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002383
Bram Moolenaare0de1712020-12-02 17:36:54 +01002384 {a: 3, b: 4}->DictFunc()
2385 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002386
2387 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002388 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002389 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002390 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002391
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002392 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002393 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002394 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002395 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002396 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002397 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002398
2399 def UseString()
2400 'xyork'->MyFunc()
2401 enddef
2402 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002403 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002404
Bram Moolenaar10409562020-07-29 20:00:38 +02002405 def UseString2()
2406 "knife"->MyFunc()
2407 enddef
2408 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002409 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002410
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002411 # prepending a colon makes it a mark
2412 new
2413 setline(1, ['aaa', 'bbb', 'ccc'])
2414 normal! 3Gmt1G
2415 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002416 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002417 bwipe!
2418
Bram Moolenaare6b53242020-07-01 17:28:33 +02002419 MyFunc(
2420 'continued'
2421 )
2422 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002423 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002424 )
2425
2426 call MyFunc(
2427 'more'
2428 ..
2429 'lines'
2430 )
2431 assert_equal(
2432 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002433 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002434 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002435 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002436 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002437enddef
2438
2439def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002440 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002441 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002442 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002443 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002444 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002445 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002446 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002447 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002448 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002449enddef
2450
Bram Moolenaar65b95452020-07-19 14:03:09 +02002451def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002452 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002453 vim9script
2454 def MyFunc(arg: string)
2455 echo arg
2456 enddef
2457 MyFunc(1234)
2458 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002459 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002460enddef
2461
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002462def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002463 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002464 vim9script
2465 const var = ''
2466 def MyFunc(arg: string)
2467 var = 'asdf'
2468 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002469 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002470 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002471 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002472 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002473
2474 lines =<< trim END
2475 const g:Aconst = 77
2476 def Change()
2477 # comment
2478 g:Aconst = 99
2479 enddef
2480 call Change()
2481 unlet g:Aconst
2482 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002483 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002484enddef
2485
2486" Test that inside :function a Python function can be defined, :def is not
2487" recognized.
2488func Test_function_python()
2489 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002490 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002491 execute py "<< EOF"
2492def do_something():
2493 return 1
2494EOF
2495endfunc
2496
2497def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002498 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002499 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002500 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002501 echo 'hello'
2502 enddef
2503
2504 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002505 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002506 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002507 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002508
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002509 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002510 CallGoneSoon()
2511 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002512 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002513 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2514 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002515enddef
2516
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002517func Test_free_dict_while_in_funcstack()
2518 " relies on the sleep command
2519 CheckUnix
2520 call Run_Test_free_dict_while_in_funcstack()
2521endfunc
2522
2523def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002524 # this was freeing the TermRun() default argument dictionary while it was
2525 # still referenced in a funcstack_T
2526 var lines =<< trim END
2527 vim9script
2528
2529 &updatetime = 400
2530 def TermRun(_ = {})
2531 def Post()
2532 enddef
2533 def Exec()
2534 term_start('sleep 1', {
2535 term_finish: 'close',
2536 exit_cb: (_, _) => Post(),
2537 })
2538 enddef
2539 Exec()
2540 enddef
2541 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2542 timer_start(100, (_) => feedkeys("\<F4>"))
2543 timer_start(1000, (_) => feedkeys("\<F4>"))
2544 sleep 1500m
2545 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002546 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002547 nunmap <F4>
2548 set updatetime&
2549enddef
2550
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002551def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002552 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002553 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002554 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002555 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002556 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002557 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002558 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002559 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002560 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002561
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002562 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002563 g:Func1()->assert_equal('Func1')
2564 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002565
2566 delfunc! Func0
2567 delfunc! Func1
2568 delfunc! Func2
2569enddef
2570
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002571def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002572 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002573 vim9script
2574 func Func(arg)
2575 echo a:arg
2576 endfunc
2577 Func('text')
2578 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002579 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002580 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002581enddef
2582
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002583let s:funcResult = 0
2584
2585def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002586 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002587enddef
2588
2589def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002590 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002591 return 1234
2592enddef
2593
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002594def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002595 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002596 return 'text'
2597enddef
2598
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002599def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002600 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002601enddef
2602
2603def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002604 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002605 return arg
2606enddef
2607
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002608def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002609 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002610enddef
2611
Bram Moolenaar62aec932022-01-29 21:45:34 +00002612def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002613 return arg
2614enddef
2615
Bram Moolenaar62aec932022-01-29 21:45:34 +00002616def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002617 return arg
2618enddef
2619
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002620def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002621 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002622 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002623 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002624 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002625 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002626
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002627 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002628 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002629 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002630 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002631 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002632
Bram Moolenaar53900992020-08-22 19:02:02 +02002633 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002634 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002635 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002636 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002637
Bram Moolenaar53900992020-08-22 19:02:02 +02002638 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002639 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002640 Ref2()->assert_equal(1234)
2641 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002642
Bram Moolenaar53900992020-08-22 19:02:02 +02002643 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002644 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002645 Ref2(13)->assert_equal(13)
2646 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002647enddef
2648
Bram Moolenaar9978d472020-07-05 16:01:56 +02002649def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002650 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002651 for n in repeat([1], 3)
2652 res += n
2653 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002654 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002655
2656 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002657 for n in repeat(0z01, 3)->blob2list()
2658 res += n
2659 endfor
2660 res->assert_equal(3)
2661
2662 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002663 for n in add([1, 2], 3)
2664 res += n
2665 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002666 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002667enddef
2668
Bram Moolenaar846178a2020-07-05 17:04:13 +02002669def Test_argv_return_type()
2670 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002671 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002672 for name in argv()
2673 res ..= name
2674 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002675 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002676enddef
2677
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002678def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002679 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002680 RefVoid = g:FuncNoArgNoRet
2681 RefVoid = g:FuncOneArgNoRet
2682 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 +00002683 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 +02002684
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002685 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002686 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002687 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002688 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2689 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 +02002690
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002691 var RefAnyNoArgs: func: any = RefAny
2692
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002693 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002694 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002695 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002696 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 +00002697 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 +02002698
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002699 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002700 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002701 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002702 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2703 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 +02002704enddef
2705
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002706def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002707 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002708
Bram Moolenaar62aec932022-01-29 21:45:34 +00002709 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2710 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002711 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 +00002712 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2713 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
2714 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 +02002715
Bram Moolenaar62aec932022-01-29 21:45:34 +00002716 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2717 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2718 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:')
2719 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002720enddef
2721
Bram Moolenaar89228602020-04-05 22:14:54 +02002722def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002723 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002724 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002725 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002726
2727 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002728 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002729
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002730 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002731 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002732 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002733
Bram Moolenaar62aec932022-01-29 21:45:34 +00002734 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002735enddef
2736
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002737def Test_func_common_type()
2738 def FuncOne(n: number): number
2739 return n
2740 enddef
2741 def FuncTwo(s: string): number
2742 return len(s)
2743 enddef
2744 def FuncThree(n: number, s: string): number
2745 return n + len(s)
2746 enddef
2747 var list = [FuncOne, FuncTwo, FuncThree]
2748 assert_equal(8, list[0](8))
2749 assert_equal(4, list[1]('word'))
2750 assert_equal(7, list[2](3, 'word'))
2751enddef
2752
Bram Moolenaar62aec932022-01-29 21:45:34 +00002753def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002754 arg1: string,
2755 arg2 = 1234,
2756 ...rest: list<string>
2757 ): string
2758 return arg1 .. arg2 .. join(rest, '-')
2759enddef
2760
Bram Moolenaar2c330432020-04-13 14:41:35 +02002761def MultiLineComment(
2762 arg1: string, # comment
2763 arg2 = 1234, # comment
2764 ...rest: list<string> # comment
2765 ): string # comment
2766 return arg1 .. arg2 .. join(rest, '-')
2767enddef
2768
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002769def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002770 MultiLine('text')->assert_equal('text1234')
2771 MultiLine('text', 777)->assert_equal('text777')
2772 MultiLine('text', 777, 'one')->assert_equal('text777one')
2773 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002774enddef
2775
Bram Moolenaar23e03252020-04-12 22:22:31 +02002776func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002777 call s:MultiLine('text')->assert_equal('text1234')
2778 call s:MultiLine('text', 777)->assert_equal('text777')
2779 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2780 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002781endfunc
2782
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002783
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002784" When using CheckScriptFailure() for the below test, E1010 is generated instead
2785" of E1056.
2786func Test_E1056_1059()
2787 let caught_1056 = 0
2788 try
2789 def F():
2790 return 1
2791 enddef
2792 catch /E1056:/
2793 let caught_1056 = 1
2794 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002795 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002796
2797 let caught_1059 = 0
2798 try
2799 def F5(items : list)
2800 echo 'a'
2801 enddef
2802 catch /E1059:/
2803 let caught_1059 = 1
2804 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002805 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002806endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002807
Bram Moolenaar015f4262020-05-05 21:25:22 +02002808func DelMe()
2809 echo 'DelMe'
2810endfunc
2811
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002812def Test_error_reporting()
2813 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002814 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002815 " comment
2816 def Func()
2817 # comment
2818 # comment
2819 invalid
2820 enddef
2821 defcompile
2822 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002823 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002824 try
2825 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002826 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002827 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002828 v:exception->assert_match('Invalid command: invalid')
2829 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002830 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002831 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002832
2833 # comment lines after the start of the function
2834 lines =<< trim END
2835 " comment
2836 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002837 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002838 # comment
2839 # comment
2840 invalid
2841 enddef
2842 defcompile
2843 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002844 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002845 try
2846 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002847 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002848 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002849 v:exception->assert_match('Invalid command: invalid')
2850 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002851 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002852 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002853
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002854 lines =<< trim END
2855 vim9script
2856 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002857 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002858 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002859 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002860 enddef
2861 defcompile
2862 Func()
2863 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002864 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002865 try
2866 source Xdef
2867 assert_report('should have failed')
2868 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002869 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002870 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002871 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002872enddef
2873
Bram Moolenaar015f4262020-05-05 21:25:22 +02002874def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002875 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002876 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002877 'delfunc g:DelMe',
2878 'echo RefMe()'], 'E117:')
2879enddef
2880
2881def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002882 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002883 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002884 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002885enddef
2886
Bram Moolenaar62aec932022-01-29 21:45:34 +00002887def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002888 return Ref('more')
2889enddef
2890
2891def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002892 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002893 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002894enddef
2895
Bram Moolenaar62aec932022-01-29 21:45:34 +00002896def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002897 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002898 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002899enddef
2900
2901def Test_closure_ref_after_return()
2902 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002903 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002904 unlet g:Ref
2905enddef
2906
Bram Moolenaar62aec932022-01-29 21:45:34 +00002907def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002908 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002909 g:Extend = (s) => local->add(s)
2910 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002911enddef
2912
2913def Test_closure_two_refs()
2914 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002915 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002916 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002917 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002918 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002919 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002920
2921 unlet g:Extend
2922 unlet g:Read
2923enddef
2924
Bram Moolenaar62aec932022-01-29 21:45:34 +00002925def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002926 return join(Ref(), ' ')
2927enddef
2928
Bram Moolenaar62aec932022-01-29 21:45:34 +00002929def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002930 Ref(add)
2931enddef
2932
2933def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002934 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002935 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002936 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002937 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002938 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002939 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002940
2941 unlet g:Extend
2942 unlet g:Read
2943enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002944
Bram Moolenaar62aec932022-01-29 21:45:34 +00002945def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002946 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002947 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002948enddef
2949
Bram Moolenaar62aec932022-01-29 21:45:34 +00002950def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002951 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002952 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002953enddef
2954
2955def Test_closure_using_argument()
2956 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002957 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002958
2959 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002960 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002961
2962 unlet g:UseArg
2963 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01002964
2965 var lines =<< trim END
2966 vim9script
2967 def Test(Fun: func(number): number): list<number>
2968 return map([1, 2, 3], (_, i) => Fun(i))
2969 enddef
2970 def Inc(nr: number): number
2971 return nr + 2
2972 enddef
2973 assert_equal([3, 4, 5], Test(Inc))
2974 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002975 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002976enddef
2977
Bram Moolenaar62aec932022-01-29 21:45:34 +00002978def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02002979 var local = 'a'
2980
2981 def Append(arg: string)
2982 local ..= arg
2983 enddef
2984 g:Append = Append
2985
2986 def Get(): string
2987 return local
2988 enddef
2989 g:Get = Get
2990enddef
2991
2992def Test_closure_append_get()
2993 MakeGetAndAppendRefs()
2994 g:Get()->assert_equal('a')
2995 g:Append('-b')
2996 g:Get()->assert_equal('a-b')
2997 g:Append('-c')
2998 g:Get()->assert_equal('a-b-c')
2999
3000 unlet g:Append
3001 unlet g:Get
3002enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003003
Bram Moolenaar04b12692020-05-04 23:24:44 +02003004def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003005 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003006 def Closure(arg: string): string
3007 return local .. arg
3008 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003009 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003010enddef
3011
Bram Moolenaar62aec932022-01-29 21:45:34 +00003012func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003013 return a:Ref('some')
3014endfunc
3015
3016def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003017 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003018 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003019 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003020enddef
3021
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003022def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003023 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003024 vim9script
3025 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003026 var name = 0
3027 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003028 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003029 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003030 enddef
3031 Func()
3032 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003033 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003034enddef
3035
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003036def Test_nested_closure_used()
3037 var lines =<< trim END
3038 vim9script
3039 def Func()
3040 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003041 var Closure = () => x
3042 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003043 enddef
3044 Func()
3045 assert_equal('hello', g:Myclosure())
3046 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003047 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003048enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003049
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003050def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003051 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003052 vim9script
3053 def FuncA()
3054 FuncB(0)
3055 enddef
3056 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003057 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003058 enddef
3059 FuncA()
3060 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003061 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003062enddef
3063
Bram Moolenaar6de22962022-09-09 21:35:36 +01003064def Run_Test_closure_in_for_loop_fails()
3065 var lines =<< trim END
3066 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003067 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003068 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003069 # time should be enough for startup to finish
3070 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003071 echo n
3072 })
3073 endfor
3074 END
3075 writefile(lines, 'XTest_closure_fails', 'D')
3076
3077 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003078 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003079 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003080
3081 # clean up
3082 g:StopVimInTerminal(buf)
3083enddef
3084
3085func Test_closure_in_for_loop_fails()
3086 CheckScreendump
3087 call Run_Test_closure_in_for_loop_fails()
3088endfunc
3089
Bram Moolenaarf112f302020-12-20 17:47:52 +01003090def Test_global_closure()
3091 var lines =<< trim END
3092 vim9script
3093 def ReverseEveryNLines(n: number, line1: number, line2: number)
3094 var mods = 'sil keepj keepp lockm '
3095 var range = ':' .. line1 .. ',' .. line2
3096 def g:Offset(): number
3097 var offset = (line('.') - line1 + 1) % n
3098 return offset != 0 ? offset : n
3099 enddef
3100 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3101 enddef
3102
3103 new
3104 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3105 ReverseEveryNLines(3, 1, 9)
3106 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003107 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003108 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3109 assert_equal(expected, getline(1, 9))
3110 bwipe!
3111enddef
3112
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003113def Test_global_closure_called_directly()
3114 var lines =<< trim END
3115 vim9script
3116 def Outer()
3117 var x = 1
3118 def g:Inner()
3119 var y = x
3120 x += 1
3121 assert_equal(1, y)
3122 enddef
3123 g:Inner()
3124 assert_equal(2, x)
3125 enddef
3126 Outer()
3127 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003128 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003129 delfunc g:Inner
3130enddef
3131
Bram Moolenaar69c76172021-12-02 16:38:52 +00003132def Test_closure_called_from_legacy()
3133 var lines =<< trim END
3134 vim9script
3135 def Func()
3136 var outer = 'foo'
3137 var F = () => {
3138 outer = 'bar'
3139 }
3140 execute printf('call %s()', string(F))
3141 enddef
3142 Func()
3143 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003144 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003145enddef
3146
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003147def Test_failure_in_called_function()
3148 # this was using the frame index as the return value
3149 var lines =<< trim END
3150 vim9script
3151 au TerminalWinOpen * eval [][0]
3152 def PopupTerm(a: any)
3153 # make sure typvals on stack are string
3154 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3155 FireEvent()
3156 enddef
3157 def FireEvent()
3158 do TerminalWinOpen
3159 enddef
3160 # use try/catch to make eval fail
3161 try
3162 call PopupTerm(0)
3163 catch
3164 endtry
3165 au! TerminalWinOpen
3166 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003167 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003168enddef
3169
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003170def Test_nested_lambda()
3171 var lines =<< trim END
3172 vim9script
3173 def Func()
3174 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003175 var Lambda1 = () => 7
3176 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003177 var res = Lambda2()
3178 assert_equal([7, 4], res)
3179 enddef
3180 Func()
3181 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003182 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003183enddef
3184
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003185def Test_double_nested_lambda()
3186 var lines =<< trim END
3187 vim9script
3188 def F(head: string): func(string): func(string): string
3189 return (sep: string): func(string): string => ((tail: string): string => {
3190 return head .. sep .. tail
3191 })
3192 enddef
3193 assert_equal('hello-there', F('hello')('-')('there'))
3194 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003195 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003196enddef
3197
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003198def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003199 var lines =<< trim END
3200 vim9script
3201 def F(text: string): func(string): func(string): string
3202 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003203 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003204 })
3205 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003206 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003207 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003208 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003209
3210 lines =<< trim END
3211 vim9script
3212 echo range(4)->mapnew((_, v) => {
3213 return range(v) ->mapnew((_, s) => {
3214 return string(s)
3215 })
3216 })
3217 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003218 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003219
3220 lines =<< trim END
3221 vim9script
3222
Bram Moolenaara749a422022-02-12 19:52:25 +00003223 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003224 range(10)
3225 ->mapnew((_, _) => ({
3226 key: range(10)->mapnew((_, _) => {
3227 return ' '
3228 }),
3229 }))
3230 enddef
3231
3232 defcomp
3233 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003234 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003235enddef
3236
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003237def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003238 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003239 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003240enddef
3241
3242def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003243 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003244enddef
3245
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003246def Test_compiling_referenced_func_no_shadow()
3247 var lines =<< trim END
3248 vim9script
3249
3250 def InitializeReply(lspserver: dict<any>)
3251 enddef
3252
3253 def ProcessReply(lspserver: dict<any>)
3254 var lsp_reply_handlers: dict<func> =
3255 { 'initialize': InitializeReply }
3256 lsp_reply_handlers['initialize'](lspserver)
3257 enddef
3258
3259 call ProcessReply({})
3260 END
3261 v9.CheckScriptSuccess(lines)
3262enddef
3263
Bram Moolenaar62aec932022-01-29 21:45:34 +00003264def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003265 var path: string = empty(dir)
3266 \ ? 'empty'
3267 \ : 'full'
3268 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003269enddef
3270
3271def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003272 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003273enddef
3274
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003275def Test_script_var_in_lambda()
3276 var lines =<< trim END
3277 vim9script
3278 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003279 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003280 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003281 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003282enddef
3283
Bram Moolenaar62aec932022-01-29 21:45:34 +00003284def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003285 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003286 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003287 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003288 ->reverse()
3289 return x
3290enddef
3291
3292def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003293 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003294
3295 var lines =<< trim END
3296 vim9script
3297 var res = [{n: 1, m: 2, s: 'xxx'}]
3298 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3299 v.n,
3300 v.m,
3301 substitute(v.s, '.*', 'yyy', '')
3302 ))
3303 assert_equal(['1:2:yyy'], res)
3304 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003305 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003306enddef
3307
Bram Moolenaarb6571982021-01-08 22:24:19 +01003308def Test_list_lambda()
3309 timer_start(1000, (_) => 0)
3310 var body = execute(timer_info()[0].callback
3311 ->string()
3312 ->substitute("('", ' ', '')
3313 ->substitute("')", '', '')
3314 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003315 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003316enddef
3317
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003318def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003319 var lines =<< trim END
3320 vim9script
3321 var flist: list<func>
3322 for i in range(10)
3323 var inloop = i
3324 flist[i] = () => inloop
3325 endfor
3326 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003327 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003328
3329 lines =<< trim END
3330 vim9script
3331 if true
3332 var outloop = 5
3333 var flist: list<func>
3334 for i in range(10)
3335 flist[i] = () => outloop
3336 endfor
3337 endif
3338 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003339 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003340
3341 lines =<< trim END
3342 vim9script
3343 if true
3344 var outloop = 5
3345 endif
3346 var flist: list<func>
3347 for i in range(10)
3348 flist[i] = () => outloop
3349 endfor
3350 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003351 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003352
3353 lines =<< trim END
3354 vim9script
3355 for i in range(10)
3356 var Ref = () => 0
3357 endfor
3358 assert_equal(0, ((i) => 0)(0))
3359 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003360 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003361enddef
3362
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003363def Test_legacy_lambda()
3364 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003365
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003366 var lines =<< trim END
3367 echo {x -> 'hello ' .. x}('foo')
3368 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003369 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003370
3371 lines =<< trim END
3372 vim9script
3373 def Func()
3374 echo (() => 'no error')()
3375 enddef
3376 legacy call s:Func()
3377 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003378 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003379enddef
3380
Bram Moolenaarce024c32021-06-26 13:00:49 +02003381def Test_legacy()
3382 var lines =<< trim END
3383 vim9script
3384 func g:LegacyFunction()
3385 let g:legacyvar = 1
3386 endfunc
3387 def Testit()
3388 legacy call g:LegacyFunction()
3389 enddef
3390 Testit()
3391 assert_equal(1, g:legacyvar)
3392 unlet g:legacyvar
3393 delfunc g:LegacyFunction
3394 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003395 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003396enddef
3397
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003398def Test_legacy_errors()
3399 for cmd in ['if', 'elseif', 'else', 'endif',
3400 'for', 'endfor', 'continue', 'break',
3401 'while', 'endwhile',
3402 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003403 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003404 endfor
3405enddef
3406
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003407def Test_call_legacy_with_dict()
3408 var lines =<< trim END
3409 vim9script
3410 func Legacy() dict
3411 let g:result = self.value
3412 endfunc
3413 def TestDirect()
3414 var d = {value: 'yes', func: Legacy}
3415 d.func()
3416 enddef
3417 TestDirect()
3418 assert_equal('yes', g:result)
3419 unlet g:result
3420
3421 def TestIndirect()
3422 var d = {value: 'foo', func: Legacy}
3423 var Fi = d.func
3424 Fi()
3425 enddef
3426 TestIndirect()
3427 assert_equal('foo', g:result)
3428 unlet g:result
3429
3430 var d = {value: 'bar', func: Legacy}
3431 d.func()
3432 assert_equal('bar', g:result)
3433 unlet g:result
3434 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003435 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003436enddef
3437
Bram Moolenaar62aec932022-01-29 21:45:34 +00003438def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003439 # closure nested inside another closure using argument
3440 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3441 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3442enddef
3443
3444def Test_nested_closure_using_argument()
3445 assert_equal(['x', 'x2'], DoFilterThis('x'))
3446enddef
3447
Bram Moolenaar0186e582021-01-10 18:33:11 +01003448def Test_triple_nested_closure()
3449 var what = 'x'
3450 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3451 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3452 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3453enddef
3454
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003455func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003456 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003457 call Run_Test_silent_echo()
3458endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003459
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003460def Run_Test_silent_echo()
3461 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003462 vim9script
3463 def EchoNothing()
3464 silent echo ''
3465 enddef
3466 defcompile
3467 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003468 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003469
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003470 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003471 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003472 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003473 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003474
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003475 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003476 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003477enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003478
Bram Moolenaar171fb922020-10-28 16:54:47 +01003479def SilentlyError()
3480 execute('silent! invalid')
3481 g:did_it = 'yes'
3482enddef
3483
Bram Moolenaar62aec932022-01-29 21:45:34 +00003484func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003485 silent! invalid
3486endfunc
3487
3488def SilentlyUserError()
3489 UserError()
3490 g:did_it = 'yes'
3491enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003492
3493" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003494func Test_ignore_silent_error()
3495 let g:did_it = 'no'
3496 call SilentlyError()
3497 call assert_equal('yes', g:did_it)
3498
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003499 let g:did_it = 'no'
3500 call SilentlyUserError()
3501 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003502
3503 unlet g:did_it
3504endfunc
3505
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003506def Test_ignore_silent_error_in_filter()
3507 var lines =<< trim END
3508 vim9script
3509 def Filter(winid: number, key: string): bool
3510 if key == 'o'
3511 silent! eval [][0]
3512 return true
3513 endif
3514 return popup_filter_menu(winid, key)
3515 enddef
3516
Bram Moolenaare0de1712020-12-02 17:36:54 +01003517 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003518 feedkeys("o\r", 'xnt')
3519 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003520 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003521enddef
3522
Bram Moolenaar62aec932022-01-29 21:45:34 +00003523def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003524 if n < 2
3525 return n
3526 else
3527 return Fibonacci(n - 1) + Fibonacci(n - 2)
3528 endif
3529enddef
3530
Bram Moolenaar985116a2020-07-12 17:31:09 +02003531def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003532 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003533enddef
3534
Bram Moolenaar62aec932022-01-29 21:45:34 +00003535def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003536 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003537 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003538 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003539 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003540 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003541enddef
3542
3543def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003544 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003545 writefile(['111'], 'XclosureDir/file1')
3546 writefile(['222'], 'XclosureDir/file2')
3547 writefile(['333'], 'XclosureDir/tdir/file3')
3548
Bram Moolenaare0de1712020-12-02 17:36:54 +01003549 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003550enddef
3551
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003552def Test_invalid_function_name()
3553 var lines =<< trim END
3554 vim9script
3555 def s: list<string>
3556 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003557 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003558
3559 lines =<< trim END
3560 vim9script
3561 def g: list<string>
3562 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003563 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003564
3565 lines =<< trim END
3566 vim9script
3567 def <SID>: list<string>
3568 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003569 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003570
3571 lines =<< trim END
3572 vim9script
3573 def F list<string>
3574 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003575 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003576enddef
3577
Bram Moolenaara90afb92020-07-15 22:38:56 +02003578def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003579 var lines =<< trim END
3580 var Xsetlist: func
3581 Xsetlist = function('setloclist', [0])
3582 Xsetlist([], ' ', {title: 'test'})
3583 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003584
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003585 Xsetlist = function('setloclist', [0, [], ' '])
3586 Xsetlist({title: 'test'})
3587 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003588
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003589 Xsetlist = function('setqflist')
3590 Xsetlist([], ' ', {title: 'test'})
3591 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003592
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003593 Xsetlist = function('setqflist', [[], ' '])
3594 Xsetlist({title: 'test'})
3595 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003596
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003597 var Len: func: number = function('len', ['word'])
3598 assert_equal(4, Len())
3599
3600 var RepeatFunc = function('repeat', ['o'])
3601 assert_equal('ooooo', RepeatFunc(5))
3602 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003603 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003604
3605 lines =<< trim END
3606 vim9script
3607 def Foo(Parser: any)
3608 enddef
3609 var Expr: func(dict<any>): dict<any>
3610 const Call = Foo(Expr)
3611 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003612 v9.CheckScriptFailure(lines, 'E1031:')
Bram Moolenaara90afb92020-07-15 22:38:56 +02003613enddef
3614
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003615def Test_partial_double_nested()
3616 var idx = 123
3617 var Get = () => idx
3618 var Ref = function(Get, [])
3619 var RefRef = function(Ref, [])
3620 assert_equal(123, RefRef())
3621enddef
3622
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003623def Test_partial_null_function()
3624 var lines =<< trim END
3625 var d: dict<func> = {f: null_function}
3626 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003627 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003628 END
3629 v9.CheckDefAndScriptSuccess(lines)
3630enddef
3631
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003632def Test_cmd_modifier()
3633 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003634 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003635enddef
3636
3637def Test_restore_modifiers()
3638 # check that when compiling a :def function command modifiers are not messed
3639 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003640 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003641 vim9script
3642 set eventignore=
3643 autocmd QuickFixCmdPost * copen
3644 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003645 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003646 enddef
3647 func Func()
3648 noautocmd call s:AutocmdsDisabled()
3649 let g:ei_after = &eventignore
3650 endfunc
3651 Func()
3652 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003653 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003654 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003655enddef
3656
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003657def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003658 eval 1 + 2
3659 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003660 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003661 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003662enddef
3663
3664def StackBot()
3665 # throw an error
3666 eval [][0]
3667enddef
3668
3669def Test_callstack_def()
3670 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003671 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003672 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003673 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003674 endtry
3675enddef
3676
Bram Moolenaare8211a32020-10-09 22:04:29 +02003677" Re-using spot for variable used in block
3678def Test_block_scoped_var()
3679 var lines =<< trim END
3680 vim9script
3681 def Func()
3682 var x = ['a', 'b', 'c']
3683 if 1
3684 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003685 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003686 endif
3687 var z = x
3688 assert_equal(['x', 'x', 'x'], z)
3689 enddef
3690 Func()
3691 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003692 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003693enddef
3694
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003695def Test_reset_did_emsg()
3696 var lines =<< trim END
3697 @s = 'blah'
3698 au BufWinLeave * #
3699 def Func()
3700 var winid = popup_create('popup', {})
3701 exe '*s'
3702 popup_close(winid)
3703 enddef
3704 Func()
3705 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003706 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003707 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003708enddef
3709
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003710def Test_did_emsg_reset()
3711 # executing an autocommand resets did_emsg, this should not result in a
3712 # builtin function considered failing
3713 var lines =<< trim END
3714 vim9script
3715 au BufWinLeave * #
3716 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003717 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003718 eval [][0]
3719 enddef
3720 nno <F3> <cmd>call <sid>Func()<cr>
3721 feedkeys("\<F3>\e", 'xt')
3722 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003723 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003724 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003725
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003726 nunmap <F3>
3727 au! BufWinLeave
3728enddef
3729
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003730def Test_abort_with_silent_call()
3731 var lines =<< trim END
3732 vim9script
3733 g:result = 'none'
3734 def Func()
3735 g:result += 3
3736 g:result = 'yes'
3737 enddef
3738 # error is silenced, but function aborts on error
3739 silent! Func()
3740 assert_equal('none', g:result)
3741 unlet g:result
3742 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003743 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003744enddef
3745
Bram Moolenaarf665e972020-12-05 19:17:16 +01003746def Test_continues_with_silent_error()
3747 var lines =<< trim END
3748 vim9script
3749 g:result = 'none'
3750 def Func()
3751 silent! g:result += 3
3752 g:result = 'yes'
3753 enddef
3754 # error is silenced, function does not abort
3755 Func()
3756 assert_equal('yes', g:result)
3757 unlet g:result
3758 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003759 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003760enddef
3761
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003762def Test_abort_even_with_silent()
3763 var lines =<< trim END
3764 vim9script
3765 g:result = 'none'
3766 def Func()
3767 eval {-> ''}() .. '' .. {}['X']
3768 g:result = 'yes'
3769 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003770 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003771 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003772 unlet g:result
3773 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003774 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003775enddef
3776
Bram Moolenaarf665e972020-12-05 19:17:16 +01003777def Test_cmdmod_silent_restored()
3778 var lines =<< trim END
3779 vim9script
3780 def Func()
3781 g:result = 'none'
3782 silent! g:result += 3
3783 g:result = 'none'
3784 g:result += 3
3785 enddef
3786 Func()
3787 END
3788 # can't use CheckScriptFailure, it ignores the :silent!
3789 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003790 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003791 var caught = 'no'
3792 try
3793 exe 'source ' .. fname
3794 catch /E1030:/
3795 caught = 'yes'
3796 assert_match('Func, line 4', v:throwpoint)
3797 endtry
3798 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003799enddef
3800
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003801def Test_cmdmod_silent_nested()
3802 var lines =<< trim END
3803 vim9script
3804 var result = ''
3805
3806 def Error()
3807 result ..= 'Eb'
3808 eval [][0]
3809 result ..= 'Ea'
3810 enddef
3811
3812 def Crash()
3813 result ..= 'Cb'
3814 sil! Error()
3815 result ..= 'Ca'
3816 enddef
3817
3818 Crash()
3819 assert_equal('CbEbEaCa', result)
3820 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003821 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003822enddef
3823
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003824def Test_dict_member_with_silent()
3825 var lines =<< trim END
3826 vim9script
3827 g:result = 'none'
3828 var d: dict<any>
3829 def Func()
3830 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003831 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003832 catch
3833 endtry
3834 enddef
3835 silent! Func()
3836 assert_equal('0', g:result)
3837 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003838 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003839 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003840enddef
3841
Bram Moolenaarf9041332021-01-21 19:41:16 +01003842def Test_skip_cmds_with_silent()
3843 var lines =<< trim END
3844 vim9script
3845
3846 def Func(b: bool)
3847 Crash()
3848 enddef
3849
3850 def Crash()
3851 sil! :/not found/d _
3852 sil! :/not found/put _
3853 enddef
3854
3855 Func(true)
3856 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003857 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003858enddef
3859
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003860def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003861 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003862 def g:Opfunc(_: any): string
3863 setline(1, 'ASDF')
3864 return ''
3865 enddef
3866 new
3867 setline(1, 'asdf')
3868 feedkeys("\<F3>$", 'x')
3869 assert_equal('ASDF', getline(1))
3870
3871 bwipe!
3872 nunmap <F3>
3873enddef
3874
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003875func Test_opfunc_error()
3876 CheckScreendump
3877 call Run_Test_opfunc_error()
3878endfunc
3879
3880def Run_Test_opfunc_error()
3881 # test that the error from Opfunc() is displayed right away
3882 var lines =<< trim END
3883 vim9script
3884
3885 def Opfunc(type: string)
3886 try
3887 eval [][0]
3888 catch /nothing/ # error not caught
3889 endtry
3890 enddef
3891 &operatorfunc = Opfunc
3892 nnoremap <expr> l <SID>L()
3893 def L(): string
3894 return 'l'
3895 enddef
3896 'x'->repeat(10)->setline(1)
3897 feedkeys('g@l', 'n')
3898 feedkeys('llll')
3899 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003900 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003901
Bram Moolenaar62aec932022-01-29 21:45:34 +00003902 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3903 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003904 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003905
3906 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003907 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003908enddef
3909
Bram Moolenaar077a4232020-12-22 18:33:27 +01003910" this was crashing on exit
3911def Test_nested_lambda_in_closure()
3912 var lines =<< trim END
3913 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003914 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003915 def Outer()
3916 def g:Inner()
3917 echo map([1, 2, 3], {_, v -> v + 1})
3918 enddef
3919 g:Inner()
3920 enddef
3921 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003922 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003923 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003924 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003925 return
3926 endif
3927 assert_equal(['Done'], readfile('XnestedDone'))
3928 delete('XnestedDone')
3929enddef
3930
Bram Moolenaar92368aa2022-02-07 17:50:39 +00003931def Test_nested_closure_funcref()
3932 var lines =<< trim END
3933 vim9script
3934 def Func()
3935 var n: number
3936 def Nested()
3937 ++n
3938 enddef
3939 Nested()
3940 g:result_one = n
3941 var Ref = function(Nested)
3942 Ref()
3943 g:result_two = n
3944 enddef
3945 Func()
3946 END
3947 v9.CheckScriptSuccess(lines)
3948 assert_equal(1, g:result_one)
3949 assert_equal(2, g:result_two)
3950 unlet g:result_one g:result_two
3951enddef
3952
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00003953def Test_nested_closure_in_dict()
3954 var lines =<< trim END
3955 vim9script
3956 def Func(): dict<any>
3957 var n: number
3958 def Inc(): number
3959 ++n
3960 return n
3961 enddef
3962 return {inc: function(Inc)}
3963 enddef
3964 disas Func
3965 var d = Func()
3966 assert_equal(1, d.inc())
3967 assert_equal(2, d.inc())
3968 END
3969 v9.CheckScriptSuccess(lines)
3970enddef
3971
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003972def Test_script_local_other_script()
3973 var lines =<< trim END
3974 function LegacyJob()
3975 let FuncRef = function('s:close_cb')
3976 endfunction
3977 function s:close_cb(...)
3978 endfunction
3979 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003980 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003981 source Xlegacy.vim
3982 g:LegacyJob()
3983 g:LegacyJob()
3984 g:LegacyJob()
3985
3986 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003987enddef
3988
Bram Moolenaar04947cc2021-03-06 19:26:46 +01003989def Test_check_func_arg_types()
3990 var lines =<< trim END
3991 vim9script
3992 def F1(x: string): string
3993 return x
3994 enddef
3995
3996 def F2(x: number): number
3997 return x + 1
3998 enddef
3999
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004000 def G(Fg: func): dict<func>
4001 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004002 enddef
4003
4004 def H(d: dict<func>): string
4005 return d.f('a')
4006 enddef
4007 END
4008
Bram Moolenaar62aec932022-01-29 21:45:34 +00004009 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4010 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004011
4012 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004013enddef
4014
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004015def Test_call_func_with_null()
4016 var lines =<< trim END
4017 def Fstring(v: string)
4018 assert_equal(null_string, v)
4019 enddef
4020 Fstring(null_string)
4021 def Fblob(v: blob)
4022 assert_equal(null_blob, v)
4023 enddef
4024 Fblob(null_blob)
4025 def Flist(v: list<number>)
4026 assert_equal(null_list, v)
4027 enddef
4028 Flist(null_list)
4029 def Fdict(v: dict<number>)
4030 assert_equal(null_dict, v)
4031 enddef
4032 Fdict(null_dict)
4033 def Ffunc(Fv: func(number): number)
4034 assert_equal(null_function, Fv)
4035 enddef
4036 Ffunc(null_function)
4037 if has('channel')
4038 def Fchannel(v: channel)
4039 assert_equal(null_channel, v)
4040 enddef
4041 Fchannel(null_channel)
4042 def Fjob(v: job)
4043 assert_equal(null_job, v)
4044 enddef
4045 Fjob(null_job)
4046 endif
4047 END
4048 v9.CheckDefAndScriptSuccess(lines)
4049enddef
4050
4051def Test_null_default_argument()
4052 var lines =<< trim END
4053 def Fstring(v: string = null_string)
4054 assert_equal(null_string, v)
4055 enddef
4056 Fstring()
4057 def Fblob(v: blob = null_blob)
4058 assert_equal(null_blob, v)
4059 enddef
4060 Fblob()
4061 def Flist(v: list<number> = null_list)
4062 assert_equal(null_list, v)
4063 enddef
4064 Flist()
4065 def Fdict(v: dict<number> = null_dict)
4066 assert_equal(null_dict, v)
4067 enddef
4068 Fdict()
4069 def Ffunc(Fv: func(number): number = null_function)
4070 assert_equal(null_function, Fv)
4071 enddef
4072 Ffunc()
4073 if has('channel')
4074 def Fchannel(v: channel = null_channel)
4075 assert_equal(null_channel, v)
4076 enddef
4077 Fchannel()
4078 def Fjob(v: job = null_job)
4079 assert_equal(null_job, v)
4080 enddef
4081 Fjob()
4082 endif
4083 END
4084 v9.CheckDefAndScriptSuccess(lines)
4085enddef
4086
4087def Test_null_return()
4088 var lines =<< trim END
4089 def Fstring(): string
4090 return null_string
4091 enddef
4092 assert_equal(null_string, Fstring())
4093 def Fblob(): blob
4094 return null_blob
4095 enddef
4096 assert_equal(null_blob, Fblob())
4097 def Flist(): list<number>
4098 return null_list
4099 enddef
4100 assert_equal(null_list, Flist())
4101 def Fdict(): dict<number>
4102 return null_dict
4103 enddef
4104 assert_equal(null_dict, Fdict())
4105 def Ffunc(): func(number): number
4106 return null_function
4107 enddef
4108 assert_equal(null_function, Ffunc())
4109 if has('channel')
4110 def Fchannel(): channel
4111 return null_channel
4112 enddef
4113 assert_equal(null_channel, Fchannel())
4114 def Fjob(): job
4115 return null_job
4116 enddef
4117 assert_equal(null_job, Fjob())
4118 endif
4119 END
4120 v9.CheckDefAndScriptSuccess(lines)
4121enddef
4122
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004123def Test_list_any_type_checked()
4124 var lines =<< trim END
4125 vim9script
4126 def Foo()
4127 --decl--
4128 Bar(l)
4129 enddef
4130 def Bar(ll: list<dict<any>>)
4131 enddef
4132 Foo()
4133 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004134 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004135 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004136 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004137 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004138 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004139
4140 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004141 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004142enddef
4143
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004144def Test_compile_error()
4145 var lines =<< trim END
4146 def g:Broken()
4147 echo 'a' + {}
4148 enddef
4149 call g:Broken()
4150 END
4151 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004152 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004153
4154 # Second call won't try compiling again
4155 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004156 delfunc g:Broken
4157
4158 # No error when compiling with :silent!
4159 lines =<< trim END
4160 def g:Broken()
4161 echo 'a' + []
4162 enddef
4163 silent! defcompile
4164 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004165 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004166
4167 # Calling the function won't try compiling again
4168 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4169 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004170enddef
4171
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004172def Test_ignored_argument()
4173 var lines =<< trim END
4174 vim9script
4175 def Ignore(_, _): string
4176 return 'yes'
4177 enddef
4178 assert_equal('yes', Ignore(1, 2))
4179
4180 func Ok(_)
4181 return a:_
4182 endfunc
4183 assert_equal('ok', Ok('ok'))
4184
4185 func Oktoo()
4186 let _ = 'too'
4187 return _
4188 endfunc
4189 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004190
4191 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004192 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004193 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004194
4195 lines =<< trim END
4196 def Ignore(_: string): string
4197 return _
4198 enddef
4199 defcompile
4200 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004201 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004202
4203 lines =<< trim END
4204 var _ = 1
4205 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004206 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004207
4208 lines =<< trim END
4209 var x = _
4210 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004211 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004212enddef
4213
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004214def Test_too_many_arguments()
4215 var lines =<< trim END
4216 echo [0, 1, 2]->map(() => 123)
4217 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004218 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004219
4220 lines =<< trim END
4221 echo [0, 1, 2]->map((_) => 123)
4222 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004223 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004224
4225 lines =<< trim END
4226 vim9script
4227 def OneArgument(arg: string)
4228 echo arg
4229 enddef
4230 var Ref = OneArgument
4231 Ref('a', 'b')
4232 END
4233 v9.CheckScriptFailure(lines, 'E118:')
4234enddef
4235
4236def Test_funcref_with_base()
4237 var lines =<< trim END
4238 vim9script
4239 def TwoArguments(str: string, nr: number)
4240 echo str nr
4241 enddef
4242 var Ref = TwoArguments
4243 Ref('a', 12)
4244 'b'->Ref(34)
4245 END
4246 v9.CheckScriptSuccess(lines)
4247
4248 lines =<< trim END
4249 vim9script
4250 def TwoArguments(str: string, nr: number)
4251 echo str nr
4252 enddef
4253 var Ref = TwoArguments
4254 'a'->Ref('b')
4255 END
4256 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4257
4258 lines =<< trim END
4259 vim9script
4260 def TwoArguments(str: string, nr: number)
4261 echo str nr
4262 enddef
4263 var Ref = TwoArguments
4264 123->Ref(456)
4265 END
4266 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4267
4268 lines =<< trim END
4269 vim9script
4270 def TwoArguments(nr: number, str: string)
4271 echo str nr
4272 enddef
4273 var Ref = TwoArguments
4274 123->Ref('b')
4275 def AndNowCompiled()
4276 456->Ref('x')
4277 enddef
4278 AndNowCompiled()
4279 END
4280 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004281enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004282
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004283def Test_closing_brace_at_start_of_line()
4284 var lines =<< trim END
4285 def Func()
4286 enddef
4287 Func(
4288 )
4289 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004290 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004291enddef
4292
Bram Moolenaar62aec932022-01-29 21:45:34 +00004293func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004294 let g:mydict = {}
4295 func g:mydict.afunc()
4296 let g:result = self.key
4297 endfunc
4298endfunc
4299
4300def Test_numbered_function_reference()
4301 CreateMydict()
4302 var output = execute('legacy func g:mydict.afunc')
4303 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4304 execute 'function(' .. funcName .. ', [], {key: 42})()'
4305 # check that the function still exists
4306 assert_equal(output, execute('legacy func g:mydict.afunc'))
4307 unlet g:mydict
4308enddef
4309
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004310def Test_numbered_function_call()
4311 var lines =<< trim END
4312 let s:legacyscript = {}
4313 func s:legacyscript.Helper() abort
4314 return "Success"
4315 endfunc
4316 let g:legacyscript = deepcopy(s:legacyscript)
4317
4318 let g:legacy_result = eval("g:legacyscript.Helper()")
4319 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4320 END
4321 v9.CheckScriptSuccess(lines)
4322 assert_equal('Success', g:legacy_result)
4323 assert_equal('Success', g:vim9_result)
4324
4325 unlet g:legacy_result
4326 unlet g:vim9_result
4327enddef
4328
Bram Moolenaard3a11782022-01-05 16:50:40 +00004329def Test_go_beyond_end_of_cmd()
4330 # this was reading the byte after the end of the line
4331 var lines =<< trim END
4332 def F()
4333 cal
4334 enddef
4335 defcompile
4336 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004337 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004338enddef
4339
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004340" Test for memory allocation failure when defining a new lambda
4341func Test_lambda_allocation_failure()
4342 new
4343 let lines =<< trim END
4344 vim9script
4345 g:Xlambda = (x): number => {
4346 return x + 1
4347 }
4348 END
4349 call setline(1, lines)
4350 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4351 call assert_fails('source', 'E342:')
4352 call assert_false(exists('g:Xlambda'))
4353 bw!
4354endfunc
4355
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004356def Test_lambda_argument_type_check()
4357 var lines =<< trim END
4358 vim9script
4359
4360 def Scan(ll: list<any>): func(func(any))
4361 return (Emit: func(any)) => {
4362 for e in ll
4363 Emit(e)
4364 endfor
4365 }
4366 enddef
4367
4368 def Sum(Cont: func(func(any))): any
4369 var sum = 0.0
4370 Cont((v: float) => { # <== NOTE: the lambda expects a float
4371 sum += v
4372 })
4373 return sum
4374 enddef
4375
Bram Moolenaar47bba532023-01-20 18:49:46 +00004376 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004377 echo Scan(ml)->Sum()
4378 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004379 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004380enddef
4381
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004382def Test_multiple_funcref()
4383 # This was using a NULL pointer
4384 var lines =<< trim END
4385 vim9script
4386 def A(F: func, ...args: list<any>): func
4387 return funcref(F, args)
4388 enddef
4389
4390 def B(F: func): func
4391 return funcref(A, [F])
4392 enddef
4393
4394 def Test(n: number)
4395 enddef
4396
4397 const X = B(Test)
4398 X(1)
4399 END
4400 v9.CheckScriptSuccess(lines)
4401
4402 # slightly different case
4403 lines =<< trim END
4404 vim9script
4405
4406 def A(F: func, ...args: list<any>): any
4407 return call(F, args)
4408 enddef
4409
4410 def B(F: func): func
4411 return funcref(A, [F])
4412 enddef
4413
4414 def Test(n: number)
4415 enddef
4416
4417 const X = B(Test)
4418 X(1)
4419 END
4420 v9.CheckScriptSuccess(lines)
4421enddef
4422
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004423def Test_cexpr_errmsg_line_number()
4424 var lines =<< trim END
4425 vim9script
4426 def Func()
4427 var qfl = {}
4428 cexpr qfl
4429 enddef
4430 Func()
4431 END
4432 v9.CheckScriptFailure(lines, 'E777', 2)
4433enddef
4434
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004435def AddDefer(s: string)
4436 g:deferred->extend([s])
4437enddef
4438
4439def DeferTwo()
4440 g:deferred->extend(['in Two'])
4441 for n in range(3)
4442 defer g:AddDefer('two' .. n)
4443 endfor
4444 g:deferred->extend(['end Two'])
4445enddef
4446
4447def DeferOne()
4448 g:deferred->extend(['in One'])
4449 defer g:AddDefer('one')
4450 g:DeferTwo()
4451 g:deferred->extend(['end One'])
4452
4453 writefile(['text'], 'XdeferFile')
4454 defer delete('XdeferFile')
4455enddef
4456
4457def Test_defer()
4458 g:deferred = []
4459 g:DeferOne()
4460 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4461 unlet g:deferred
4462 assert_equal('', glob('XdeferFile'))
4463enddef
4464
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004465def Test_invalid_redir()
4466 var lines =<< trim END
4467 def Tone()
4468 if 1
4469 redi =>@�0
4470 redi END
4471 endif
4472 enddef
4473 defcompile
4474 END
4475 v9.CheckScriptFailure(lines, 'E354:')
4476 delfunc g:Tone
4477
4478 # this was reading past the end of the line
4479 lines =<< trim END
4480 def Ttwo()
4481 if 0
4482 redi =>@�0
4483 redi END
4484 endif
4485 enddef
4486 defcompile
4487 END
4488 v9.CheckScriptFailure(lines, 'E354:')
4489 delfunc g:Ttwo
4490enddef
4491
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004492func Test_keytyped_in_nested_function()
4493 CheckRunVimInTerminal
4494
4495 call Run_Test_keytyped_in_nested_function()
4496endfunc
4497
4498def Run_Test_keytyped_in_nested_function()
4499 var lines =<< trim END
4500 vim9script
4501 autocmd CmdlineEnter * sample#Init()
4502
4503 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4504 END
4505 writefile(lines, 'Xkeytyped', 'D')
4506
4507 var dir = 'Xrtpdir/autoload'
4508 mkdir(dir, 'pR')
4509
4510 lines =<< trim END
4511 vim9script
4512 export def Init(): void
4513 cnoremap <expr>" <SID>Quote('"')
4514 enddef
4515 def Quote(str: string): string
4516 def InPair(): number
4517 return 0
4518 enddef
4519 return str
4520 enddef
4521 END
4522 writefile(lines, dir .. '/sample.vim')
4523
4524 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4525
4526 term_sendkeys(buf, ':"')
4527 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4528
4529 # clean up
4530 term_sendkeys(buf, "\<Esc>")
4531 g:StopVimInTerminal(buf)
4532enddef
4533
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004534" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004535if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004536 def Test_python3_command()
4537 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004538 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004539 assert_equal('yes', g:done)
4540 unlet g:done
4541 enddef
4542
Bram Moolenaar20677332021-06-06 17:02:53 +02004543 def Test_python3_heredoc()
4544 py3 << trim EOF
4545 import vim
4546 vim.vars['didit'] = 'yes'
4547 EOF
4548 assert_equal('yes', g:didit)
4549
4550 python3 << trim EOF
4551 import vim
4552 vim.vars['didit'] = 'again'
4553 EOF
4554 assert_equal('again', g:didit)
4555 enddef
4556endif
4557
Bram Moolenaar20677332021-06-06 17:02:53 +02004558if has('lua')
4559 def Test_lua_heredoc()
4560 g:d = {}
4561 lua << trim EOF
4562 x = vim.eval('g:d')
4563 x['key'] = 'val'
4564 EOF
4565 assert_equal('val', g:d.key)
4566 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004567
4568 def Test_lua_heredoc_fails()
4569 var lines = [
4570 'vim9script',
4571 'def ExeLua()',
4572 'lua << trim EOLUA',
4573 "x = vim.eval('g:nodict')",
4574 'EOLUA',
4575 'enddef',
4576 'ExeLua()',
4577 ]
4578 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4579 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004580endif
4581
Bram Moolenaard881d152022-05-13 13:50:36 +01004582if has('perl')
4583 def Test_perl_heredoc_nested()
4584 var lines =<< trim END
4585 vim9script
4586 def F(): string
4587 def G(): string
4588 perl << EOF
4589 EOF
4590 return 'done'
4591 enddef
4592 return G()
4593 enddef
4594 assert_equal('done', F())
4595 END
4596 v9.CheckScriptSuccess(lines)
4597 enddef
4598endif
4599
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004600
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004601" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker