blob: 0f28ba038ff712b9394a0dfee34d1938e90b017b [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 Moolenaar47bba532023-01-20 18:49:46 +0000755def Test_convert_number_to_float()
756 var lines =<< trim END
757 vim9script
758 def Foo(a: float, b: float): float
759 return a + b
760 enddef
761
762 assert_equal(5.3, Foo(3.3, 2))
763 END
764 v9.CheckScriptSuccess(lines)
765enddef
766
Bram Moolenaar62aec932022-01-29 21:45:34 +0000767def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100768 a: number, #comment
769 b: bool, # comment
770 c: string) #comment
771 assert_equal(4, a)
772 assert_equal(true, b)
773 assert_equal('yes', c)
774enddef
775
776def Test_func_with_comments()
777 FuncWithComment(4, true, 'yes')
778
779 var lines =<< trim END
780 def Func(# comment
781 arg: string)
782 enddef
783 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000784 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100785
786 lines =<< trim END
787 def Func(
788 arg: string# comment
789 )
790 enddef
791 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000792 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100793
794 lines =<< trim END
795 def Func(
796 arg: string
797 )# comment
798 enddef
799 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000800 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100801enddef
802
Bram Moolenaar04b12692020-05-04 23:24:44 +0200803def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000804 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200805 return 'nested ' .. arg
806 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000807 NestedDef(':def')->assert_equal('nested :def')
808
809 func NestedFunc(arg)
810 return 'nested ' .. a:arg
811 endfunc
812 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200813
Bram Moolenaar62aec932022-01-29 21:45:34 +0000814 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
815 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200816
Bram Moolenaar62aec932022-01-29 21:45:34 +0000817 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
818 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200819
Bram Moolenaar54021752020-12-06 18:50:36 +0100820 var lines =<< trim END
821 def Outer()
822 def Inner()
823 # comment
824 enddef
825 def Inner()
826 enddef
827 enddef
828 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000829 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100830
831 lines =<< trim END
832 def Outer()
833 def Inner()
834 # comment
835 enddef
836 def! Inner()
837 enddef
838 enddef
839 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000840 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100841
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000842 lines =<< trim END
843 vim9script
844 def Outer()
845 def Inner()
846 g:result = 'ok'
847 enddef
848 Inner()
849 enddef
850 Outer()
851 Inner()
852 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000853 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000854 assert_equal('ok', g:result)
855 unlet g:result
856
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000857 lines =<< trim END
858 vim9script
859 def Outer()
860 def _Inner()
861 echo 'bad'
862 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000863 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000864 enddef
865 defcompile
866 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000867 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000868
869 lines =<< trim END
870 vim9script
871 def Outer()
872 def g:inner()
873 echo 'bad'
874 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000875 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000876 enddef
877 defcompile
878 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000879 v9.CheckScriptFailure(lines, 'E1267:')
880
881 lines =<< trim END
882 vim9script
883 def g:_Func()
884 echo 'bad'
885 enddef
886 END
887 v9.CheckScriptFailure(lines, 'E1267:')
888
889 lines =<< trim END
890 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000891 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +0000892 echo 'bad'
893 enddef
894 END
895 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000896
Bram Moolenaar54021752020-12-06 18:50:36 +0100897 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +0100898 lines =<< trim END
899 vim9script
900 var thecount = 0
901 if true
902 def Test(): number
903 def TheFunc(): number
904 thecount += 1
905 return thecount
906 enddef
907 return TheFunc()
908 enddef
909 endif
910 defcompile
911 assert_equal(1, Test())
912 assert_equal(2, Test())
913 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000914 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +0100915
916 # also works when "thecount" is inside the "if" block
917 lines =<< trim END
918 vim9script
919 if true
920 var thecount = 0
921 def Test(): number
922 def TheFunc(): number
923 thecount += 1
924 return thecount
925 enddef
926 return TheFunc()
927 enddef
928 endif
929 defcompile
930 assert_equal(1, Test())
931 assert_equal(2, Test())
932 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000933 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200934
Bram Moolenaara915fa02022-03-23 11:29:15 +0000935 # nested function with recursive call
936 lines =<< trim END
937 vim9script
938
939 def MyFunc(): number
940 def Fib(n: number): number
941 if n < 2
942 return 1
943 endif
944 return Fib(n - 2) + Fib(n - 1)
945 enddef
946
947 return Fib(5)
948 enddef
949
950 assert_equal(8, MyFunc())
951 END
952 v9.CheckScriptSuccess(lines)
953
Bram Moolenaar4bba16d2021-08-15 19:28:05 +0200954 lines =<< trim END
955 vim9script
956 def Outer()
957 def Inner()
958 echo 'hello'
959 enddef burp
960 enddef
961 defcompile
962 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000963 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200964enddef
965
Bram Moolenaar1889f492022-08-16 19:34:44 +0100966def Test_nested_function_fails()
967 var lines =<< trim END
968 def T()
969 def Func(g: string):string
970 enddef
971 Func()
972 enddef
973 silent! defcompile
974 END
975 v9.CheckScriptFailure(lines, 'E1069:')
976enddef
977
Bram Moolenaaradc8e442020-12-31 18:28:18 +0100978def Test_not_nested_function()
979 echo printf('%d',
980 function('len')('xxx'))
981enddef
982
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200983func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200984 call MyDefaultArgs()->assert_equal('string')
985 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200986 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200987endfunc
988
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200989def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200990 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200991 vim9script
992 def Outer()
993 def g:Inner(): string
994 return 'inner'
995 enddef
996 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200997 defcompile
998 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200999 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001000 delfunc g:Inner
1001 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001002 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001003 delfunc g:Inner
1004 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001005 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001006 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001007 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001008 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001009
1010 lines =<< trim END
1011 vim9script
1012 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001013 func g:Inner()
1014 return 'inner'
1015 endfunc
1016 enddef
1017 defcompile
1018 Outer()
1019 g:Inner()->assert_equal('inner')
1020 delfunc g:Inner
1021 Outer()
1022 g:Inner()->assert_equal('inner')
1023 delfunc g:Inner
1024 Outer()
1025 g:Inner()->assert_equal('inner')
1026 delfunc g:Inner
1027 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001028 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001029
1030 lines =<< trim END
1031 vim9script
1032 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001033 def g:Inner(): string
1034 return 'inner'
1035 enddef
1036 enddef
1037 defcompile
1038 Outer()
1039 Outer()
1040 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001041 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001042 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001043
1044 lines =<< trim END
1045 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001046 def Outer()
1047 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001048 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001049 enddef
1050 g:Inner()
1051 enddef
1052 Outer()
1053 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001054 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001055 delfunc g:Inner
1056
1057 lines =<< trim END
1058 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001059 def Func()
1060 echo 'script'
1061 enddef
1062 def Outer()
1063 def Func()
1064 echo 'inner'
1065 enddef
1066 enddef
1067 defcompile
1068 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001069 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001070
1071 lines =<< trim END
1072 vim9script
1073 def Func()
1074 echo 'script'
1075 enddef
1076 def Func()
1077 echo 'script'
1078 enddef
1079 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001080 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001081enddef
1082
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001083def DefListAll()
1084 def
1085enddef
1086
1087def DefListOne()
1088 def DefListOne
1089enddef
1090
1091def DefListMatches()
1092 def /DefList
1093enddef
1094
1095def Test_nested_def_list()
1096 var funcs = split(execute('call DefListAll()'), "\n")
1097 assert_true(len(funcs) > 10)
1098 assert_true(funcs->index('def DefListAll()') >= 0)
1099
1100 funcs = split(execute('call DefListOne()'), "\n")
1101 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1102
1103 funcs = split(execute('call DefListMatches()'), "\n")
1104 assert_true(len(funcs) >= 3)
1105 assert_true(funcs->index('def DefListAll()') >= 0)
1106 assert_true(funcs->index('def DefListOne()') >= 0)
1107 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001108
1109 var lines =<< trim END
1110 vim9script
1111 def Func()
1112 def +Func+
1113 enddef
1114 defcompile
1115 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001116 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001117enddef
1118
Bram Moolenaare08be092022-02-17 13:08:26 +00001119def Test_global_function_not_found()
1120 var lines =<< trim END
1121 g:Ref = 123
1122 call g:Ref()
1123 END
1124 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1125enddef
1126
Bram Moolenaar333894b2020-08-01 18:53:07 +02001127def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001128 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001129 vim9script
1130 def g:Func(): string
1131 return 'global'
1132 enddef
1133 def Func(): string
1134 return 'local'
1135 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001136 g:Func()->assert_equal('global')
1137 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001138 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001139 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001140 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001141
1142 lines =<< trim END
1143 vim9script
1144 def g:Funcy()
1145 echo 'funcy'
1146 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001147 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001148 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001149 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001150enddef
1151
Bram Moolenaar0f769812020-09-12 18:32:34 +02001152def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001153 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001154 vim9script
1155 def g:Gfunc(): string
1156 return 'global'
1157 enddef
1158 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001159 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001160 return Gfunc('testing')
1161 enddef
1162 g:Gfunc()->assert_equal('global')
1163 AnotherFunc()->assert_equal(7)
1164 delfunc g:Gfunc
1165 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001166 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001167
1168 lines =<< trim END
1169 vim9script
1170 def g:Func(): string
1171 return 'global'
1172 enddef
1173 def AnotherFunc()
1174 g:Func = function('len')
1175 enddef
1176 AnotherFunc()
1177 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001178 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001179 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001180
Bram Moolenaar62aec932022-01-29 21:45:34 +00001181 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001182 lines =<< trim END
1183 vim9script
1184 def g:Func(): string
1185 return 'global'
1186 enddef
1187 def AnotherFunc(): string
1188 return Func()
1189 enddef
1190 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001191 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001192 v9.CheckScriptFailure(lines, 'E117:')
1193 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001194
1195 lines =<< trim END
1196 vim9script
1197 def g:Func(): string
1198 return 'global'
1199 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001200 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001201 delfunc g:Func
1202 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001203 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001204
1205 # This does not shadow "i" which is visible only inside the for loop
1206 lines =<< trim END
1207 vim9script
1208
1209 def Foo(i: number)
1210 echo i
1211 enddef
1212
1213 for i in range(3)
1214 # Foo() is compiled here
1215 Foo(i)
1216 endfor
1217 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001218 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001219enddef
1220
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001221func TakesOneArg(arg)
1222 echo a:arg
1223endfunc
1224
1225def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001226 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1227 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1228 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1229 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001230
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001231 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001232 vim9script
1233 def Func(s: string)
1234 echo s
1235 enddef
1236 Func([])
1237 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001238 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001239
Bram Moolenaar9a015112021-12-31 14:06:45 +00001240 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001241 lines =<< trim END
1242 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001243 var name = 'piet'
1244 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001245 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001246 enddef
1247 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001248 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001249
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001250 # same, inside the same block
1251 lines =<< trim END
1252 vim9script
1253 if true
1254 var name = 'piet'
1255 def FuncOne(name: string)
1256 echo name
1257 enddef
1258 endif
1259 END
1260 v9.CheckScriptFailure(lines, 'E1168:')
1261
1262 # variable in other block is OK
1263 lines =<< trim END
1264 vim9script
1265 if true
1266 var name = 'piet'
1267 endif
1268 def FuncOne(name: string)
1269 echo name
1270 enddef
1271 END
1272 v9.CheckScriptSuccess(lines)
1273
Bram Moolenaardce24412022-02-08 20:35:30 +00001274 # with another variable in another block
1275 lines =<< trim END
1276 vim9script
1277 if true
1278 var name = 'piet'
1279 # define a function so that the variable isn't cleared
1280 def GetItem(): string
1281 return item
1282 enddef
1283 endif
1284 if true
1285 var name = 'peter'
1286 def FuncOne(name: string)
1287 echo name
1288 enddef
1289 endif
1290 END
1291 v9.CheckScriptFailure(lines, 'E1168:')
1292
1293 # only variable in another block is OK
1294 lines =<< trim END
1295 vim9script
1296 if true
1297 var name = 'piet'
1298 # define a function so that the variable isn't cleared
1299 def GetItem(): string
1300 return item
1301 enddef
1302 endif
1303 if true
1304 def FuncOne(name: string)
1305 echo name
1306 enddef
1307 endif
1308 END
1309 v9.CheckScriptSuccess(lines)
1310
Bram Moolenaar9a015112021-12-31 14:06:45 +00001311 # argument name declared later is only found when compiling
1312 lines =<< trim END
1313 vim9script
1314 def FuncOne(name: string)
1315 echo nr
1316 enddef
1317 var name = 'piet'
1318 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001319 v9.CheckScriptSuccess(lines)
1320 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001321
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001322 lines =<< trim END
1323 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001324 def FuncOne(nr: number)
1325 echo nr
1326 enddef
1327 def FuncTwo()
1328 FuncOne()
1329 enddef
1330 defcompile
1331 END
1332 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001333 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001334 try
1335 source Xscript
1336 catch
1337 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1338 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1339 didCatch = true
1340 endtry
1341 assert_true(didCatch)
1342
1343 lines =<< trim END
1344 vim9script
1345 def FuncOne(nr: number)
1346 echo nr
1347 enddef
1348 def FuncTwo()
1349 FuncOne(1, 2)
1350 enddef
1351 defcompile
1352 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001353 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001354 didCatch = false
1355 try
1356 source Xscript
1357 catch
1358 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1359 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1360 didCatch = true
1361 endtry
1362 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001363enddef
1364
Bram Moolenaar50824712020-12-20 21:10:17 +01001365def Test_call_funcref_wrong_args()
1366 var head =<< trim END
1367 vim9script
1368 def Func3(a1: string, a2: number, a3: list<number>)
1369 echo a1 .. a2 .. a3[0]
1370 enddef
1371 def Testme()
1372 var funcMap: dict<func> = {func: Func3}
1373 END
1374 var tail =<< trim END
1375 enddef
1376 Testme()
1377 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001378 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001379
Bram Moolenaar62aec932022-01-29 21:45:34 +00001380 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1381 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001382
1383 var lines =<< trim END
1384 vim9script
1385 var Ref: func(number): any
1386 Ref = (j) => !j
1387 echo Ref(false)
1388 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001389 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001390
1391 lines =<< trim END
1392 vim9script
1393 var Ref: func(number): any
1394 Ref = (j) => !j
1395 call Ref(false)
1396 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001397 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001398enddef
1399
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001400def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001401 var lines =<< trim END
1402 var Callback = (..._) => 'anything'
1403 assert_equal('anything', Callback())
1404 assert_equal('anything', Callback(1))
1405 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001406
1407 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001408 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001409 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001410
Bram Moolenaar62aec932022-01-29 21:45:34 +00001411 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001412 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001413
Bram Moolenaar2a389082021-04-09 20:24:31 +02001414 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001415 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001416 echo Ref(1, 'x')
1417 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001418 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001419
1420 lines =<< trim END
1421 var Ref: func(job, string, number)
1422 Ref = (x, y) => 0
1423 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001424 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001425
1426 lines =<< trim END
1427 var Ref: func(job, string)
1428 Ref = (x, y, z) => 0
1429 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001430 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001431
1432 lines =<< trim END
1433 var one = 1
1434 var l = [1, 2, 3]
1435 echo map(l, (one) => one)
1436 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001437 v9.CheckDefFailure(lines, 'E1167:')
1438 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001439
1440 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001441 var Ref: func(any, ?any): bool
1442 Ref = (_, y = 1) => false
1443 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001444 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001445
1446 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001447 var a = 0
1448 var b = (a == 0 ? 1 : 2)
1449 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001450 var txt = 'a'
1451 b = (txt =~ 'x' ? 1 : 2)
1452 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001453 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001454 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001455
1456 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001457 def ShadowLocal()
1458 var one = 1
1459 var l = [1, 2, 3]
1460 echo map(l, (one) => one)
1461 enddef
1462 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001463 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001464
1465 lines =<< trim END
1466 def Shadowarg(one: number)
1467 var l = [1, 2, 3]
1468 echo map(l, (one) => one)
1469 enddef
1470 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001471 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001472
1473 lines =<< trim END
1474 echo ((a) => a)('aa', 'bb')
1475 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001476 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001477
1478 lines =<< trim END
1479 echo 'aa'->((a) => a)('bb')
1480 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001481 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1482 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001483enddef
1484
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001485def Test_lambda_line_nr()
1486 var lines =<< trim END
1487 vim9script
1488 # comment
1489 # comment
1490 var id = timer_start(1'000, (_) => 0)
1491 var out = execute('verbose ' .. timer_info(id)[0].callback
1492 ->string()
1493 ->substitute("('\\|')", ' ', 'g'))
1494 assert_match('Last set from .* line 4', out)
1495 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001496 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001497enddef
1498
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001499def FilterWithCond(x: string, Cond: func(string): bool): bool
1500 return Cond(x)
1501enddef
1502
Bram Moolenaar0346b792021-01-31 22:18:29 +01001503def Test_lambda_return_type()
1504 var lines =<< trim END
1505 var Ref = (): => 123
1506 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001507 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001508
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001509 # no space before the return type
1510 lines =<< trim END
1511 var Ref = (x):number => x + 1
1512 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001513 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001514
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001515 # this works
1516 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001517 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001518 endfor
1519
1520 # this fails
1521 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001522 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001523 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001524 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 +02001525
1526 lines =<< trim END
1527 var Lambda1 = (x) => {
1528 return x
1529 }
1530 assert_equal('asdf', Lambda1('asdf'))
1531 var Lambda2 = (x): string => {
1532 return x
1533 }
1534 assert_equal('foo', Lambda2('foo'))
1535 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001536 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001537
1538 lines =<< trim END
1539 var Lambda = (x): string => {
1540 return x
1541 }
1542 echo Lambda(['foo'])
1543 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001544 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001545enddef
1546
Bram Moolenaar709664c2020-12-12 14:33:41 +01001547def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001548 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001549 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001550 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001551enddef
1552
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001553def Test_lambda_invalid_block()
1554 var lines =<< trim END
1555 timer_start(0, (_) => { # echo
1556 echo 'yes'
1557 })
1558 END
1559 v9.CheckDefAndScriptSuccess(lines)
1560
1561 lines =<< trim END
1562 timer_start(0, (_) => { " echo
1563 echo 'yes'
1564 })
1565 END
1566 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1567
1568 lines =<< trim END
1569 timer_start(0, (_) => { | echo
1570 echo 'yes'
1571 })
1572 END
1573 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1574enddef
1575
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001576def Test_lambda_with_following_cmd()
1577 var lines =<< trim END
1578 set ts=2
1579 var Lambda = () => {
1580 set ts=4
1581 } | set ts=3
1582 assert_equal(3, &ts)
1583 Lambda()
1584 assert_equal(4, &ts)
1585 END
1586 v9.CheckDefAndScriptSuccess(lines)
1587 set ts=8
1588enddef
1589
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001590def Test_pass_legacy_lambda_to_def_func()
1591 var lines =<< trim END
1592 vim9script
1593 func Foo()
1594 eval s:Bar({x -> 0})
1595 endfunc
1596 def Bar(y: any)
1597 enddef
1598 Foo()
1599 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001600 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001601
1602 lines =<< trim END
1603 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001604 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001605 enddef
1606 legacy call g:TestFunc({-> 0})
1607 delfunc g:TestFunc
1608
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001609 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001610 enddef
1611 legacy call g:TestFunc({nr -> 0})
1612 delfunc g:TestFunc
1613 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001614 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001615enddef
1616
Bram Moolenaar844fb642021-10-23 13:32:30 +01001617def Test_lambda_in_reduce_line_break()
1618 # this was using freed memory
1619 var lines =<< trim END
1620 vim9script
1621 const result: dict<number> =
1622 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1623 ->reduce((acc, val) => {
1624 if has_key(acc, val)
1625 acc[val] += 1
1626 return acc
1627 else
1628 acc[val] = 1
1629 return acc
1630 endif
1631 }, {})
1632 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1633 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001634 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001635enddef
1636
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001637def Test_set_opfunc_to_lambda()
1638 var lines =<< trim END
1639 vim9script
1640 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1641 def CountSpaces(type = ''): string
1642 if type == ''
1643 &operatorfunc = (t) => CountSpaces(t)
1644 return 'g@'
1645 endif
1646 normal! '[V']y
1647 g:result = getreg('"')->count(' ')
1648 return ''
1649 enddef
1650 new
1651 'a b c d e'->setline(1)
1652 feedkeys("\<F4>", 'x')
1653 assert_equal(4, g:result)
1654 bwipe!
1655 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001656 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001657enddef
1658
Bram Moolenaaref082e12021-12-12 21:02:03 +00001659def Test_set_opfunc_to_global_function()
1660 var lines =<< trim END
1661 vim9script
1662 def g:CountSpaces(type = ''): string
1663 normal! '[V']y
1664 g:result = getreg('"')->count(' ')
1665 return ''
1666 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001667 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001668 &operatorfunc = g:CountSpaces
1669 new
1670 'a b c d e'->setline(1)
1671 feedkeys("g@_", 'x')
1672 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001673
1674 &operatorfunc = ''
1675 g:result = 0
1676 # global function works in :def function
1677 def Func()
1678 &operatorfunc = g:CountSpaces
1679 enddef
1680 Func()
1681 feedkeys("g@_", 'x')
1682 assert_equal(4, g:result)
1683
Bram Moolenaaref082e12021-12-12 21:02:03 +00001684 bwipe!
1685 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001686 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001687 &operatorfunc = ''
1688enddef
1689
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001690def Test_use_script_func_name_with_prefix()
1691 var lines =<< trim END
1692 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001693 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001694 return 'it'
1695 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001696 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001697 assert_equal('it', Fn())
1698 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001699 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001700enddef
1701
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001702def Test_lambda_type_allocated()
1703 # Check that unreferencing a partial using a lambda can use the variable type
1704 # after the lambda has been freed and does not leak memory.
1705 var lines =<< trim END
1706 vim9script
1707
1708 func MyomniFunc1(val, findstart, base)
1709 return a:findstart ? 0 : []
1710 endfunc
1711
1712 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1713 &omnifunc = Lambda
1714 Lambda = (a, b) => MyomniFunc1(20, a, b)
1715 &omnifunc = string(Lambda)
1716 Lambda = (a, b) => strlen(a)
1717 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001718 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001719enddef
1720
Bram Moolenaara7583c42022-05-07 21:14:05 +01001721def Test_define_lambda_in_execute()
1722 var lines =<< trim [CODE]
1723 vim9script
1724
1725 def BuildFuncMultiLine(): func
1726 var x =<< trim END
1727 g:SomeRandomFunc = (d: dict<any>) => {
1728 return d.k1 + d.k2
1729 }
1730 END
1731 execute(x)
1732 return g:SomeRandomFunc
1733 enddef
1734 var ResultPlus = BuildFuncMultiLine()
1735 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1736 [CODE]
1737 v9.CheckScriptSuccess(lines)
1738 unlet g:SomeRandomFunc
1739enddef
1740
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001741" Default arg and varargs
1742def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001743 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001744 for s in rest
1745 res ..= ',' .. s
1746 endfor
1747 return res
1748enddef
1749
1750def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001751 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1752 g:MyDefVarargs('one')->assert_equal('one,foo')
1753 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1754 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1755 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001756 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001757 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001758 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001759
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001760 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001761 vim9script
1762 def Func(...l: list<string>)
1763 echo l
1764 enddef
1765 Func('a', 'b', 'c')
1766 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001767 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001768
1769 lines =<< trim END
1770 vim9script
1771 def Func(...l: list<string>)
1772 echo l
1773 enddef
1774 Func()
1775 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001776 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001777
1778 lines =<< trim END
1779 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001780 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001781 echo l
1782 enddef
1783 Func(0)
1784 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001785 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001786
1787 lines =<< trim END
1788 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001789 def Func(...l: any)
1790 echo l
1791 enddef
1792 Func(0)
1793 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001794 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001795
1796 lines =<< trim END
1797 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001798 def Func(..._l: list<string>)
1799 echo _l
1800 enddef
1801 Func('a', 'b', 'c')
1802 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001803 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001804
1805 lines =<< trim END
1806 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001807 def Func(...l: list<string>)
1808 echo l
1809 enddef
1810 Func(1, 2, 3)
1811 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001812 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001813
1814 lines =<< trim END
1815 vim9script
1816 def Func(...l: list<string>)
1817 echo l
1818 enddef
1819 Func('a', 9)
1820 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001821 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001822
1823 lines =<< trim END
1824 vim9script
1825 def Func(...l: list<string>)
1826 echo l
1827 enddef
1828 Func(1, 'a')
1829 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001830 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001831
1832 lines =<< trim END
1833 vim9script
1834 def Func( # some comment
1835 ...l = []
1836 )
1837 echo l
1838 enddef
1839 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001840 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001841
1842 lines =<< trim END
1843 vim9script
1844 def DoIt()
1845 g:Later('')
1846 enddef
1847 defcompile
1848 def g:Later(...l: list<number>)
1849 enddef
1850 DoIt()
1851 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001852 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001853enddef
1854
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001855let s:value = ''
1856
1857def FuncOneDefArg(opt = 'text')
1858 s:value = opt
1859enddef
1860
1861def FuncTwoDefArg(nr = 123, opt = 'text'): string
1862 return nr .. opt
1863enddef
1864
1865def FuncVarargs(...arg: list<string>): string
1866 return join(arg, ',')
1867enddef
1868
1869def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001870 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001871 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001872 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001873 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001874 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001875 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001876
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001877 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001878 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001879 RefDef2Arg()->assert_equal('123text')
1880 RefDef2Arg(99)->assert_equal('99text')
1881 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001882
Bram Moolenaar62aec932022-01-29 21:45:34 +00001883 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
1884 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001885
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001886 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001887 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001888 RefVarargs()->assert_equal('')
1889 RefVarargs('one')->assert_equal('one')
1890 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001891
Bram Moolenaar62aec932022-01-29 21:45:34 +00001892 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
1893 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001894enddef
1895
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001896" Only varargs
1897def MyVarargsOnly(...args: list<string>): string
1898 return join(args, ',')
1899enddef
1900
1901def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001902 g:MyVarargsOnly()->assert_equal('')
1903 g:MyVarargsOnly('one')->assert_equal('one')
1904 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
1905 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
1906 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001907enddef
1908
Bram Moolenaar36818a92023-01-03 12:33:26 +00001909def Test_varargs_mismatch()
1910 var lines =<< trim END
1911 vim9script
1912
1913 def Map(Fn: func(...any): number): number
1914 return Fn('12')
1915 enddef
1916
1917 var res = Map((v) => str2nr(v))
1918 assert_equal(12, res)
1919 END
1920 v9.CheckScriptSuccess(lines)
1921enddef
1922
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001923def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00001924 var lines =<< trim END
1925 def Func(x: number)
1926 var x = 234
1927 enddef
1928 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001929 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00001930
1931 lines =<< trim END
1932 def Func(Ref: number)
1933 def Ref()
1934 enddef
1935 enddef
1936 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001937 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001938enddef
1939
Bram Moolenaar62aec932022-01-29 21:45:34 +00001940def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001941 arg['key'] = 'value'
1942enddef
1943
Bram Moolenaar62aec932022-01-29 21:45:34 +00001944def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001945 arg[0] = 'value'
1946enddef
1947
1948def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001949 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001950 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001951 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001952 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001953 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001954 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001955 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001956
Bram Moolenaar62aec932022-01-29 21:45:34 +00001957 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001958 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02001959enddef
1960
Bram Moolenaarb816dae2020-09-20 22:04:00 +02001961" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00001962def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02001963 return firstline .. lastline
1964enddef
1965
1966def Test_argument_names()
1967 assert_equal('OK', WithReservedNames('O', 'K'))
1968enddef
1969
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001970def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001971 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001972 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001973enddef
1974
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02001975func DefinedLater(arg)
1976 return a:arg
1977endfunc
1978
1979def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001980 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001981 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00001982 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02001983
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001984 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02001985 vim9script
1986 def RetNumber(): number
1987 return 123
1988 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001989 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001990 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02001991 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001992 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02001993
1994 lines =<< trim END
1995 vim9script
1996 def RetNumber(): number
1997 return 123
1998 enddef
1999 def Bar(F: func: number): number
2000 return F()
2001 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002002 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002003 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002004 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002005 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002006
2007 lines =<< trim END
2008 vim9script
2009 def UseNumber(nr: number)
2010 echo nr
2011 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002012 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002013 Funcref(123)
2014 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002015 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002016
2017 lines =<< trim END
2018 vim9script
2019 def UseNumber(nr: number)
2020 echo nr
2021 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002022 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002023 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002024 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002025
2026 lines =<< trim END
2027 vim9script
2028 def EchoNr(nr = 34)
2029 g:echo = nr
2030 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002031 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002032 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002033 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002034 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002035 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002036 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002037 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002038
2039 lines =<< trim END
2040 vim9script
2041 def EchoList(...l: list<number>)
2042 g:echo = l
2043 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002044 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002045 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002046 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002047 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002048 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002049 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002050 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002051
2052 lines =<< trim END
2053 vim9script
2054 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2055 g:optarg = opt
2056 g:listarg = l
2057 return nr
2058 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002059 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002060 Funcref(10)->assert_equal(10)
2061 g:optarg->assert_equal(12)
2062 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002063
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002064 Funcref(11, 22)->assert_equal(11)
2065 g:optarg->assert_equal(22)
2066 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002067
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002068 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2069 g:optarg->assert_equal(18)
2070 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002071 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002072 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002073
2074 lines =<< trim END
2075 function s:func(num)
2076 return a:num * 2
2077 endfunction
2078
2079 def s:CallFuncref()
2080 var Funcref = function('s:func')
2081 Funcref(3)->assert_equal(6)
2082 enddef
2083 call s:CallFuncref()
2084 END
2085 v9.CheckScriptSuccess(lines)
2086
2087 lines =<< trim END
2088 function s:func(num)
2089 return a:num * 2
2090 endfunction
2091
2092 def s:CallFuncref()
2093 var Funcref = function(s:func)
2094 Funcref(3)->assert_equal(6)
2095 enddef
2096 call s:CallFuncref()
2097 END
2098 v9.CheckScriptSuccess(lines)
2099
2100 lines =<< trim END
2101 function s:func(num)
2102 return a:num * 2
2103 endfunction
2104
2105 def s:CallFuncref()
2106 var Funcref = s:func
2107 Funcref(3)->assert_equal(6)
2108 enddef
2109 call s:CallFuncref()
2110 END
2111 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002112enddef
2113
2114let SomeFunc = function('len')
2115let NotAFunc = 'text'
2116
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002117def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002118 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002119 var Ref1: func(bool): string
2120 var Ref2: func(bool): number
2121 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002122 Ref3 = g:cond ? Ref1 : Ref2
2123
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002124 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002125 var Refa1: func(bool): number
2126 var Refa2: func(bool, number): number
2127 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002128 Refa3 = g:cond ? Refa1 : Refa2
2129
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002130 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002131 var Refb1: func(bool, string): number
2132 var Refb2: func(string, number): number
2133 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002134 Refb3 = g:cond ? Refb1 : Refb2
2135enddef
2136
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002137def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002138 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002139enddef
2140
2141def DefinedEvenLater(arg: string): string
2142 return arg
2143enddef
2144
2145def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002146 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002147 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002148enddef
2149
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002150def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002151 var lines =<< trim END
2152 vim9script
2153 # Define an outer function
2154 def FirstFunction()
2155 # Define an inner function
2156 def SecondFunction()
2157 # the function has a body, a double free is detected.
2158 AAAAA
2159
2160 # enddef followed by | or } followed by # one or more characters
2161 enddef|BBBB
2162 enddef
2163
2164 # Compile all functions
2165 defcompile
2166 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002167 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002168enddef
2169
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002170def Test_nested_function_with_args_split()
2171 var lines =<< trim END
2172 vim9script
2173 def FirstFunction()
2174 def SecondFunction(
2175 )
2176 # had a double free if the right parenthesis of the nested function is
2177 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002178
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002179 enddef|BBBB
2180 enddef
2181 # Compile all functions
2182 defcompile
2183 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002184 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002185
2186 lines =<< trim END
2187 vim9script
2188 def FirstFunction()
2189 func SecondFunction()
2190 endfunc|BBBB
2191 enddef
2192 defcompile
2193 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002194 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002195enddef
2196
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002197def Test_error_in_function_args()
2198 var lines =<< trim END
2199 def FirstFunction()
2200 def SecondFunction(J =
2201 # Nois
2202 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002203
2204 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002205 enddef
2206 # Compile all functions
2207 defcompile
2208 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002209 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002210enddef
2211
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002212def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002213 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002214 'def Func(): number',
2215 'return "a"',
2216 'enddef',
2217 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002218 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002219 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002220 'def Func(): string',
2221 'return 1',
2222 'enddef',
2223 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002224 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002225 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002226 'def Func(): void',
2227 'return "a"',
2228 'enddef',
2229 'defcompile'],
2230 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002231 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002232 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002233 'def Func()',
2234 'return "a"',
2235 'enddef',
2236 'defcompile'],
2237 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002238 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002239
Bram Moolenaar62aec932022-01-29 21:45:34 +00002240 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002241 'def Func(): number',
2242 'return',
2243 'enddef',
2244 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002245 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002246
Bram Moolenaar62aec932022-01-29 21:45:34 +00002247 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002248 'def Func():number',
2249 'return 123',
2250 'enddef',
2251 'defcompile'], 'E1069:')
2252 delfunc! g:Func
2253
Bram Moolenaar62aec932022-01-29 21:45:34 +00002254 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002255 'def Func() :number',
2256 'return 123',
2257 'enddef',
2258 'defcompile'], 'E1059:')
2259 delfunc! g:Func
2260
Bram Moolenaar62aec932022-01-29 21:45:34 +00002261 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002262 'def Func() : number',
2263 'return 123',
2264 'enddef',
2265 'defcompile'], 'E1059:')
2266 delfunc! g:Func
2267
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002268 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002269 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002270 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002271 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002272 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002273 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002274
Bram Moolenaar62aec932022-01-29 21:45:34 +00002275 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002276 'vim9script',
2277 'def FuncB()',
2278 ' return 123',
2279 'enddef',
2280 'def FuncA()',
2281 ' FuncB()',
2282 'enddef',
2283 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002284enddef
2285
2286def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002287 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002288 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2289 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2290 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2291 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2292 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002293enddef
2294
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002295def Test_white_space_before_comma()
2296 var lines =<< trim END
2297 vim9script
2298 def Func(a: number , b: number)
2299 enddef
2300 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002301 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002302 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002303enddef
2304
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002305def Test_white_space_after_comma()
2306 var lines =<< trim END
2307 vim9script
2308 def Func(a: number,b: number)
2309 enddef
2310 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002311 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002312
2313 # OK in legacy function
2314 lines =<< trim END
2315 vim9script
2316 func Func(a,b)
2317 endfunc
2318 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002319 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002320enddef
2321
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002322def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002323 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002324 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002325 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002326 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002327 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002328 enddef
2329 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002330 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002331
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002332 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002333 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002334 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002335
Bram Moolenaar67979662020-06-20 22:50:47 +02002336 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002337 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002338 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002339
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002340 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002341 def ListFunc(arg: list<number>)
2342 listvar = arg
2343 enddef
2344 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002345 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002346
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002347 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002348 def DictFunc(arg: dict<number>)
2349 dictvar = arg
2350 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002351 {a: 1, b: 2}->DictFunc()
2352 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002353 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002354 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002355 enddef
2356 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002357 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002358
Bram Moolenaare0de1712020-12-02 17:36:54 +01002359 {a: 3, b: 4}->DictFunc()
2360 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002361
2362 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002363 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002364 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002365 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002366
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002367 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002368 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002369 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002370 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002371 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002372 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002373
2374 def UseString()
2375 'xyork'->MyFunc()
2376 enddef
2377 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002378 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002379
Bram Moolenaar10409562020-07-29 20:00:38 +02002380 def UseString2()
2381 "knife"->MyFunc()
2382 enddef
2383 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002384 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002385
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002386 # prepending a colon makes it a mark
2387 new
2388 setline(1, ['aaa', 'bbb', 'ccc'])
2389 normal! 3Gmt1G
2390 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002391 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002392 bwipe!
2393
Bram Moolenaare6b53242020-07-01 17:28:33 +02002394 MyFunc(
2395 'continued'
2396 )
2397 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002398 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002399 )
2400
2401 call MyFunc(
2402 'more'
2403 ..
2404 'lines'
2405 )
2406 assert_equal(
2407 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002408 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002409 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002410 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002411 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002412enddef
2413
2414def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002415 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002416 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002417 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002418 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002419 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002420 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002421 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002422 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002423 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002424enddef
2425
Bram Moolenaar65b95452020-07-19 14:03:09 +02002426def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002427 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002428 vim9script
2429 def MyFunc(arg: string)
2430 echo arg
2431 enddef
2432 MyFunc(1234)
2433 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002434 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002435enddef
2436
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002437def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002438 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002439 vim9script
2440 const var = ''
2441 def MyFunc(arg: string)
2442 var = 'asdf'
2443 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002444 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002445 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002446 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002447 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002448
2449 lines =<< trim END
2450 const g:Aconst = 77
2451 def Change()
2452 # comment
2453 g:Aconst = 99
2454 enddef
2455 call Change()
2456 unlet g:Aconst
2457 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002458 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002459enddef
2460
2461" Test that inside :function a Python function can be defined, :def is not
2462" recognized.
2463func Test_function_python()
2464 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002465 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002466 execute py "<< EOF"
2467def do_something():
2468 return 1
2469EOF
2470endfunc
2471
2472def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002473 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002474 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002475 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002476 echo 'hello'
2477 enddef
2478
2479 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002480 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002481 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002482 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002483
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002484 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002485 CallGoneSoon()
2486 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002487 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002488 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2489 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002490enddef
2491
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002492func Test_free_dict_while_in_funcstack()
2493 " relies on the sleep command
2494 CheckUnix
2495 call Run_Test_free_dict_while_in_funcstack()
2496endfunc
2497
2498def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002499 # this was freeing the TermRun() default argument dictionary while it was
2500 # still referenced in a funcstack_T
2501 var lines =<< trim END
2502 vim9script
2503
2504 &updatetime = 400
2505 def TermRun(_ = {})
2506 def Post()
2507 enddef
2508 def Exec()
2509 term_start('sleep 1', {
2510 term_finish: 'close',
2511 exit_cb: (_, _) => Post(),
2512 })
2513 enddef
2514 Exec()
2515 enddef
2516 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2517 timer_start(100, (_) => feedkeys("\<F4>"))
2518 timer_start(1000, (_) => feedkeys("\<F4>"))
2519 sleep 1500m
2520 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002521 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002522 nunmap <F4>
2523 set updatetime&
2524enddef
2525
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002526def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002527 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002528 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002529 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002530 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002531 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002532 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002533 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002534 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002535 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002536
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002537 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002538 g:Func1()->assert_equal('Func1')
2539 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002540
2541 delfunc! Func0
2542 delfunc! Func1
2543 delfunc! Func2
2544enddef
2545
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002546def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002547 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002548 vim9script
2549 func Func(arg)
2550 echo a:arg
2551 endfunc
2552 Func('text')
2553 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002554 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002555 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002556enddef
2557
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002558let s:funcResult = 0
2559
2560def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002561 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002562enddef
2563
2564def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002565 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002566 return 1234
2567enddef
2568
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002569def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002570 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002571 return 'text'
2572enddef
2573
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002574def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002575 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002576enddef
2577
2578def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002579 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002580 return arg
2581enddef
2582
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002583def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002584 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002585enddef
2586
Bram Moolenaar62aec932022-01-29 21:45:34 +00002587def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002588 return arg
2589enddef
2590
Bram Moolenaar62aec932022-01-29 21:45:34 +00002591def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002592 return arg
2593enddef
2594
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002595def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002596 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002597 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002598 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002599 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002600 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002601
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002602 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002603 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002604 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002605 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002606 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002607
Bram Moolenaar53900992020-08-22 19:02:02 +02002608 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002609 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002610 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002611 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002612
Bram Moolenaar53900992020-08-22 19:02:02 +02002613 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002614 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002615 Ref2()->assert_equal(1234)
2616 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002617
Bram Moolenaar53900992020-08-22 19:02:02 +02002618 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002619 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002620 Ref2(13)->assert_equal(13)
2621 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002622enddef
2623
Bram Moolenaar9978d472020-07-05 16:01:56 +02002624def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002625 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002626 for n in repeat([1], 3)
2627 res += n
2628 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002629 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002630
2631 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002632 for n in repeat(0z01, 3)->blob2list()
2633 res += n
2634 endfor
2635 res->assert_equal(3)
2636
2637 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002638 for n in add([1, 2], 3)
2639 res += n
2640 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002641 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002642enddef
2643
Bram Moolenaar846178a2020-07-05 17:04:13 +02002644def Test_argv_return_type()
2645 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002646 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002647 for name in argv()
2648 res ..= name
2649 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002650 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002651enddef
2652
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002653def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002654 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002655 RefVoid = g:FuncNoArgNoRet
2656 RefVoid = g:FuncOneArgNoRet
2657 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 +00002658 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 +02002659
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002660 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002661 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002662 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002663 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2664 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 +02002665
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002666 var RefAnyNoArgs: func: any = RefAny
2667
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002668 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002669 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002670 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002671 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 +00002672 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 +02002673
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002674 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002675 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002676 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002677 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2678 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 +02002679enddef
2680
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002681def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002682 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002683
Bram Moolenaar62aec932022-01-29 21:45:34 +00002684 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2685 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002686 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 +00002687 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2688 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
2689 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 +02002690
Bram Moolenaar62aec932022-01-29 21:45:34 +00002691 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2692 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2693 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:')
2694 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002695enddef
2696
Bram Moolenaar89228602020-04-05 22:14:54 +02002697def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002698 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002699 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002700 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002701
2702 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002703 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002704
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002705 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002706 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002707 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002708
Bram Moolenaar62aec932022-01-29 21:45:34 +00002709 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002710enddef
2711
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002712def Test_func_common_type()
2713 def FuncOne(n: number): number
2714 return n
2715 enddef
2716 def FuncTwo(s: string): number
2717 return len(s)
2718 enddef
2719 def FuncThree(n: number, s: string): number
2720 return n + len(s)
2721 enddef
2722 var list = [FuncOne, FuncTwo, FuncThree]
2723 assert_equal(8, list[0](8))
2724 assert_equal(4, list[1]('word'))
2725 assert_equal(7, list[2](3, 'word'))
2726enddef
2727
Bram Moolenaar62aec932022-01-29 21:45:34 +00002728def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002729 arg1: string,
2730 arg2 = 1234,
2731 ...rest: list<string>
2732 ): string
2733 return arg1 .. arg2 .. join(rest, '-')
2734enddef
2735
Bram Moolenaar2c330432020-04-13 14:41:35 +02002736def MultiLineComment(
2737 arg1: string, # comment
2738 arg2 = 1234, # comment
2739 ...rest: list<string> # comment
2740 ): string # comment
2741 return arg1 .. arg2 .. join(rest, '-')
2742enddef
2743
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002744def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002745 MultiLine('text')->assert_equal('text1234')
2746 MultiLine('text', 777)->assert_equal('text777')
2747 MultiLine('text', 777, 'one')->assert_equal('text777one')
2748 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002749enddef
2750
Bram Moolenaar23e03252020-04-12 22:22:31 +02002751func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002752 call s:MultiLine('text')->assert_equal('text1234')
2753 call s:MultiLine('text', 777)->assert_equal('text777')
2754 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2755 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002756endfunc
2757
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002758
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002759" When using CheckScriptFailure() for the below test, E1010 is generated instead
2760" of E1056.
2761func Test_E1056_1059()
2762 let caught_1056 = 0
2763 try
2764 def F():
2765 return 1
2766 enddef
2767 catch /E1056:/
2768 let caught_1056 = 1
2769 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002770 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002771
2772 let caught_1059 = 0
2773 try
2774 def F5(items : list)
2775 echo 'a'
2776 enddef
2777 catch /E1059:/
2778 let caught_1059 = 1
2779 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002780 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002781endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002782
Bram Moolenaar015f4262020-05-05 21:25:22 +02002783func DelMe()
2784 echo 'DelMe'
2785endfunc
2786
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002787def Test_error_reporting()
2788 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002789 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002790 " comment
2791 def Func()
2792 # comment
2793 # comment
2794 invalid
2795 enddef
2796 defcompile
2797 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002798 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002799 try
2800 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002801 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002802 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002803 v:exception->assert_match('Invalid command: invalid')
2804 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002805 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002806 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002807
2808 # comment lines after the start of the function
2809 lines =<< trim END
2810 " comment
2811 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002812 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002813 # comment
2814 # comment
2815 invalid
2816 enddef
2817 defcompile
2818 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002819 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002820 try
2821 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002822 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002823 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002824 v:exception->assert_match('Invalid command: invalid')
2825 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002826 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002827 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002828
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002829 lines =<< trim END
2830 vim9script
2831 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002832 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002833 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002834 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002835 enddef
2836 defcompile
2837 Func()
2838 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002839 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002840 try
2841 source Xdef
2842 assert_report('should have failed')
2843 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002844 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002845 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002846 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002847enddef
2848
Bram Moolenaar015f4262020-05-05 21:25:22 +02002849def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002850 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002851 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002852 'delfunc g:DelMe',
2853 'echo RefMe()'], 'E117:')
2854enddef
2855
2856def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002857 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002858 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002859 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002860enddef
2861
Bram Moolenaar62aec932022-01-29 21:45:34 +00002862def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002863 return Ref('more')
2864enddef
2865
2866def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002867 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002868 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002869enddef
2870
Bram Moolenaar62aec932022-01-29 21:45:34 +00002871def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002872 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002873 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002874enddef
2875
2876def Test_closure_ref_after_return()
2877 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002878 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002879 unlet g:Ref
2880enddef
2881
Bram Moolenaar62aec932022-01-29 21:45:34 +00002882def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002883 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002884 g:Extend = (s) => local->add(s)
2885 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002886enddef
2887
2888def Test_closure_two_refs()
2889 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002890 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002891 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002892 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002893 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002894 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002895
2896 unlet g:Extend
2897 unlet g:Read
2898enddef
2899
Bram Moolenaar62aec932022-01-29 21:45:34 +00002900def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002901 return join(Ref(), ' ')
2902enddef
2903
Bram Moolenaar62aec932022-01-29 21:45:34 +00002904def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002905 Ref(add)
2906enddef
2907
2908def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002909 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002910 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002911 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002912 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002913 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002914 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002915
2916 unlet g:Extend
2917 unlet g:Read
2918enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002919
Bram Moolenaar62aec932022-01-29 21:45:34 +00002920def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002921 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002922 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002923enddef
2924
Bram Moolenaar62aec932022-01-29 21:45:34 +00002925def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002926 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002927 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002928enddef
2929
2930def Test_closure_using_argument()
2931 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002932 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002933
2934 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002935 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002936
2937 unlet g:UseArg
2938 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01002939
2940 var lines =<< trim END
2941 vim9script
2942 def Test(Fun: func(number): number): list<number>
2943 return map([1, 2, 3], (_, i) => Fun(i))
2944 enddef
2945 def Inc(nr: number): number
2946 return nr + 2
2947 enddef
2948 assert_equal([3, 4, 5], Test(Inc))
2949 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002950 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02002951enddef
2952
Bram Moolenaar62aec932022-01-29 21:45:34 +00002953def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02002954 var local = 'a'
2955
2956 def Append(arg: string)
2957 local ..= arg
2958 enddef
2959 g:Append = Append
2960
2961 def Get(): string
2962 return local
2963 enddef
2964 g:Get = Get
2965enddef
2966
2967def Test_closure_append_get()
2968 MakeGetAndAppendRefs()
2969 g:Get()->assert_equal('a')
2970 g:Append('-b')
2971 g:Get()->assert_equal('a-b')
2972 g:Append('-c')
2973 g:Get()->assert_equal('a-b-c')
2974
2975 unlet g:Append
2976 unlet g:Get
2977enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02002978
Bram Moolenaar04b12692020-05-04 23:24:44 +02002979def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002980 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02002981 def Closure(arg: string): string
2982 return local .. arg
2983 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002984 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02002985enddef
2986
Bram Moolenaar62aec932022-01-29 21:45:34 +00002987func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02002988 return a:Ref('some')
2989endfunc
2990
2991def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002992 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002993 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002994 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02002995enddef
2996
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02002997def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002998 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02002999 vim9script
3000 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003001 var name = 0
3002 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003003 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003004 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003005 enddef
3006 Func()
3007 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003008 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003009enddef
3010
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003011def Test_nested_closure_used()
3012 var lines =<< trim END
3013 vim9script
3014 def Func()
3015 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003016 var Closure = () => x
3017 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003018 enddef
3019 Func()
3020 assert_equal('hello', g:Myclosure())
3021 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003022 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003023enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003024
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003025def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003026 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003027 vim9script
3028 def FuncA()
3029 FuncB(0)
3030 enddef
3031 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003032 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003033 enddef
3034 FuncA()
3035 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003036 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003037enddef
3038
Bram Moolenaar6de22962022-09-09 21:35:36 +01003039def Run_Test_closure_in_for_loop_fails()
3040 var lines =<< trim END
3041 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003042 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003043 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003044 # time should be enough for startup to finish
3045 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003046 echo n
3047 })
3048 endfor
3049 END
3050 writefile(lines, 'XTest_closure_fails', 'D')
3051
3052 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003053 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003054 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003055
3056 # clean up
3057 g:StopVimInTerminal(buf)
3058enddef
3059
3060func Test_closure_in_for_loop_fails()
3061 CheckScreendump
3062 call Run_Test_closure_in_for_loop_fails()
3063endfunc
3064
Bram Moolenaarf112f302020-12-20 17:47:52 +01003065def Test_global_closure()
3066 var lines =<< trim END
3067 vim9script
3068 def ReverseEveryNLines(n: number, line1: number, line2: number)
3069 var mods = 'sil keepj keepp lockm '
3070 var range = ':' .. line1 .. ',' .. line2
3071 def g:Offset(): number
3072 var offset = (line('.') - line1 + 1) % n
3073 return offset != 0 ? offset : n
3074 enddef
3075 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3076 enddef
3077
3078 new
3079 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3080 ReverseEveryNLines(3, 1, 9)
3081 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003082 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003083 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3084 assert_equal(expected, getline(1, 9))
3085 bwipe!
3086enddef
3087
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003088def Test_global_closure_called_directly()
3089 var lines =<< trim END
3090 vim9script
3091 def Outer()
3092 var x = 1
3093 def g:Inner()
3094 var y = x
3095 x += 1
3096 assert_equal(1, y)
3097 enddef
3098 g:Inner()
3099 assert_equal(2, x)
3100 enddef
3101 Outer()
3102 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003103 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003104 delfunc g:Inner
3105enddef
3106
Bram Moolenaar69c76172021-12-02 16:38:52 +00003107def Test_closure_called_from_legacy()
3108 var lines =<< trim END
3109 vim9script
3110 def Func()
3111 var outer = 'foo'
3112 var F = () => {
3113 outer = 'bar'
3114 }
3115 execute printf('call %s()', string(F))
3116 enddef
3117 Func()
3118 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003119 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003120enddef
3121
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003122def Test_failure_in_called_function()
3123 # this was using the frame index as the return value
3124 var lines =<< trim END
3125 vim9script
3126 au TerminalWinOpen * eval [][0]
3127 def PopupTerm(a: any)
3128 # make sure typvals on stack are string
3129 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3130 FireEvent()
3131 enddef
3132 def FireEvent()
3133 do TerminalWinOpen
3134 enddef
3135 # use try/catch to make eval fail
3136 try
3137 call PopupTerm(0)
3138 catch
3139 endtry
3140 au! TerminalWinOpen
3141 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003142 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003143enddef
3144
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003145def Test_nested_lambda()
3146 var lines =<< trim END
3147 vim9script
3148 def Func()
3149 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003150 var Lambda1 = () => 7
3151 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003152 var res = Lambda2()
3153 assert_equal([7, 4], res)
3154 enddef
3155 Func()
3156 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003157 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003158enddef
3159
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003160def Test_double_nested_lambda()
3161 var lines =<< trim END
3162 vim9script
3163 def F(head: string): func(string): func(string): string
3164 return (sep: string): func(string): string => ((tail: string): string => {
3165 return head .. sep .. tail
3166 })
3167 enddef
3168 assert_equal('hello-there', F('hello')('-')('there'))
3169 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003170 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003171enddef
3172
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003173def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003174 var lines =<< trim END
3175 vim9script
3176 def F(text: string): func(string): func(string): string
3177 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003178 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003179 })
3180 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003181 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003182 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003183 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003184
3185 lines =<< trim END
3186 vim9script
3187 echo range(4)->mapnew((_, v) => {
3188 return range(v) ->mapnew((_, s) => {
3189 return string(s)
3190 })
3191 })
3192 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003193 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003194
3195 lines =<< trim END
3196 vim9script
3197
Bram Moolenaara749a422022-02-12 19:52:25 +00003198 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003199 range(10)
3200 ->mapnew((_, _) => ({
3201 key: range(10)->mapnew((_, _) => {
3202 return ' '
3203 }),
3204 }))
3205 enddef
3206
3207 defcomp
3208 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003209 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003210enddef
3211
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003212def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003213 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003214 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003215enddef
3216
3217def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003218 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003219enddef
3220
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003221def Test_compiling_referenced_func_no_shadow()
3222 var lines =<< trim END
3223 vim9script
3224
3225 def InitializeReply(lspserver: dict<any>)
3226 enddef
3227
3228 def ProcessReply(lspserver: dict<any>)
3229 var lsp_reply_handlers: dict<func> =
3230 { 'initialize': InitializeReply }
3231 lsp_reply_handlers['initialize'](lspserver)
3232 enddef
3233
3234 call ProcessReply({})
3235 END
3236 v9.CheckScriptSuccess(lines)
3237enddef
3238
Bram Moolenaar62aec932022-01-29 21:45:34 +00003239def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003240 var path: string = empty(dir)
3241 \ ? 'empty'
3242 \ : 'full'
3243 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003244enddef
3245
3246def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003247 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003248enddef
3249
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003250def Test_script_var_in_lambda()
3251 var lines =<< trim END
3252 vim9script
3253 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003254 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003255 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003256 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003257enddef
3258
Bram Moolenaar62aec932022-01-29 21:45:34 +00003259def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003260 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003261 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003262 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003263 ->reverse()
3264 return x
3265enddef
3266
3267def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003268 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003269
3270 var lines =<< trim END
3271 vim9script
3272 var res = [{n: 1, m: 2, s: 'xxx'}]
3273 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3274 v.n,
3275 v.m,
3276 substitute(v.s, '.*', 'yyy', '')
3277 ))
3278 assert_equal(['1:2:yyy'], res)
3279 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003280 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003281enddef
3282
Bram Moolenaarb6571982021-01-08 22:24:19 +01003283def Test_list_lambda()
3284 timer_start(1000, (_) => 0)
3285 var body = execute(timer_info()[0].callback
3286 ->string()
3287 ->substitute("('", ' ', '')
3288 ->substitute("')", '', '')
3289 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003290 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003291enddef
3292
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003293def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003294 var lines =<< trim END
3295 vim9script
3296 var flist: list<func>
3297 for i in range(10)
3298 var inloop = i
3299 flist[i] = () => inloop
3300 endfor
3301 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003302 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003303
3304 lines =<< trim END
3305 vim9script
3306 if true
3307 var outloop = 5
3308 var flist: list<func>
3309 for i in range(10)
3310 flist[i] = () => outloop
3311 endfor
3312 endif
3313 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003314 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003315
3316 lines =<< trim END
3317 vim9script
3318 if true
3319 var outloop = 5
3320 endif
3321 var flist: list<func>
3322 for i in range(10)
3323 flist[i] = () => outloop
3324 endfor
3325 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003326 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003327
3328 lines =<< trim END
3329 vim9script
3330 for i in range(10)
3331 var Ref = () => 0
3332 endfor
3333 assert_equal(0, ((i) => 0)(0))
3334 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003335 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003336enddef
3337
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003338def Test_legacy_lambda()
3339 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003340
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003341 var lines =<< trim END
3342 echo {x -> 'hello ' .. x}('foo')
3343 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003344 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003345
3346 lines =<< trim END
3347 vim9script
3348 def Func()
3349 echo (() => 'no error')()
3350 enddef
3351 legacy call s:Func()
3352 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003353 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003354enddef
3355
Bram Moolenaarce024c32021-06-26 13:00:49 +02003356def Test_legacy()
3357 var lines =<< trim END
3358 vim9script
3359 func g:LegacyFunction()
3360 let g:legacyvar = 1
3361 endfunc
3362 def Testit()
3363 legacy call g:LegacyFunction()
3364 enddef
3365 Testit()
3366 assert_equal(1, g:legacyvar)
3367 unlet g:legacyvar
3368 delfunc g:LegacyFunction
3369 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003370 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003371enddef
3372
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003373def Test_legacy_errors()
3374 for cmd in ['if', 'elseif', 'else', 'endif',
3375 'for', 'endfor', 'continue', 'break',
3376 'while', 'endwhile',
3377 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003378 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003379 endfor
3380enddef
3381
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003382def Test_call_legacy_with_dict()
3383 var lines =<< trim END
3384 vim9script
3385 func Legacy() dict
3386 let g:result = self.value
3387 endfunc
3388 def TestDirect()
3389 var d = {value: 'yes', func: Legacy}
3390 d.func()
3391 enddef
3392 TestDirect()
3393 assert_equal('yes', g:result)
3394 unlet g:result
3395
3396 def TestIndirect()
3397 var d = {value: 'foo', func: Legacy}
3398 var Fi = d.func
3399 Fi()
3400 enddef
3401 TestIndirect()
3402 assert_equal('foo', g:result)
3403 unlet g:result
3404
3405 var d = {value: 'bar', func: Legacy}
3406 d.func()
3407 assert_equal('bar', g:result)
3408 unlet g:result
3409 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003410 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003411enddef
3412
Bram Moolenaar62aec932022-01-29 21:45:34 +00003413def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003414 # closure nested inside another closure using argument
3415 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3416 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3417enddef
3418
3419def Test_nested_closure_using_argument()
3420 assert_equal(['x', 'x2'], DoFilterThis('x'))
3421enddef
3422
Bram Moolenaar0186e582021-01-10 18:33:11 +01003423def Test_triple_nested_closure()
3424 var what = 'x'
3425 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3426 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3427 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3428enddef
3429
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003430func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003431 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003432 call Run_Test_silent_echo()
3433endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003434
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003435def Run_Test_silent_echo()
3436 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003437 vim9script
3438 def EchoNothing()
3439 silent echo ''
3440 enddef
3441 defcompile
3442 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003443 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003444
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003445 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003446 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003447 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003448 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003449
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003450 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003451 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003452enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003453
Bram Moolenaar171fb922020-10-28 16:54:47 +01003454def SilentlyError()
3455 execute('silent! invalid')
3456 g:did_it = 'yes'
3457enddef
3458
Bram Moolenaar62aec932022-01-29 21:45:34 +00003459func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003460 silent! invalid
3461endfunc
3462
3463def SilentlyUserError()
3464 UserError()
3465 g:did_it = 'yes'
3466enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003467
3468" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003469func Test_ignore_silent_error()
3470 let g:did_it = 'no'
3471 call SilentlyError()
3472 call assert_equal('yes', g:did_it)
3473
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003474 let g:did_it = 'no'
3475 call SilentlyUserError()
3476 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003477
3478 unlet g:did_it
3479endfunc
3480
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003481def Test_ignore_silent_error_in_filter()
3482 var lines =<< trim END
3483 vim9script
3484 def Filter(winid: number, key: string): bool
3485 if key == 'o'
3486 silent! eval [][0]
3487 return true
3488 endif
3489 return popup_filter_menu(winid, key)
3490 enddef
3491
Bram Moolenaare0de1712020-12-02 17:36:54 +01003492 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003493 feedkeys("o\r", 'xnt')
3494 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003495 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003496enddef
3497
Bram Moolenaar62aec932022-01-29 21:45:34 +00003498def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003499 if n < 2
3500 return n
3501 else
3502 return Fibonacci(n - 1) + Fibonacci(n - 2)
3503 endif
3504enddef
3505
Bram Moolenaar985116a2020-07-12 17:31:09 +02003506def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003507 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003508enddef
3509
Bram Moolenaar62aec932022-01-29 21:45:34 +00003510def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003511 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003512 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003513 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003514 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003515 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003516enddef
3517
3518def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003519 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003520 writefile(['111'], 'XclosureDir/file1')
3521 writefile(['222'], 'XclosureDir/file2')
3522 writefile(['333'], 'XclosureDir/tdir/file3')
3523
Bram Moolenaare0de1712020-12-02 17:36:54 +01003524 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003525enddef
3526
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003527def Test_invalid_function_name()
3528 var lines =<< trim END
3529 vim9script
3530 def s: list<string>
3531 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003532 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003533
3534 lines =<< trim END
3535 vim9script
3536 def g: list<string>
3537 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003538 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003539
3540 lines =<< trim END
3541 vim9script
3542 def <SID>: list<string>
3543 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003544 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003545
3546 lines =<< trim END
3547 vim9script
3548 def F list<string>
3549 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003550 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003551enddef
3552
Bram Moolenaara90afb92020-07-15 22:38:56 +02003553def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003554 var lines =<< trim END
3555 var Xsetlist: func
3556 Xsetlist = function('setloclist', [0])
3557 Xsetlist([], ' ', {title: 'test'})
3558 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003559
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003560 Xsetlist = function('setloclist', [0, [], ' '])
3561 Xsetlist({title: 'test'})
3562 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003563
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003564 Xsetlist = function('setqflist')
3565 Xsetlist([], ' ', {title: 'test'})
3566 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003567
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003568 Xsetlist = function('setqflist', [[], ' '])
3569 Xsetlist({title: 'test'})
3570 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003571
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003572 var Len: func: number = function('len', ['word'])
3573 assert_equal(4, Len())
3574
3575 var RepeatFunc = function('repeat', ['o'])
3576 assert_equal('ooooo', RepeatFunc(5))
3577 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003578 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003579
3580 lines =<< trim END
3581 vim9script
3582 def Foo(Parser: any)
3583 enddef
3584 var Expr: func(dict<any>): dict<any>
3585 const Call = Foo(Expr)
3586 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003587 v9.CheckScriptFailure(lines, 'E1031:')
Bram Moolenaara90afb92020-07-15 22:38:56 +02003588enddef
3589
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003590def Test_partial_double_nested()
3591 var idx = 123
3592 var Get = () => idx
3593 var Ref = function(Get, [])
3594 var RefRef = function(Ref, [])
3595 assert_equal(123, RefRef())
3596enddef
3597
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003598def Test_partial_null_function()
3599 var lines =<< trim END
3600 var d: dict<func> = {f: null_function}
3601 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003602 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003603 END
3604 v9.CheckDefAndScriptSuccess(lines)
3605enddef
3606
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003607def Test_cmd_modifier()
3608 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003609 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003610enddef
3611
3612def Test_restore_modifiers()
3613 # check that when compiling a :def function command modifiers are not messed
3614 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003615 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003616 vim9script
3617 set eventignore=
3618 autocmd QuickFixCmdPost * copen
3619 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003620 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003621 enddef
3622 func Func()
3623 noautocmd call s:AutocmdsDisabled()
3624 let g:ei_after = &eventignore
3625 endfunc
3626 Func()
3627 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003628 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003629 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003630enddef
3631
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003632def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003633 eval 1 + 2
3634 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003635 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003636 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003637enddef
3638
3639def StackBot()
3640 # throw an error
3641 eval [][0]
3642enddef
3643
3644def Test_callstack_def()
3645 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003646 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003647 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003648 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003649 endtry
3650enddef
3651
Bram Moolenaare8211a32020-10-09 22:04:29 +02003652" Re-using spot for variable used in block
3653def Test_block_scoped_var()
3654 var lines =<< trim END
3655 vim9script
3656 def Func()
3657 var x = ['a', 'b', 'c']
3658 if 1
3659 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003660 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003661 endif
3662 var z = x
3663 assert_equal(['x', 'x', 'x'], z)
3664 enddef
3665 Func()
3666 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003667 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003668enddef
3669
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003670def Test_reset_did_emsg()
3671 var lines =<< trim END
3672 @s = 'blah'
3673 au BufWinLeave * #
3674 def Func()
3675 var winid = popup_create('popup', {})
3676 exe '*s'
3677 popup_close(winid)
3678 enddef
3679 Func()
3680 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003681 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003682 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003683enddef
3684
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003685def Test_did_emsg_reset()
3686 # executing an autocommand resets did_emsg, this should not result in a
3687 # builtin function considered failing
3688 var lines =<< trim END
3689 vim9script
3690 au BufWinLeave * #
3691 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003692 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003693 eval [][0]
3694 enddef
3695 nno <F3> <cmd>call <sid>Func()<cr>
3696 feedkeys("\<F3>\e", 'xt')
3697 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003698 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003699 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003700
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003701 nunmap <F3>
3702 au! BufWinLeave
3703enddef
3704
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003705def Test_abort_with_silent_call()
3706 var lines =<< trim END
3707 vim9script
3708 g:result = 'none'
3709 def Func()
3710 g:result += 3
3711 g:result = 'yes'
3712 enddef
3713 # error is silenced, but function aborts on error
3714 silent! Func()
3715 assert_equal('none', g:result)
3716 unlet g:result
3717 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003718 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003719enddef
3720
Bram Moolenaarf665e972020-12-05 19:17:16 +01003721def Test_continues_with_silent_error()
3722 var lines =<< trim END
3723 vim9script
3724 g:result = 'none'
3725 def Func()
3726 silent! g:result += 3
3727 g:result = 'yes'
3728 enddef
3729 # error is silenced, function does not abort
3730 Func()
3731 assert_equal('yes', g:result)
3732 unlet g:result
3733 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003734 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003735enddef
3736
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003737def Test_abort_even_with_silent()
3738 var lines =<< trim END
3739 vim9script
3740 g:result = 'none'
3741 def Func()
3742 eval {-> ''}() .. '' .. {}['X']
3743 g:result = 'yes'
3744 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003745 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003746 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003747 unlet g:result
3748 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003749 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003750enddef
3751
Bram Moolenaarf665e972020-12-05 19:17:16 +01003752def Test_cmdmod_silent_restored()
3753 var lines =<< trim END
3754 vim9script
3755 def Func()
3756 g:result = 'none'
3757 silent! g:result += 3
3758 g:result = 'none'
3759 g:result += 3
3760 enddef
3761 Func()
3762 END
3763 # can't use CheckScriptFailure, it ignores the :silent!
3764 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003765 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003766 var caught = 'no'
3767 try
3768 exe 'source ' .. fname
3769 catch /E1030:/
3770 caught = 'yes'
3771 assert_match('Func, line 4', v:throwpoint)
3772 endtry
3773 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003774enddef
3775
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003776def Test_cmdmod_silent_nested()
3777 var lines =<< trim END
3778 vim9script
3779 var result = ''
3780
3781 def Error()
3782 result ..= 'Eb'
3783 eval [][0]
3784 result ..= 'Ea'
3785 enddef
3786
3787 def Crash()
3788 result ..= 'Cb'
3789 sil! Error()
3790 result ..= 'Ca'
3791 enddef
3792
3793 Crash()
3794 assert_equal('CbEbEaCa', result)
3795 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003796 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003797enddef
3798
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003799def Test_dict_member_with_silent()
3800 var lines =<< trim END
3801 vim9script
3802 g:result = 'none'
3803 var d: dict<any>
3804 def Func()
3805 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003806 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003807 catch
3808 endtry
3809 enddef
3810 silent! Func()
3811 assert_equal('0', g:result)
3812 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003813 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003814 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003815enddef
3816
Bram Moolenaarf9041332021-01-21 19:41:16 +01003817def Test_skip_cmds_with_silent()
3818 var lines =<< trim END
3819 vim9script
3820
3821 def Func(b: bool)
3822 Crash()
3823 enddef
3824
3825 def Crash()
3826 sil! :/not found/d _
3827 sil! :/not found/put _
3828 enddef
3829
3830 Func(true)
3831 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003832 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003833enddef
3834
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003835def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003836 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003837 def g:Opfunc(_: any): string
3838 setline(1, 'ASDF')
3839 return ''
3840 enddef
3841 new
3842 setline(1, 'asdf')
3843 feedkeys("\<F3>$", 'x')
3844 assert_equal('ASDF', getline(1))
3845
3846 bwipe!
3847 nunmap <F3>
3848enddef
3849
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003850func Test_opfunc_error()
3851 CheckScreendump
3852 call Run_Test_opfunc_error()
3853endfunc
3854
3855def Run_Test_opfunc_error()
3856 # test that the error from Opfunc() is displayed right away
3857 var lines =<< trim END
3858 vim9script
3859
3860 def Opfunc(type: string)
3861 try
3862 eval [][0]
3863 catch /nothing/ # error not caught
3864 endtry
3865 enddef
3866 &operatorfunc = Opfunc
3867 nnoremap <expr> l <SID>L()
3868 def L(): string
3869 return 'l'
3870 enddef
3871 'x'->repeat(10)->setline(1)
3872 feedkeys('g@l', 'n')
3873 feedkeys('llll')
3874 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003875 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003876
Bram Moolenaar62aec932022-01-29 21:45:34 +00003877 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3878 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003879 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003880
3881 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003882 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003883enddef
3884
Bram Moolenaar077a4232020-12-22 18:33:27 +01003885" this was crashing on exit
3886def Test_nested_lambda_in_closure()
3887 var lines =<< trim END
3888 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003889 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003890 def Outer()
3891 def g:Inner()
3892 echo map([1, 2, 3], {_, v -> v + 1})
3893 enddef
3894 g:Inner()
3895 enddef
3896 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003897 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003898 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003899 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003900 return
3901 endif
3902 assert_equal(['Done'], readfile('XnestedDone'))
3903 delete('XnestedDone')
3904enddef
3905
Bram Moolenaar92368aa2022-02-07 17:50:39 +00003906def Test_nested_closure_funcref()
3907 var lines =<< trim END
3908 vim9script
3909 def Func()
3910 var n: number
3911 def Nested()
3912 ++n
3913 enddef
3914 Nested()
3915 g:result_one = n
3916 var Ref = function(Nested)
3917 Ref()
3918 g:result_two = n
3919 enddef
3920 Func()
3921 END
3922 v9.CheckScriptSuccess(lines)
3923 assert_equal(1, g:result_one)
3924 assert_equal(2, g:result_two)
3925 unlet g:result_one g:result_two
3926enddef
3927
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00003928def Test_nested_closure_in_dict()
3929 var lines =<< trim END
3930 vim9script
3931 def Func(): dict<any>
3932 var n: number
3933 def Inc(): number
3934 ++n
3935 return n
3936 enddef
3937 return {inc: function(Inc)}
3938 enddef
3939 disas Func
3940 var d = Func()
3941 assert_equal(1, d.inc())
3942 assert_equal(2, d.inc())
3943 END
3944 v9.CheckScriptSuccess(lines)
3945enddef
3946
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003947def Test_script_local_other_script()
3948 var lines =<< trim END
3949 function LegacyJob()
3950 let FuncRef = function('s:close_cb')
3951 endfunction
3952 function s:close_cb(...)
3953 endfunction
3954 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003955 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003956 source Xlegacy.vim
3957 g:LegacyJob()
3958 g:LegacyJob()
3959 g:LegacyJob()
3960
3961 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00003962enddef
3963
Bram Moolenaar04947cc2021-03-06 19:26:46 +01003964def Test_check_func_arg_types()
3965 var lines =<< trim END
3966 vim9script
3967 def F1(x: string): string
3968 return x
3969 enddef
3970
3971 def F2(x: number): number
3972 return x + 1
3973 enddef
3974
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00003975 def G(Fg: func): dict<func>
3976 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01003977 enddef
3978
3979 def H(d: dict<func>): string
3980 return d.f('a')
3981 enddef
3982 END
3983
Bram Moolenaar62aec932022-01-29 21:45:34 +00003984 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
3985 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00003986
3987 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01003988enddef
3989
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00003990def Test_call_func_with_null()
3991 var lines =<< trim END
3992 def Fstring(v: string)
3993 assert_equal(null_string, v)
3994 enddef
3995 Fstring(null_string)
3996 def Fblob(v: blob)
3997 assert_equal(null_blob, v)
3998 enddef
3999 Fblob(null_blob)
4000 def Flist(v: list<number>)
4001 assert_equal(null_list, v)
4002 enddef
4003 Flist(null_list)
4004 def Fdict(v: dict<number>)
4005 assert_equal(null_dict, v)
4006 enddef
4007 Fdict(null_dict)
4008 def Ffunc(Fv: func(number): number)
4009 assert_equal(null_function, Fv)
4010 enddef
4011 Ffunc(null_function)
4012 if has('channel')
4013 def Fchannel(v: channel)
4014 assert_equal(null_channel, v)
4015 enddef
4016 Fchannel(null_channel)
4017 def Fjob(v: job)
4018 assert_equal(null_job, v)
4019 enddef
4020 Fjob(null_job)
4021 endif
4022 END
4023 v9.CheckDefAndScriptSuccess(lines)
4024enddef
4025
4026def Test_null_default_argument()
4027 var lines =<< trim END
4028 def Fstring(v: string = null_string)
4029 assert_equal(null_string, v)
4030 enddef
4031 Fstring()
4032 def Fblob(v: blob = null_blob)
4033 assert_equal(null_blob, v)
4034 enddef
4035 Fblob()
4036 def Flist(v: list<number> = null_list)
4037 assert_equal(null_list, v)
4038 enddef
4039 Flist()
4040 def Fdict(v: dict<number> = null_dict)
4041 assert_equal(null_dict, v)
4042 enddef
4043 Fdict()
4044 def Ffunc(Fv: func(number): number = null_function)
4045 assert_equal(null_function, Fv)
4046 enddef
4047 Ffunc()
4048 if has('channel')
4049 def Fchannel(v: channel = null_channel)
4050 assert_equal(null_channel, v)
4051 enddef
4052 Fchannel()
4053 def Fjob(v: job = null_job)
4054 assert_equal(null_job, v)
4055 enddef
4056 Fjob()
4057 endif
4058 END
4059 v9.CheckDefAndScriptSuccess(lines)
4060enddef
4061
4062def Test_null_return()
4063 var lines =<< trim END
4064 def Fstring(): string
4065 return null_string
4066 enddef
4067 assert_equal(null_string, Fstring())
4068 def Fblob(): blob
4069 return null_blob
4070 enddef
4071 assert_equal(null_blob, Fblob())
4072 def Flist(): list<number>
4073 return null_list
4074 enddef
4075 assert_equal(null_list, Flist())
4076 def Fdict(): dict<number>
4077 return null_dict
4078 enddef
4079 assert_equal(null_dict, Fdict())
4080 def Ffunc(): func(number): number
4081 return null_function
4082 enddef
4083 assert_equal(null_function, Ffunc())
4084 if has('channel')
4085 def Fchannel(): channel
4086 return null_channel
4087 enddef
4088 assert_equal(null_channel, Fchannel())
4089 def Fjob(): job
4090 return null_job
4091 enddef
4092 assert_equal(null_job, Fjob())
4093 endif
4094 END
4095 v9.CheckDefAndScriptSuccess(lines)
4096enddef
4097
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004098def Test_list_any_type_checked()
4099 var lines =<< trim END
4100 vim9script
4101 def Foo()
4102 --decl--
4103 Bar(l)
4104 enddef
4105 def Bar(ll: list<dict<any>>)
4106 enddef
4107 Foo()
4108 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004109 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004110 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004111 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004112 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004113 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004114
4115 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004116 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004117enddef
4118
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004119def Test_compile_error()
4120 var lines =<< trim END
4121 def g:Broken()
4122 echo 'a' + {}
4123 enddef
4124 call g:Broken()
4125 END
4126 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004127 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004128
4129 # Second call won't try compiling again
4130 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004131 delfunc g:Broken
4132
4133 # No error when compiling with :silent!
4134 lines =<< trim END
4135 def g:Broken()
4136 echo 'a' + []
4137 enddef
4138 silent! defcompile
4139 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004140 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004141
4142 # Calling the function won't try compiling again
4143 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4144 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004145enddef
4146
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004147def Test_ignored_argument()
4148 var lines =<< trim END
4149 vim9script
4150 def Ignore(_, _): string
4151 return 'yes'
4152 enddef
4153 assert_equal('yes', Ignore(1, 2))
4154
4155 func Ok(_)
4156 return a:_
4157 endfunc
4158 assert_equal('ok', Ok('ok'))
4159
4160 func Oktoo()
4161 let _ = 'too'
4162 return _
4163 endfunc
4164 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004165
4166 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004167 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004168 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004169
4170 lines =<< trim END
4171 def Ignore(_: string): string
4172 return _
4173 enddef
4174 defcompile
4175 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004176 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004177
4178 lines =<< trim END
4179 var _ = 1
4180 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004181 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004182
4183 lines =<< trim END
4184 var x = _
4185 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004186 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004187enddef
4188
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004189def Test_too_many_arguments()
4190 var lines =<< trim END
4191 echo [0, 1, 2]->map(() => 123)
4192 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004193 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004194
4195 lines =<< trim END
4196 echo [0, 1, 2]->map((_) => 123)
4197 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004198 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004199
4200 lines =<< trim END
4201 vim9script
4202 def OneArgument(arg: string)
4203 echo arg
4204 enddef
4205 var Ref = OneArgument
4206 Ref('a', 'b')
4207 END
4208 v9.CheckScriptFailure(lines, 'E118:')
4209enddef
4210
4211def Test_funcref_with_base()
4212 var lines =<< trim END
4213 vim9script
4214 def TwoArguments(str: string, nr: number)
4215 echo str nr
4216 enddef
4217 var Ref = TwoArguments
4218 Ref('a', 12)
4219 'b'->Ref(34)
4220 END
4221 v9.CheckScriptSuccess(lines)
4222
4223 lines =<< trim END
4224 vim9script
4225 def TwoArguments(str: string, nr: number)
4226 echo str nr
4227 enddef
4228 var Ref = TwoArguments
4229 'a'->Ref('b')
4230 END
4231 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4232
4233 lines =<< trim END
4234 vim9script
4235 def TwoArguments(str: string, nr: number)
4236 echo str nr
4237 enddef
4238 var Ref = TwoArguments
4239 123->Ref(456)
4240 END
4241 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4242
4243 lines =<< trim END
4244 vim9script
4245 def TwoArguments(nr: number, str: string)
4246 echo str nr
4247 enddef
4248 var Ref = TwoArguments
4249 123->Ref('b')
4250 def AndNowCompiled()
4251 456->Ref('x')
4252 enddef
4253 AndNowCompiled()
4254 END
4255 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004256enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004257
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004258def Test_closing_brace_at_start_of_line()
4259 var lines =<< trim END
4260 def Func()
4261 enddef
4262 Func(
4263 )
4264 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004265 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004266enddef
4267
Bram Moolenaar62aec932022-01-29 21:45:34 +00004268func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004269 let g:mydict = {}
4270 func g:mydict.afunc()
4271 let g:result = self.key
4272 endfunc
4273endfunc
4274
4275def Test_numbered_function_reference()
4276 CreateMydict()
4277 var output = execute('legacy func g:mydict.afunc')
4278 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4279 execute 'function(' .. funcName .. ', [], {key: 42})()'
4280 # check that the function still exists
4281 assert_equal(output, execute('legacy func g:mydict.afunc'))
4282 unlet g:mydict
4283enddef
4284
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004285def Test_numbered_function_call()
4286 var lines =<< trim END
4287 let s:legacyscript = {}
4288 func s:legacyscript.Helper() abort
4289 return "Success"
4290 endfunc
4291 let g:legacyscript = deepcopy(s:legacyscript)
4292
4293 let g:legacy_result = eval("g:legacyscript.Helper()")
4294 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4295 END
4296 v9.CheckScriptSuccess(lines)
4297 assert_equal('Success', g:legacy_result)
4298 assert_equal('Success', g:vim9_result)
4299
4300 unlet g:legacy_result
4301 unlet g:vim9_result
4302enddef
4303
Bram Moolenaard3a11782022-01-05 16:50:40 +00004304def Test_go_beyond_end_of_cmd()
4305 # this was reading the byte after the end of the line
4306 var lines =<< trim END
4307 def F()
4308 cal
4309 enddef
4310 defcompile
4311 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004312 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004313enddef
4314
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004315" Test for memory allocation failure when defining a new lambda
4316func Test_lambda_allocation_failure()
4317 new
4318 let lines =<< trim END
4319 vim9script
4320 g:Xlambda = (x): number => {
4321 return x + 1
4322 }
4323 END
4324 call setline(1, lines)
4325 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4326 call assert_fails('source', 'E342:')
4327 call assert_false(exists('g:Xlambda'))
4328 bw!
4329endfunc
4330
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004331def Test_lambda_argument_type_check()
4332 var lines =<< trim END
4333 vim9script
4334
4335 def Scan(ll: list<any>): func(func(any))
4336 return (Emit: func(any)) => {
4337 for e in ll
4338 Emit(e)
4339 endfor
4340 }
4341 enddef
4342
4343 def Sum(Cont: func(func(any))): any
4344 var sum = 0.0
4345 Cont((v: float) => { # <== NOTE: the lambda expects a float
4346 sum += v
4347 })
4348 return sum
4349 enddef
4350
Bram Moolenaar47bba532023-01-20 18:49:46 +00004351 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004352 echo Scan(ml)->Sum()
4353 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004354 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004355enddef
4356
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004357def Test_multiple_funcref()
4358 # This was using a NULL pointer
4359 var lines =<< trim END
4360 vim9script
4361 def A(F: func, ...args: list<any>): func
4362 return funcref(F, args)
4363 enddef
4364
4365 def B(F: func): func
4366 return funcref(A, [F])
4367 enddef
4368
4369 def Test(n: number)
4370 enddef
4371
4372 const X = B(Test)
4373 X(1)
4374 END
4375 v9.CheckScriptSuccess(lines)
4376
4377 # slightly different case
4378 lines =<< trim END
4379 vim9script
4380
4381 def A(F: func, ...args: list<any>): any
4382 return call(F, args)
4383 enddef
4384
4385 def B(F: func): func
4386 return funcref(A, [F])
4387 enddef
4388
4389 def Test(n: number)
4390 enddef
4391
4392 const X = B(Test)
4393 X(1)
4394 END
4395 v9.CheckScriptSuccess(lines)
4396enddef
4397
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004398def Test_cexpr_errmsg_line_number()
4399 var lines =<< trim END
4400 vim9script
4401 def Func()
4402 var qfl = {}
4403 cexpr qfl
4404 enddef
4405 Func()
4406 END
4407 v9.CheckScriptFailure(lines, 'E777', 2)
4408enddef
4409
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004410def AddDefer(s: string)
4411 g:deferred->extend([s])
4412enddef
4413
4414def DeferTwo()
4415 g:deferred->extend(['in Two'])
4416 for n in range(3)
4417 defer g:AddDefer('two' .. n)
4418 endfor
4419 g:deferred->extend(['end Two'])
4420enddef
4421
4422def DeferOne()
4423 g:deferred->extend(['in One'])
4424 defer g:AddDefer('one')
4425 g:DeferTwo()
4426 g:deferred->extend(['end One'])
4427
4428 writefile(['text'], 'XdeferFile')
4429 defer delete('XdeferFile')
4430enddef
4431
4432def Test_defer()
4433 g:deferred = []
4434 g:DeferOne()
4435 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4436 unlet g:deferred
4437 assert_equal('', glob('XdeferFile'))
4438enddef
4439
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004440def Test_invalid_redir()
4441 var lines =<< trim END
4442 def Tone()
4443 if 1
4444 redi =>@�0
4445 redi END
4446 endif
4447 enddef
4448 defcompile
4449 END
4450 v9.CheckScriptFailure(lines, 'E354:')
4451 delfunc g:Tone
4452
4453 # this was reading past the end of the line
4454 lines =<< trim END
4455 def Ttwo()
4456 if 0
4457 redi =>@�0
4458 redi END
4459 endif
4460 enddef
4461 defcompile
4462 END
4463 v9.CheckScriptFailure(lines, 'E354:')
4464 delfunc g:Ttwo
4465enddef
4466
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004467func Test_keytyped_in_nested_function()
4468 CheckRunVimInTerminal
4469
4470 call Run_Test_keytyped_in_nested_function()
4471endfunc
4472
4473def Run_Test_keytyped_in_nested_function()
4474 var lines =<< trim END
4475 vim9script
4476 autocmd CmdlineEnter * sample#Init()
4477
4478 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4479 END
4480 writefile(lines, 'Xkeytyped', 'D')
4481
4482 var dir = 'Xrtpdir/autoload'
4483 mkdir(dir, 'pR')
4484
4485 lines =<< trim END
4486 vim9script
4487 export def Init(): void
4488 cnoremap <expr>" <SID>Quote('"')
4489 enddef
4490 def Quote(str: string): string
4491 def InPair(): number
4492 return 0
4493 enddef
4494 return str
4495 enddef
4496 END
4497 writefile(lines, dir .. '/sample.vim')
4498
4499 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4500
4501 term_sendkeys(buf, ':"')
4502 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4503
4504 # clean up
4505 term_sendkeys(buf, "\<Esc>")
4506 g:StopVimInTerminal(buf)
4507enddef
4508
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004509" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004510if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004511 def Test_python3_command()
4512 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004513 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004514 assert_equal('yes', g:done)
4515 unlet g:done
4516 enddef
4517
Bram Moolenaar20677332021-06-06 17:02:53 +02004518 def Test_python3_heredoc()
4519 py3 << trim EOF
4520 import vim
4521 vim.vars['didit'] = 'yes'
4522 EOF
4523 assert_equal('yes', g:didit)
4524
4525 python3 << trim EOF
4526 import vim
4527 vim.vars['didit'] = 'again'
4528 EOF
4529 assert_equal('again', g:didit)
4530 enddef
4531endif
4532
Bram Moolenaar20677332021-06-06 17:02:53 +02004533if has('lua')
4534 def Test_lua_heredoc()
4535 g:d = {}
4536 lua << trim EOF
4537 x = vim.eval('g:d')
4538 x['key'] = 'val'
4539 EOF
4540 assert_equal('val', g:d.key)
4541 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004542
4543 def Test_lua_heredoc_fails()
4544 var lines = [
4545 'vim9script',
4546 'def ExeLua()',
4547 'lua << trim EOLUA',
4548 "x = vim.eval('g:nodict')",
4549 'EOLUA',
4550 'enddef',
4551 'ExeLua()',
4552 ]
4553 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4554 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004555endif
4556
Bram Moolenaard881d152022-05-13 13:50:36 +01004557if has('perl')
4558 def Test_perl_heredoc_nested()
4559 var lines =<< trim END
4560 vim9script
4561 def F(): string
4562 def G(): string
4563 perl << EOF
4564 EOF
4565 return 'done'
4566 enddef
4567 return G()
4568 enddef
4569 assert_equal('done', F())
4570 END
4571 v9.CheckScriptSuccess(lines)
4572 enddef
4573endif
4574
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004575
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004576" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker