blob: 701a2f085dd3a13a8d58e75f6c3ee8700d00c112 [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 Moolenaard4a9b7f2023-05-23 14:48:42 +0100169def Test_listing_function_error()
170 var lines =<< trim END
171 var filler = 123
172 func DoesNotExist
173 END
174 v9.CheckDefExecFailure(lines, 'E123:', 2)
175enddef
176
Bram Moolenaar3f45d672023-02-27 22:06:51 +0000177def Test_break_in_skipped_block()
178 var lines =<< trim END
179 vim9script
180
181 def FixStackFrame(): string
182 for _ in [2]
183 var path = 'xxx'
184 if !!path
185 if false
186 break
187 else
188 return 'foo'
189 endif
190 endif
191 endfor
192 return 'xxx'
193 enddef
194
195 disas FixStackFrame
196
197 FixStackFrame()
198 END
199 v9.CheckScriptSuccess(lines)
200enddef
201
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200202def Test_autoload_name_mismatch()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100203 var dir = 'Xnamedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100204 mkdir(dir, 'pR')
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200205
206 var lines =<< trim END
207 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000208 export def NoFunction()
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200209 # comment
210 g:runtime = 'yes'
211 enddef
212 END
213 writefile(lines, dir .. '/script.vim')
214
215 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100216 exe 'set rtp=' .. getcwd() .. '/Xnamedir'
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200217 lines =<< trim END
218 call script#Function()
219 END
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000220 v9.CheckScriptFailure(lines, 'E117:', 1)
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200221
222 &rtp = save_rtp
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200223enddef
224
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200225def Test_autoload_names()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100226 var dir = 'Xandir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100227 mkdir(dir, 'pR')
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200228
229 var lines =<< trim END
230 func foobar#function()
231 return 'yes'
232 endfunc
233 let foobar#var = 'no'
234 END
235 writefile(lines, dir .. '/foobar.vim')
236
237 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100238 exe 'set rtp=' .. getcwd() .. '/Xandir'
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200239
240 lines =<< trim END
241 assert_equal('yes', foobar#function())
242 var Function = foobar#function
243 assert_equal('yes', Function())
244
245 assert_equal('no', foobar#var)
246 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000247 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200248
249 &rtp = save_rtp
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200250enddef
251
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200252def Test_autoload_error_in_script()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100253 var dir = 'Xaedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100254 mkdir(dir, 'pR')
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200255
256 var lines =<< trim END
257 func scripterror#function()
258 let g:called_function = 'yes'
259 endfunc
260 let 0 = 1
261 END
262 writefile(lines, dir .. '/scripterror.vim')
263
264 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100265 exe 'set rtp=' .. getcwd() .. '/Xaedir'
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200266
267 g:called_function = 'no'
268 # The error in the autoload script cannot be checked with assert_fails(), use
269 # CheckDefSuccess() instead of CheckDefFailure()
270 try
Bram Moolenaar62aec932022-01-29 21:45:34 +0000271 v9.CheckDefSuccess(['scripterror#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200272 catch
273 assert_match('E121: Undefined variable: 0', v:exception)
274 endtry
275 assert_equal('no', g:called_function)
276
277 lines =<< trim END
278 func scriptcaught#function()
279 let g:called_function = 'yes'
280 endfunc
281 try
282 let 0 = 1
283 catch
284 let g:caught = v:exception
285 endtry
286 END
287 writefile(lines, dir .. '/scriptcaught.vim')
288
289 g:called_function = 'no'
Bram Moolenaar62aec932022-01-29 21:45:34 +0000290 v9.CheckDefSuccess(['scriptcaught#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200291 assert_match('E121: Undefined variable: 0', g:caught)
292 assert_equal('yes', g:called_function)
293
294 &rtp = save_rtp
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200295enddef
296
Bram Moolenaar62aec932022-01-29 21:45:34 +0000297def s:CallRecursive(n: number): number
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100298 return CallRecursive(n + 1)
299enddef
300
Bram Moolenaar62aec932022-01-29 21:45:34 +0000301def s:CallMapRecursive(l: list<number>): number
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100302 return map(l, (_, v) => CallMapRecursive([v]))[0]
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100303enddef
304
305def Test_funcdepth_error()
306 set maxfuncdepth=10
307
308 var caught = false
309 try
310 CallRecursive(1)
311 catch /E132:/
312 caught = true
313 endtry
314 assert_true(caught)
315
316 caught = false
317 try
318 CallMapRecursive([1])
319 catch /E132:/
320 caught = true
321 endtry
322 assert_true(caught)
323
324 set maxfuncdepth&
325enddef
326
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100327def Test_endfunc_enddef()
328 var lines =<< trim END
329 def Test()
330 echo 'test'
331 endfunc
332 enddef
333 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000334 v9.CheckScriptFailure(lines, 'E1151:', 3)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100335
336 lines =<< trim END
337 def Test()
338 func Nested()
339 echo 'test'
340 enddef
341 enddef
342 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000343 v9.CheckScriptFailure(lines, 'E1152:', 4)
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100344
345 lines =<< trim END
346 def Ok()
347 echo 'hello'
348 enddef | echo 'there'
349 def Bad()
350 echo 'hello'
351 enddef there
352 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000353 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100354enddef
355
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100356def Test_missing_endfunc_enddef()
357 var lines =<< trim END
358 vim9script
359 def Test()
360 echo 'test'
361 endef
362 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000363 v9.CheckScriptFailure(lines, 'E1057:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100364
365 lines =<< trim END
366 vim9script
367 func Some()
368 echo 'test'
369 enfffunc
370 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000371 v9.CheckScriptFailure(lines, 'E126:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100372enddef
373
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100374def Test_white_space_before_paren()
375 var lines =<< trim END
376 vim9script
377 def Test ()
378 echo 'test'
379 enddef
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 vim9script
385 func Test ()
386 echo 'test'
387 endfunc
388 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000389 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100390
391 lines =<< trim END
392 def Test ()
393 echo 'test'
394 enddef
395 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000396 v9.CheckScriptFailure(lines, 'E1068:', 1)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100397
398 lines =<< trim END
399 func Test ()
400 echo 'test'
401 endfunc
402 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000403 v9.CheckScriptSuccess(lines)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100404enddef
405
Bram Moolenaar832ea892021-01-08 21:55:26 +0100406def Test_enddef_dict_key()
407 var d = {
408 enddef: 'x',
409 endfunc: 'y',
410 }
411 assert_equal({enddef: 'x', endfunc: 'y'}, d)
412enddef
413
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200414def ReturnString(): string
415 return 'string'
416enddef
417
418def ReturnNumber(): number
419 return 123
420enddef
421
422let g:notNumber = 'string'
423
424def ReturnGlobal(): number
425 return g:notNumber
426enddef
427
428def Test_return_something()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000429 g:ReturnString()->assert_equal('string')
430 g:ReturnNumber()->assert_equal(123)
Bram Moolenaar848fadd2022-01-30 15:28:30 +0000431 assert_fails('g:ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaaref7aadb2022-01-18 18:46:07 +0000432
433 var lines =<< trim END
434 vim9script
435
436 def Msg()
437 echomsg 'in Msg()...'
438 enddef
439
440 def Func()
441 return Msg()
442 enddef
443 defcompile
444 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000445 v9.CheckScriptFailure(lines, 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200446enddef
447
Bram Moolenaare32e5162021-01-21 20:21:29 +0100448def Test_check_argument_type()
449 var lines =<< trim END
450 vim9script
451 def Val(a: number, b: number): number
452 return 0
453 enddef
454 def Func()
455 var x: any = true
456 Val(0, x)
457 enddef
458 disass Func
459 Func()
460 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000461 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
Bram Moolenaar56310d32022-12-27 17:25:05 +0000462
463 lines =<< trim END
464 vim9script
465
466 def Foobar(Fn: func(any, ?string): any)
467 enddef
468
469 Foobar((t) => 0)
470 END
471 v9.CheckScriptSuccess(lines)
Bram Moolenaare32e5162021-01-21 20:21:29 +0100472enddef
473
Bram Moolenaarefd88552020-06-18 20:50:10 +0200474def Test_missing_return()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000475 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200476 ' if g:cond',
477 ' echo "no return"',
478 ' else',
479 ' return 0',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100480 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200481 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000482 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200483 ' if g:cond',
484 ' return 1',
485 ' else',
486 ' echo "no return"',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100487 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200488 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000489 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200490 ' if g:cond',
491 ' return 1',
492 ' else',
493 ' return 2',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100494 ' endif',
495 ' return 3',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200496 'enddef'], 'E1095:')
497enddef
498
Bram Moolenaarcf2610c2023-05-14 19:59:59 +0100499def Test_not_missing_return()
500 var lines =<< trim END
501 def Funky(): number
502 if false
503 return 0
504 endif
505 throw 'Error'
506 enddef
507 defcompile
508 END
509 v9.CheckScriptSuccess(lines)
510enddef
511
Bram Moolenaar403dc312020-10-17 19:29:51 +0200512def Test_return_bool()
513 var lines =<< trim END
514 vim9script
515 def MenuFilter(id: number, key: string): bool
516 return popup_filter_menu(id, key)
517 enddef
518 def YesnoFilter(id: number, key: string): bool
519 return popup_filter_yesno(id, key)
520 enddef
521 defcompile
522 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000523 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200524enddef
525
mityu500c4442022-12-02 18:12:05 +0000526def Test_return_void_comment_follows()
527 var lines =<< trim END
528 vim9script
529 def ReturnCommentFollows(): void
530 return # Some comment
531 enddef
532 defcompile
533 END
534 v9.CheckScriptSuccess(lines)
535enddef
536
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200537let s:nothing = 0
538def ReturnNothing()
539 s:nothing = 1
540 if true
541 return
542 endif
543 s:nothing = 2
544enddef
545
546def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000547 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200548 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200549enddef
550
Bram Moolenaar648ea762021-01-15 19:04:32 +0100551def Test_return_invalid()
552 var lines =<< trim END
553 vim9script
554 def Func(): invalid
555 return xxx
556 enddef
557 defcompile
558 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000559 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100560
561 lines =<< trim END
562 vim9script
563 def Test(Fun: func(number): number): list<number>
564 return map([1, 2, 3], (_, i) => Fun(i))
565 enddef
566 defcompile
567 def Inc(nr: number): nr
568 return nr + 2
569 enddef
570 echo Test(Inc)
571 END
572 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000573 v9.CheckScriptFailure(lines, 'E1010:')
574 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100575enddef
576
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200577def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000578 # This used to fail but now the actual list type is checked, and since it has
579 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200580 var lines =<< trim END
581 vim9script
582 def Func(): list<string>
583 var l: list<any>
584 l->add('string')
585 return l
586 enddef
587 echo Func()
588 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000589 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000590
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200591 lines =<< trim END
592 vim9script
593 def Func(): list<string>
594 var l: list<any>
595 l += ['string']
596 return l
597 enddef
598 echo Func()
599 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000600 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200601enddef
602
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000603def Test_return_any_two_types()
604 var lines =<< trim END
605 vim9script
606
607 def G(Fn: func(string): any)
608 g:result = Fn("hello")
609 enddef
610
611 def F(a: number, b: string): any
612 echo b
613 if a > 0
614 return 1
615 else
616 return []
617 endif
618 enddef
619
620 G(function(F, [1]))
621 END
622 v9.CheckScriptSuccess(lines)
623 assert_equal(1, g:result)
624 unlet g:result
625enddef
626
Bram Moolenaar62aec932022-01-29 21:45:34 +0000627func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200628 let g:counter += 1
629endfunc
630
631def Test_call_ufunc_count()
632 g:counter = 1
633 Increment()
634 Increment()
635 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200636 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200637 g:counter->assert_equal(4)
638 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200639 unlet g:counter
640enddef
641
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000642def Test_call_ufunc_failure()
643 var lines =<< trim END
644 vim9script
645 def Tryit()
646 g:Global(1, 2, 3)
647 enddef
648
649 func g:Global(a, b, c)
650 echo a:a a:b a:c
651 endfunc
652
653 defcompile
654
655 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000656 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000657 endfunc
658 Tryit()
659 END
660 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
661 delfunc g:Global
662
663 lines =<< trim END
664 vim9script
665
666 g:Ref = function('len')
667 def Tryit()
668 g:Ref('x')
669 enddef
670
671 defcompile
672
673 g:Ref = function('add')
674 Tryit()
675 END
676 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
677 unlet g:Ref
678enddef
679
Bram Moolenaar62aec932022-01-29 21:45:34 +0000680def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200681 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200682 for s in rest
683 res ..= ',' .. s
684 endfor
685 return res
686enddef
687
688def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200689 MyVarargs('one')->assert_equal('one')
690 MyVarargs('one', 'two')->assert_equal('one,two')
691 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200692enddef
693
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200694def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000695 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200696enddef
697
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200698def MyDefaultArgs(name = 'string'): string
699 return name
700enddef
701
Bram Moolenaar62aec932022-01-29 21:45:34 +0000702def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200703 return second ? name : 'none'
704enddef
705
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200706
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200707def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000708 g:MyDefaultArgs()->assert_equal('string')
709 g:MyDefaultArgs(v:none)->assert_equal('string')
710 g:MyDefaultArgs('one')->assert_equal('one')
711 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200712
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200713 MyDefaultSecond('test')->assert_equal('test')
714 MyDefaultSecond('test', true)->assert_equal('test')
715 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200716
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200717 var lines =<< trim END
718 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
719 return name .. aa .. bb
720 enddef
721
722 MyDefaultThird('->')->assert_equal('->aabb')
723 MyDefaultThird('->', v:none)->assert_equal('->aabb')
724 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
725 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
726 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
727 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
728 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200729
730 def DefArg(mandatory: any, optional = mandatory): string
731 return mandatory .. optional
732 enddef
733 DefArg(1234)->assert_equal('12341234')
734 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200735 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000736 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200737
Bram Moolenaar62aec932022-01-29 21:45:34 +0000738 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100739 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000740 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 +0100741 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000742 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100743
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200744 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100745 vim9script
746 def Func(a = b == 0 ? 1 : 2, b = 0)
747 enddef
748 defcompile
749 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000750 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000751
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000752 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000753 lines =<< trim END
754 vim9script
755 var a: any
756 def Func(arg: string = a)
757 echo arg
758 enddef
759 defcompile
760 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000761 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
762 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000763
764 # using global variable does not require type cast
765 lines =<< trim END
766 vim9script
767 def Func(arg: string = g:str)
768 echo arg
769 enddef
770 g:str = 'works'
771 Func()
772 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000773 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200774enddef
775
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100776def Test_using_vnone_default()
777 var lines =<< trim END
778 vim9script
779
780 def F(a: string = v:none)
781 if a isnot v:none
782 var b = a
783 endif
784 enddef
785 F()
786 END
787 v9.CheckScriptSuccess(lines)
788
Bram Moolenaar2ba51232023-05-15 16:22:38 +0100789 lines =<< trim END
790 vim9script
791
792 export def Floats(x: float, y = 2.0, z = 5.0)
793 g:result = printf("%.2f %.2f %.2f", x, y, z)
794 enddef
795 END
796 writefile(lines, 'Xlib.vim', 'D')
797
798 # test using a function reference in script-local variable
799 lines =<< trim END
800 vim9script
801
802 import './Xlib.vim'
803 const Floatfunc = Xlib.Floats
804 Floatfunc(1.0, v:none, 3.0)
805 END
806 v9.CheckScriptSuccess(lines)
807 assert_equal('1.00 2.00 3.00', g:result)
808 unlet g:result
809
810 # test calling the imported function
811 lines =<< trim END
812 vim9script
813
814 import './Xlib.vim'
815 Xlib.Floats(1.0, v:none, 3.0)
816 END
817 v9.CheckScriptSuccess(lines)
818 assert_equal('1.00 2.00 3.00', g:result)
819 unlet g:result
820
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100821 # TODO: this should give an error for using a missing argument
822 # lines =<< trim END
823 # vim9script
824
825 # def F(a: string = v:none)
826 # var b = a
827 # enddef
828 # F()
829 # END
830 # v9.CheckScriptFailure(lines, 'E99:')
831enddef
832
Bram Moolenaar47bba532023-01-20 18:49:46 +0000833def Test_convert_number_to_float()
834 var lines =<< trim END
835 vim9script
836 def Foo(a: float, b: float): float
837 return a + b
838 enddef
839
840 assert_equal(5.3, Foo(3.3, 2))
841 END
842 v9.CheckScriptSuccess(lines)
843enddef
844
Bram Moolenaar62aec932022-01-29 21:45:34 +0000845def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100846 a: number, #comment
847 b: bool, # comment
848 c: string) #comment
849 assert_equal(4, a)
850 assert_equal(true, b)
851 assert_equal('yes', c)
852enddef
853
854def Test_func_with_comments()
855 FuncWithComment(4, true, 'yes')
856
857 var lines =<< trim END
858 def Func(# comment
859 arg: string)
860 enddef
861 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000862 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100863
864 lines =<< trim END
865 def Func(
866 arg: string# comment
867 )
868 enddef
869 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000870 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100871
872 lines =<< trim END
873 def Func(
874 arg: string
875 )# comment
876 enddef
877 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000878 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100879enddef
880
Bram Moolenaar04b12692020-05-04 23:24:44 +0200881def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000882 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200883 return 'nested ' .. arg
884 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000885 NestedDef(':def')->assert_equal('nested :def')
886
887 func NestedFunc(arg)
888 return 'nested ' .. a:arg
889 endfunc
890 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200891
Bram Moolenaar62aec932022-01-29 21:45:34 +0000892 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
893 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200894
Bram Moolenaar62aec932022-01-29 21:45:34 +0000895 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
896 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200897
Bram Moolenaar54021752020-12-06 18:50:36 +0100898 var lines =<< trim END
899 def Outer()
900 def Inner()
901 # comment
902 enddef
903 def Inner()
904 enddef
905 enddef
906 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000907 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100908
909 lines =<< trim END
910 def Outer()
911 def Inner()
912 # comment
913 enddef
914 def! Inner()
915 enddef
916 enddef
917 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000918 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100919
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000920 lines =<< trim END
921 vim9script
922 def Outer()
923 def Inner()
924 g:result = 'ok'
925 enddef
926 Inner()
927 enddef
928 Outer()
929 Inner()
930 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000931 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000932 assert_equal('ok', g:result)
933 unlet g:result
934
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000935 lines =<< trim END
936 vim9script
937 def Outer()
938 def _Inner()
939 echo 'bad'
940 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000941 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000942 enddef
943 defcompile
944 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000945 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000946
947 lines =<< trim END
948 vim9script
949 def Outer()
950 def g:inner()
951 echo 'bad'
952 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000953 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000954 enddef
955 defcompile
956 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000957 v9.CheckScriptFailure(lines, 'E1267:')
958
959 lines =<< trim END
960 vim9script
961 def g:_Func()
962 echo 'bad'
963 enddef
964 END
965 v9.CheckScriptFailure(lines, 'E1267:')
966
967 lines =<< trim END
968 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000969 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +0000970 echo 'bad'
971 enddef
972 END
973 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000974
Bram Moolenaar54021752020-12-06 18:50:36 +0100975 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +0100976 lines =<< trim END
977 vim9script
978 var thecount = 0
979 if true
980 def Test(): number
981 def TheFunc(): number
982 thecount += 1
983 return thecount
984 enddef
985 return TheFunc()
986 enddef
987 endif
988 defcompile
989 assert_equal(1, Test())
990 assert_equal(2, Test())
991 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000992 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +0100993
994 # also works when "thecount" is inside the "if" block
995 lines =<< trim END
996 vim9script
997 if true
998 var thecount = 0
999 def Test(): number
1000 def TheFunc(): number
1001 thecount += 1
1002 return thecount
1003 enddef
1004 return TheFunc()
1005 enddef
1006 endif
1007 defcompile
1008 assert_equal(1, Test())
1009 assert_equal(2, Test())
1010 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001011 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001012
Bram Moolenaara915fa02022-03-23 11:29:15 +00001013 # nested function with recursive call
1014 lines =<< trim END
1015 vim9script
1016
1017 def MyFunc(): number
1018 def Fib(n: number): number
1019 if n < 2
1020 return 1
1021 endif
1022 return Fib(n - 2) + Fib(n - 1)
1023 enddef
1024
1025 return Fib(5)
1026 enddef
1027
1028 assert_equal(8, MyFunc())
1029 END
1030 v9.CheckScriptSuccess(lines)
1031
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001032 lines =<< trim END
1033 vim9script
1034 def Outer()
1035 def Inner()
1036 echo 'hello'
1037 enddef burp
1038 enddef
1039 defcompile
1040 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001041 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001042enddef
1043
Bram Moolenaar1889f492022-08-16 19:34:44 +01001044def Test_nested_function_fails()
1045 var lines =<< trim END
1046 def T()
1047 def Func(g: string):string
1048 enddef
1049 Func()
1050 enddef
1051 silent! defcompile
1052 END
1053 v9.CheckScriptFailure(lines, 'E1069:')
1054enddef
1055
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001056def Test_not_nested_function()
1057 echo printf('%d',
1058 function('len')('xxx'))
1059enddef
1060
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001061func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001062 call MyDefaultArgs()->assert_equal('string')
1063 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001064 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001065endfunc
1066
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001067def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001068 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001069 vim9script
1070 def Outer()
1071 def g:Inner(): string
1072 return 'inner'
1073 enddef
1074 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001075 defcompile
1076 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001077 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001078 delfunc g:Inner
1079 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001080 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001081 delfunc g:Inner
1082 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001083 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001084 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001085 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001086 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001087
1088 lines =<< trim END
1089 vim9script
1090 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001091 func g:Inner()
1092 return 'inner'
1093 endfunc
1094 enddef
1095 defcompile
1096 Outer()
1097 g:Inner()->assert_equal('inner')
1098 delfunc g:Inner
1099 Outer()
1100 g:Inner()->assert_equal('inner')
1101 delfunc g:Inner
1102 Outer()
1103 g:Inner()->assert_equal('inner')
1104 delfunc g:Inner
1105 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001106 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001107
1108 lines =<< trim END
1109 vim9script
1110 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001111 def g:Inner(): string
1112 return 'inner'
1113 enddef
1114 enddef
1115 defcompile
1116 Outer()
1117 Outer()
1118 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001119 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001120 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001121
1122 lines =<< trim END
1123 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001124 def Outer()
1125 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001126 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001127 enddef
1128 g:Inner()
1129 enddef
1130 Outer()
1131 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001132 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001133 delfunc g:Inner
1134
1135 lines =<< trim END
1136 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001137 def Func()
1138 echo 'script'
1139 enddef
1140 def Outer()
1141 def Func()
1142 echo 'inner'
1143 enddef
1144 enddef
1145 defcompile
1146 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001147 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001148
1149 lines =<< trim END
1150 vim9script
1151 def Func()
1152 echo 'script'
1153 enddef
1154 def Func()
1155 echo 'script'
1156 enddef
1157 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001158 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001159enddef
1160
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001161def DefListAll()
1162 def
1163enddef
1164
1165def DefListOne()
1166 def DefListOne
1167enddef
1168
1169def DefListMatches()
1170 def /DefList
1171enddef
1172
1173def Test_nested_def_list()
1174 var funcs = split(execute('call DefListAll()'), "\n")
1175 assert_true(len(funcs) > 10)
1176 assert_true(funcs->index('def DefListAll()') >= 0)
1177
1178 funcs = split(execute('call DefListOne()'), "\n")
1179 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1180
1181 funcs = split(execute('call DefListMatches()'), "\n")
1182 assert_true(len(funcs) >= 3)
1183 assert_true(funcs->index('def DefListAll()') >= 0)
1184 assert_true(funcs->index('def DefListOne()') >= 0)
1185 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001186
1187 var lines =<< trim END
1188 vim9script
1189 def Func()
1190 def +Func+
1191 enddef
1192 defcompile
1193 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001194 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001195enddef
1196
Bram Moolenaare08be092022-02-17 13:08:26 +00001197def Test_global_function_not_found()
1198 var lines =<< trim END
1199 g:Ref = 123
1200 call g:Ref()
1201 END
1202 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1203enddef
1204
Bram Moolenaar333894b2020-08-01 18:53:07 +02001205def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001206 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001207 vim9script
1208 def g:Func(): string
1209 return 'global'
1210 enddef
1211 def Func(): string
1212 return 'local'
1213 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001214 g:Func()->assert_equal('global')
1215 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001216 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001217 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001218 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001219
1220 lines =<< trim END
1221 vim9script
1222 def g:Funcy()
1223 echo 'funcy'
1224 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001225 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001226 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001227 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001228enddef
1229
Bram Moolenaar0f769812020-09-12 18:32:34 +02001230def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001231 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001232 vim9script
1233 def g:Gfunc(): string
1234 return 'global'
1235 enddef
1236 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001237 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001238 return Gfunc('testing')
1239 enddef
1240 g:Gfunc()->assert_equal('global')
1241 AnotherFunc()->assert_equal(7)
1242 delfunc g:Gfunc
1243 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001244 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001245
1246 lines =<< trim END
1247 vim9script
1248 def g:Func(): string
1249 return 'global'
1250 enddef
1251 def AnotherFunc()
1252 g:Func = function('len')
1253 enddef
1254 AnotherFunc()
1255 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001256 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001257 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001258
Bram Moolenaar62aec932022-01-29 21:45:34 +00001259 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001260 lines =<< trim END
1261 vim9script
1262 def g:Func(): string
1263 return 'global'
1264 enddef
1265 def AnotherFunc(): string
1266 return Func()
1267 enddef
1268 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001269 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001270 v9.CheckScriptFailure(lines, 'E117:')
1271 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001272
1273 lines =<< trim END
1274 vim9script
1275 def g:Func(): string
1276 return 'global'
1277 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001278 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001279 delfunc g:Func
1280 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001281 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001282
1283 # This does not shadow "i" which is visible only inside the for loop
1284 lines =<< trim END
1285 vim9script
1286
1287 def Foo(i: number)
1288 echo i
1289 enddef
1290
1291 for i in range(3)
1292 # Foo() is compiled here
1293 Foo(i)
1294 endfor
1295 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001296 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001297enddef
1298
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001299func TakesOneArg(arg)
1300 echo a:arg
1301endfunc
1302
1303def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001304 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1305 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1306 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1307 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001308
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001309 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001310 vim9script
1311 def Func(s: string)
1312 echo s
1313 enddef
1314 Func([])
1315 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001316 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001317
Bram Moolenaar9a015112021-12-31 14:06:45 +00001318 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001319 lines =<< trim END
1320 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001321 var name = 'piet'
1322 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001323 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001324 enddef
1325 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001326 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001327
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001328 # same, inside the same block
1329 lines =<< trim END
1330 vim9script
1331 if true
1332 var name = 'piet'
1333 def FuncOne(name: string)
1334 echo name
1335 enddef
1336 endif
1337 END
1338 v9.CheckScriptFailure(lines, 'E1168:')
1339
1340 # variable in other block is OK
1341 lines =<< trim END
1342 vim9script
1343 if true
1344 var name = 'piet'
1345 endif
1346 def FuncOne(name: string)
1347 echo name
1348 enddef
1349 END
1350 v9.CheckScriptSuccess(lines)
1351
Bram Moolenaardce24412022-02-08 20:35:30 +00001352 # with another variable in another block
1353 lines =<< trim END
1354 vim9script
1355 if true
1356 var name = 'piet'
1357 # define a function so that the variable isn't cleared
1358 def GetItem(): string
1359 return item
1360 enddef
1361 endif
1362 if true
1363 var name = 'peter'
1364 def FuncOne(name: string)
1365 echo name
1366 enddef
1367 endif
1368 END
1369 v9.CheckScriptFailure(lines, 'E1168:')
1370
1371 # only variable in another block is OK
1372 lines =<< trim END
1373 vim9script
1374 if true
1375 var name = 'piet'
1376 # define a function so that the variable isn't cleared
1377 def GetItem(): string
1378 return item
1379 enddef
1380 endif
1381 if true
1382 def FuncOne(name: string)
1383 echo name
1384 enddef
1385 endif
1386 END
1387 v9.CheckScriptSuccess(lines)
1388
Bram Moolenaar9a015112021-12-31 14:06:45 +00001389 # argument name declared later is only found when compiling
1390 lines =<< trim END
1391 vim9script
1392 def FuncOne(name: string)
1393 echo nr
1394 enddef
1395 var name = 'piet'
1396 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001397 v9.CheckScriptSuccess(lines)
1398 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001399
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001400 lines =<< trim END
1401 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001402 def FuncOne(nr: number)
1403 echo nr
1404 enddef
1405 def FuncTwo()
1406 FuncOne()
1407 enddef
1408 defcompile
1409 END
1410 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001411 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001412 try
1413 source Xscript
1414 catch
1415 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1416 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1417 didCatch = true
1418 endtry
1419 assert_true(didCatch)
1420
1421 lines =<< trim END
1422 vim9script
1423 def FuncOne(nr: number)
1424 echo nr
1425 enddef
1426 def FuncTwo()
1427 FuncOne(1, 2)
1428 enddef
1429 defcompile
1430 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001431 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001432 didCatch = false
1433 try
1434 source Xscript
1435 catch
1436 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1437 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1438 didCatch = true
1439 endtry
1440 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001441enddef
1442
Bram Moolenaar50824712020-12-20 21:10:17 +01001443def Test_call_funcref_wrong_args()
1444 var head =<< trim END
1445 vim9script
1446 def Func3(a1: string, a2: number, a3: list<number>)
1447 echo a1 .. a2 .. a3[0]
1448 enddef
1449 def Testme()
1450 var funcMap: dict<func> = {func: Func3}
1451 END
1452 var tail =<< trim END
1453 enddef
1454 Testme()
1455 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001456 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001457
Bram Moolenaar62aec932022-01-29 21:45:34 +00001458 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1459 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001460
1461 var lines =<< trim END
1462 vim9script
1463 var Ref: func(number): any
1464 Ref = (j) => !j
1465 echo Ref(false)
1466 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001467 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001468
1469 lines =<< trim END
1470 vim9script
1471 var Ref: func(number): any
1472 Ref = (j) => !j
1473 call Ref(false)
1474 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001475 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001476enddef
1477
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001478def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001479 var lines =<< trim END
1480 var Callback = (..._) => 'anything'
1481 assert_equal('anything', Callback())
1482 assert_equal('anything', Callback(1))
1483 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001484
1485 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001486 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001487 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001488
Bram Moolenaar62aec932022-01-29 21:45:34 +00001489 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001490 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001491
Bram Moolenaar2a389082021-04-09 20:24:31 +02001492 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001493 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001494 echo Ref(1, 'x')
1495 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001496 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001497
1498 lines =<< trim END
1499 var Ref: func(job, string, number)
1500 Ref = (x, y) => 0
1501 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001502 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001503
1504 lines =<< trim END
1505 var Ref: func(job, string)
1506 Ref = (x, y, z) => 0
1507 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001508 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001509
1510 lines =<< trim END
1511 var one = 1
1512 var l = [1, 2, 3]
1513 echo map(l, (one) => one)
1514 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001515 v9.CheckDefFailure(lines, 'E1167:')
1516 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001517
1518 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001519 var Ref: func(any, ?any): bool
1520 Ref = (_, y = 1) => false
1521 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001522 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001523
1524 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001525 var a = 0
1526 var b = (a == 0 ? 1 : 2)
1527 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001528 var txt = 'a'
1529 b = (txt =~ 'x' ? 1 : 2)
1530 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001531 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001532 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001533
1534 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001535 def ShadowLocal()
1536 var one = 1
1537 var l = [1, 2, 3]
1538 echo map(l, (one) => one)
1539 enddef
1540 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001541 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001542
1543 lines =<< trim END
1544 def Shadowarg(one: number)
1545 var l = [1, 2, 3]
1546 echo map(l, (one) => one)
1547 enddef
1548 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001549 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001550
1551 lines =<< trim END
1552 echo ((a) => a)('aa', 'bb')
1553 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001554 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001555
1556 lines =<< trim END
1557 echo 'aa'->((a) => a)('bb')
1558 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001559 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1560 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001561enddef
1562
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001563def Test_lambda_line_nr()
1564 var lines =<< trim END
1565 vim9script
1566 # comment
1567 # comment
1568 var id = timer_start(1'000, (_) => 0)
1569 var out = execute('verbose ' .. timer_info(id)[0].callback
1570 ->string()
1571 ->substitute("('\\|')", ' ', 'g'))
1572 assert_match('Last set from .* line 4', out)
1573 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001574 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001575enddef
1576
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001577def FilterWithCond(x: string, Cond: func(string): bool): bool
1578 return Cond(x)
1579enddef
1580
Bram Moolenaar0346b792021-01-31 22:18:29 +01001581def Test_lambda_return_type()
1582 var lines =<< trim END
1583 var Ref = (): => 123
1584 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001585 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001586
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001587 # no space before the return type
1588 lines =<< trim END
1589 var Ref = (x):number => x + 1
1590 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001591 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001592
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001593 # this works
1594 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001595 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001596 endfor
1597
1598 # this fails
1599 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001600 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001601 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001602 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 +02001603
1604 lines =<< trim END
1605 var Lambda1 = (x) => {
1606 return x
1607 }
1608 assert_equal('asdf', Lambda1('asdf'))
1609 var Lambda2 = (x): string => {
1610 return x
1611 }
1612 assert_equal('foo', Lambda2('foo'))
1613 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001614 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001615
1616 lines =<< trim END
1617 var Lambda = (x): string => {
1618 return x
1619 }
1620 echo Lambda(['foo'])
1621 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001622 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001623enddef
1624
Bram Moolenaar709664c2020-12-12 14:33:41 +01001625def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001626 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001627 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001628 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001629enddef
1630
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001631def Test_lambda_invalid_block()
1632 var lines =<< trim END
1633 timer_start(0, (_) => { # echo
1634 echo 'yes'
1635 })
1636 END
1637 v9.CheckDefAndScriptSuccess(lines)
1638
1639 lines =<< trim END
1640 timer_start(0, (_) => { " echo
1641 echo 'yes'
1642 })
1643 END
1644 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1645
1646 lines =<< trim END
1647 timer_start(0, (_) => { | echo
1648 echo 'yes'
1649 })
1650 END
1651 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1652enddef
1653
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001654def Test_lambda_with_following_cmd()
1655 var lines =<< trim END
1656 set ts=2
1657 var Lambda = () => {
1658 set ts=4
1659 } | set ts=3
1660 assert_equal(3, &ts)
1661 Lambda()
1662 assert_equal(4, &ts)
1663 END
1664 v9.CheckDefAndScriptSuccess(lines)
1665 set ts=8
1666enddef
1667
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001668def Test_pass_legacy_lambda_to_def_func()
1669 var lines =<< trim END
1670 vim9script
1671 func Foo()
1672 eval s:Bar({x -> 0})
1673 endfunc
1674 def Bar(y: any)
1675 enddef
1676 Foo()
1677 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001678 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001679
1680 lines =<< trim END
1681 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001682 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001683 enddef
1684 legacy call g:TestFunc({-> 0})
1685 delfunc g:TestFunc
1686
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001687 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001688 enddef
1689 legacy call g:TestFunc({nr -> 0})
1690 delfunc g:TestFunc
1691 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001692 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001693enddef
1694
Bram Moolenaar844fb642021-10-23 13:32:30 +01001695def Test_lambda_in_reduce_line_break()
1696 # this was using freed memory
1697 var lines =<< trim END
1698 vim9script
1699 const result: dict<number> =
1700 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1701 ->reduce((acc, val) => {
1702 if has_key(acc, val)
1703 acc[val] += 1
1704 return acc
1705 else
1706 acc[val] = 1
1707 return acc
1708 endif
1709 }, {})
1710 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1711 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001712 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001713enddef
1714
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001715def Test_set_opfunc_to_lambda()
1716 var lines =<< trim END
1717 vim9script
1718 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1719 def CountSpaces(type = ''): string
1720 if type == ''
1721 &operatorfunc = (t) => CountSpaces(t)
1722 return 'g@'
1723 endif
1724 normal! '[V']y
1725 g:result = getreg('"')->count(' ')
1726 return ''
1727 enddef
1728 new
1729 'a b c d e'->setline(1)
1730 feedkeys("\<F4>", 'x')
1731 assert_equal(4, g:result)
1732 bwipe!
1733 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001734 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001735enddef
1736
Bram Moolenaaref082e12021-12-12 21:02:03 +00001737def Test_set_opfunc_to_global_function()
1738 var lines =<< trim END
1739 vim9script
1740 def g:CountSpaces(type = ''): string
1741 normal! '[V']y
1742 g:result = getreg('"')->count(' ')
1743 return ''
1744 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001745 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001746 &operatorfunc = g:CountSpaces
1747 new
1748 'a b c d e'->setline(1)
1749 feedkeys("g@_", 'x')
1750 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001751
1752 &operatorfunc = ''
1753 g:result = 0
1754 # global function works in :def function
1755 def Func()
1756 &operatorfunc = g:CountSpaces
1757 enddef
1758 Func()
1759 feedkeys("g@_", 'x')
1760 assert_equal(4, g:result)
1761
Bram Moolenaaref082e12021-12-12 21:02:03 +00001762 bwipe!
1763 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001764 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001765 &operatorfunc = ''
1766enddef
1767
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001768def Test_use_script_func_name_with_prefix()
1769 var lines =<< trim END
1770 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001771 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001772 return 'it'
1773 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001774 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001775 assert_equal('it', Fn())
1776 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001777 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001778enddef
1779
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001780def Test_lambda_type_allocated()
1781 # Check that unreferencing a partial using a lambda can use the variable type
1782 # after the lambda has been freed and does not leak memory.
1783 var lines =<< trim END
1784 vim9script
1785
1786 func MyomniFunc1(val, findstart, base)
1787 return a:findstart ? 0 : []
1788 endfunc
1789
1790 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1791 &omnifunc = Lambda
1792 Lambda = (a, b) => MyomniFunc1(20, a, b)
1793 &omnifunc = string(Lambda)
1794 Lambda = (a, b) => strlen(a)
1795 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001796 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001797enddef
1798
Bram Moolenaara7583c42022-05-07 21:14:05 +01001799def Test_define_lambda_in_execute()
1800 var lines =<< trim [CODE]
1801 vim9script
1802
1803 def BuildFuncMultiLine(): func
1804 var x =<< trim END
1805 g:SomeRandomFunc = (d: dict<any>) => {
1806 return d.k1 + d.k2
1807 }
1808 END
1809 execute(x)
1810 return g:SomeRandomFunc
1811 enddef
1812 var ResultPlus = BuildFuncMultiLine()
1813 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1814 [CODE]
1815 v9.CheckScriptSuccess(lines)
1816 unlet g:SomeRandomFunc
1817enddef
1818
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001819" Default arg and varargs
1820def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001821 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001822 for s in rest
1823 res ..= ',' .. s
1824 endfor
1825 return res
1826enddef
1827
1828def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001829 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1830 g:MyDefVarargs('one')->assert_equal('one,foo')
1831 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1832 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1833 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001834 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001835 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001836 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001837
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001838 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001839 vim9script
1840 def Func(...l: list<string>)
1841 echo l
1842 enddef
1843 Func('a', 'b', 'c')
1844 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001845 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001846
1847 lines =<< trim END
1848 vim9script
1849 def Func(...l: list<string>)
1850 echo l
1851 enddef
1852 Func()
1853 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001854 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001855
1856 lines =<< trim END
1857 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001858 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001859 echo l
1860 enddef
1861 Func(0)
1862 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001863 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001864
1865 lines =<< trim END
1866 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001867 def Func(...l: any)
1868 echo l
1869 enddef
1870 Func(0)
1871 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001872 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001873
1874 lines =<< trim END
1875 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001876 def Func(..._l: list<string>)
1877 echo _l
1878 enddef
1879 Func('a', 'b', 'c')
1880 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001881 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001882
1883 lines =<< trim END
1884 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001885 def Func(...l: list<string>)
1886 echo l
1887 enddef
1888 Func(1, 2, 3)
1889 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001890 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001891
1892 lines =<< trim END
1893 vim9script
1894 def Func(...l: list<string>)
1895 echo l
1896 enddef
1897 Func('a', 9)
1898 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001899 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001900
1901 lines =<< trim END
1902 vim9script
1903 def Func(...l: list<string>)
1904 echo l
1905 enddef
1906 Func(1, 'a')
1907 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001908 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001909
1910 lines =<< trim END
1911 vim9script
1912 def Func( # some comment
1913 ...l = []
1914 )
1915 echo l
1916 enddef
1917 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001918 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001919
1920 lines =<< trim END
1921 vim9script
1922 def DoIt()
1923 g:Later('')
1924 enddef
1925 defcompile
1926 def g:Later(...l: list<number>)
1927 enddef
1928 DoIt()
1929 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001930 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001931enddef
1932
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001933let s:value = ''
1934
1935def FuncOneDefArg(opt = 'text')
1936 s:value = opt
1937enddef
1938
1939def FuncTwoDefArg(nr = 123, opt = 'text'): string
1940 return nr .. opt
1941enddef
1942
1943def FuncVarargs(...arg: list<string>): string
1944 return join(arg, ',')
1945enddef
1946
1947def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001948 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001949 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001950 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001951 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001952 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001953 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001954
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001955 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001956 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001957 RefDef2Arg()->assert_equal('123text')
1958 RefDef2Arg(99)->assert_equal('99text')
1959 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001960
Bram Moolenaar62aec932022-01-29 21:45:34 +00001961 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
1962 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001963
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001964 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001965 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001966 RefVarargs()->assert_equal('')
1967 RefVarargs('one')->assert_equal('one')
1968 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001969
Bram Moolenaar62aec932022-01-29 21:45:34 +00001970 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
1971 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001972enddef
1973
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001974" Only varargs
1975def MyVarargsOnly(...args: list<string>): string
1976 return join(args, ',')
1977enddef
1978
1979def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001980 g:MyVarargsOnly()->assert_equal('')
1981 g:MyVarargsOnly('one')->assert_equal('one')
1982 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
1983 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
1984 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001985enddef
1986
Bram Moolenaar36818a92023-01-03 12:33:26 +00001987def Test_varargs_mismatch()
1988 var lines =<< trim END
1989 vim9script
1990
1991 def Map(Fn: func(...any): number): number
1992 return Fn('12')
1993 enddef
1994
1995 var res = Map((v) => str2nr(v))
1996 assert_equal(12, res)
1997 END
Ernie Rael96952b22023-10-17 18:15:01 +02001998 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected func(...any): number but got func(any): number')
Bram Moolenaar36818a92023-01-03 12:33:26 +00001999enddef
2000
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002001def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00002002 var lines =<< trim END
2003 def Func(x: number)
2004 var x = 234
2005 enddef
2006 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002007 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002008
2009 lines =<< trim END
2010 def Func(Ref: number)
2011 def Ref()
2012 enddef
2013 enddef
2014 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002015 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002016enddef
2017
Bram Moolenaar62aec932022-01-29 21:45:34 +00002018def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002019 arg['key'] = 'value'
2020enddef
2021
Bram Moolenaar62aec932022-01-29 21:45:34 +00002022def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002023 arg[0] = 'value'
2024enddef
2025
2026def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002027 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002028 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002029 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002030 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002031 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002032 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002033 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002034
Bram Moolenaar62aec932022-01-29 21:45:34 +00002035 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002036 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002037enddef
2038
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002039" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002040def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002041 return firstline .. lastline
2042enddef
2043
2044def Test_argument_names()
2045 assert_equal('OK', WithReservedNames('O', 'K'))
2046enddef
2047
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002048def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002049 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002050 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002051enddef
2052
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002053func DefinedLater(arg)
2054 return a:arg
2055endfunc
2056
2057def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002058 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002059 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002060 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002061
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002062 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002063 vim9script
2064 def RetNumber(): number
2065 return 123
2066 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002067 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002068 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002069 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002070 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002071
2072 lines =<< trim END
2073 vim9script
2074 def RetNumber(): number
2075 return 123
2076 enddef
2077 def Bar(F: func: number): number
2078 return F()
2079 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002080 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002081 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002082 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002083 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002084
2085 lines =<< trim END
2086 vim9script
2087 def UseNumber(nr: number)
2088 echo nr
2089 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002090 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002091 Funcref(123)
2092 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002093 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002094
2095 lines =<< trim END
2096 vim9script
2097 def UseNumber(nr: number)
2098 echo nr
2099 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002100 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002101 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002102 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002103
2104 lines =<< trim END
2105 vim9script
2106 def EchoNr(nr = 34)
2107 g:echo = nr
2108 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002109 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002110 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002111 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002112 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002113 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002114 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002115 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002116
2117 lines =<< trim END
2118 vim9script
2119 def EchoList(...l: list<number>)
2120 g:echo = l
2121 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002122 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002123 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002124 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002125 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002126 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002127 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002128 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002129
2130 lines =<< trim END
2131 vim9script
2132 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2133 g:optarg = opt
2134 g:listarg = l
2135 return nr
2136 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002137 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002138 Funcref(10)->assert_equal(10)
2139 g:optarg->assert_equal(12)
2140 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002141
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002142 Funcref(11, 22)->assert_equal(11)
2143 g:optarg->assert_equal(22)
2144 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002145
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002146 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2147 g:optarg->assert_equal(18)
2148 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002149 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002150 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002151
2152 lines =<< trim END
2153 function s:func(num)
2154 return a:num * 2
2155 endfunction
2156
2157 def s:CallFuncref()
2158 var Funcref = function('s:func')
2159 Funcref(3)->assert_equal(6)
2160 enddef
2161 call s:CallFuncref()
2162 END
2163 v9.CheckScriptSuccess(lines)
2164
2165 lines =<< trim END
2166 function s:func(num)
2167 return a:num * 2
2168 endfunction
2169
2170 def s:CallFuncref()
2171 var Funcref = function(s:func)
2172 Funcref(3)->assert_equal(6)
2173 enddef
2174 call s:CallFuncref()
2175 END
2176 v9.CheckScriptSuccess(lines)
2177
2178 lines =<< trim END
2179 function s:func(num)
2180 return a:num * 2
2181 endfunction
2182
2183 def s:CallFuncref()
2184 var Funcref = s:func
2185 Funcref(3)->assert_equal(6)
2186 enddef
2187 call s:CallFuncref()
2188 END
2189 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002190enddef
2191
2192let SomeFunc = function('len')
2193let NotAFunc = 'text'
2194
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002195def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002196 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002197 var Ref1: func(bool): string
2198 var Ref2: func(bool): number
2199 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002200 Ref3 = g:cond ? Ref1 : Ref2
2201
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002202 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002203 var Refa1: func(bool): number
2204 var Refa2: func(bool, number): number
2205 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002206 Refa3 = g:cond ? Refa1 : Refa2
2207
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002208 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002209 var Refb1: func(bool, string): number
2210 var Refb2: func(string, number): number
2211 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002212 Refb3 = g:cond ? Refb1 : Refb2
2213enddef
2214
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002215def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002216 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002217enddef
2218
2219def DefinedEvenLater(arg: string): string
2220 return arg
2221enddef
2222
2223def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002224 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002225 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002226enddef
2227
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002228def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002229 var lines =<< trim END
2230 vim9script
2231 # Define an outer function
2232 def FirstFunction()
2233 # Define an inner function
2234 def SecondFunction()
2235 # the function has a body, a double free is detected.
2236 AAAAA
2237
2238 # enddef followed by | or } followed by # one or more characters
2239 enddef|BBBB
2240 enddef
2241
2242 # Compile all functions
2243 defcompile
2244 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002245 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002246enddef
2247
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002248def Test_nested_function_with_args_split()
2249 var lines =<< trim END
2250 vim9script
2251 def FirstFunction()
2252 def SecondFunction(
2253 )
2254 # had a double free if the right parenthesis of the nested function is
2255 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002256
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002257 enddef|BBBB
2258 enddef
2259 # Compile all functions
2260 defcompile
2261 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002262 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002263
2264 lines =<< trim END
2265 vim9script
2266 def FirstFunction()
2267 func SecondFunction()
2268 endfunc|BBBB
2269 enddef
2270 defcompile
2271 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002272 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002273enddef
2274
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002275def Test_error_in_function_args()
2276 var lines =<< trim END
2277 def FirstFunction()
2278 def SecondFunction(J =
2279 # Nois
2280 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002281
2282 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002283 enddef
2284 # Compile all functions
2285 defcompile
2286 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002287 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002288enddef
2289
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002290def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002291 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002292 'def Func(): number',
2293 'return "a"',
2294 'enddef',
2295 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002296 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002297 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002298 'def Func(): string',
2299 'return 1',
2300 'enddef',
2301 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002302 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002303 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002304 'def Func(): void',
2305 'return "a"',
2306 'enddef',
2307 'defcompile'],
2308 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002309 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002310 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002311 'def Func()',
2312 'return "a"',
2313 'enddef',
2314 'defcompile'],
2315 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002316 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002317
Bram Moolenaar62aec932022-01-29 21:45:34 +00002318 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002319 'def Func(): number',
2320 'return',
2321 'enddef',
2322 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002323 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002324
Bram Moolenaar62aec932022-01-29 21:45:34 +00002325 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002326 'def Func():number',
2327 'return 123',
2328 'enddef',
2329 'defcompile'], 'E1069:')
2330 delfunc! g:Func
2331
Bram Moolenaar62aec932022-01-29 21:45:34 +00002332 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002333 'def Func() :number',
2334 'return 123',
2335 'enddef',
2336 'defcompile'], 'E1059:')
2337 delfunc! g:Func
2338
Bram Moolenaar62aec932022-01-29 21:45:34 +00002339 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002340 'def Func() : number',
2341 'return 123',
2342 'enddef',
2343 'defcompile'], 'E1059:')
2344 delfunc! g:Func
2345
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002346 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002347 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002348 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002349 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002350 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002351 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002352
Bram Moolenaar62aec932022-01-29 21:45:34 +00002353 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002354 'vim9script',
2355 'def FuncB()',
2356 ' return 123',
2357 'enddef',
2358 'def FuncA()',
2359 ' FuncB()',
2360 'enddef',
2361 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002362enddef
2363
2364def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002365 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002366 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2367 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2368 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2369 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2370 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002371enddef
2372
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002373def Test_white_space_before_comma()
2374 var lines =<< trim END
2375 vim9script
2376 def Func(a: number , b: number)
2377 enddef
2378 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002379 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002380 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002381enddef
2382
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002383def Test_white_space_after_comma()
2384 var lines =<< trim END
2385 vim9script
2386 def Func(a: number,b: number)
2387 enddef
2388 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002389 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002390
2391 # OK in legacy function
2392 lines =<< trim END
2393 vim9script
2394 func Func(a,b)
2395 endfunc
2396 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002397 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002398enddef
2399
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002400def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002401 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002402 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002403 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002404 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002405 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002406 enddef
2407 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002408 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002409
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002410 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002411 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002412 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002413
Bram Moolenaar67979662020-06-20 22:50:47 +02002414 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002415 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002416 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002417
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002418 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002419 def ListFunc(arg: list<number>)
2420 listvar = arg
2421 enddef
2422 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002423 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002424
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002425 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002426 def DictFunc(arg: dict<number>)
2427 dictvar = arg
2428 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002429 {a: 1, b: 2}->DictFunc()
2430 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002431 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002432 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002433 enddef
2434 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002435 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002436
Bram Moolenaare0de1712020-12-02 17:36:54 +01002437 {a: 3, b: 4}->DictFunc()
2438 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002439
2440 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002441 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002442 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002443 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002444
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002445 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002446 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002447 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002448 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002449 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002450 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002451
2452 def UseString()
2453 'xyork'->MyFunc()
2454 enddef
2455 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002456 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002457
Bram Moolenaar10409562020-07-29 20:00:38 +02002458 def UseString2()
2459 "knife"->MyFunc()
2460 enddef
2461 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002462 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002463
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002464 # prepending a colon makes it a mark
2465 new
2466 setline(1, ['aaa', 'bbb', 'ccc'])
2467 normal! 3Gmt1G
2468 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002469 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002470 bwipe!
2471
Bram Moolenaare6b53242020-07-01 17:28:33 +02002472 MyFunc(
2473 'continued'
2474 )
2475 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002476 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002477 )
2478
2479 call MyFunc(
2480 'more'
2481 ..
2482 'lines'
2483 )
2484 assert_equal(
2485 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002486 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002487 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002488 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002489 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002490enddef
2491
2492def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002493 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002494 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002495 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002496 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002497 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002498 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002499 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002500 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002501 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002502enddef
2503
Bram Moolenaar65b95452020-07-19 14:03:09 +02002504def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002505 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002506 vim9script
2507 def MyFunc(arg: string)
2508 echo arg
2509 enddef
2510 MyFunc(1234)
2511 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002512 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002513enddef
2514
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002515def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002516 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002517 vim9script
2518 const var = ''
2519 def MyFunc(arg: string)
2520 var = 'asdf'
2521 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002522 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002523 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002524 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002525 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002526
2527 lines =<< trim END
2528 const g:Aconst = 77
2529 def Change()
2530 # comment
2531 g:Aconst = 99
2532 enddef
2533 call Change()
2534 unlet g:Aconst
2535 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002536 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002537enddef
2538
2539" Test that inside :function a Python function can be defined, :def is not
2540" recognized.
2541func Test_function_python()
2542 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002543 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002544 execute py "<< EOF"
2545def do_something():
2546 return 1
2547EOF
2548endfunc
2549
2550def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002551 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002552 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002553 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002554 echo 'hello'
2555 enddef
2556
2557 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002558 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002559 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002560 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002561
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002562 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002563 CallGoneSoon()
2564 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002565 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002566 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2567 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002568enddef
2569
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002570func Test_free_dict_while_in_funcstack()
2571 " relies on the sleep command
2572 CheckUnix
2573 call Run_Test_free_dict_while_in_funcstack()
2574endfunc
2575
2576def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002577 # this was freeing the TermRun() default argument dictionary while it was
2578 # still referenced in a funcstack_T
2579 var lines =<< trim END
2580 vim9script
2581
2582 &updatetime = 400
2583 def TermRun(_ = {})
2584 def Post()
2585 enddef
2586 def Exec()
2587 term_start('sleep 1', {
2588 term_finish: 'close',
2589 exit_cb: (_, _) => Post(),
2590 })
2591 enddef
2592 Exec()
2593 enddef
2594 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2595 timer_start(100, (_) => feedkeys("\<F4>"))
2596 timer_start(1000, (_) => feedkeys("\<F4>"))
2597 sleep 1500m
2598 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002599 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002600 nunmap <F4>
2601 set updatetime&
2602enddef
2603
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002604def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002605 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002606 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002607 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002608 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002609 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002610 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002611 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002612 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002613 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002614
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002615 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002616 g:Func1()->assert_equal('Func1')
2617 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002618
2619 delfunc! Func0
2620 delfunc! Func1
2621 delfunc! Func2
2622enddef
2623
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002624def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002625 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002626 vim9script
2627 func Func(arg)
2628 echo a:arg
2629 endfunc
2630 Func('text')
2631 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002632 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002633 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002634enddef
2635
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002636let s:funcResult = 0
2637
2638def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002639 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002640enddef
2641
2642def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002643 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002644 return 1234
2645enddef
2646
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002647def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002648 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002649 return 'text'
2650enddef
2651
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002652def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002653 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002654enddef
2655
2656def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002657 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002658 return arg
2659enddef
2660
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002661def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002662 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002663enddef
2664
Bram Moolenaar62aec932022-01-29 21:45:34 +00002665def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002666 return arg
2667enddef
2668
Bram Moolenaar62aec932022-01-29 21:45:34 +00002669def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002670 return arg
2671enddef
2672
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002673def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002674 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002675 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002676 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002677 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002678 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002679
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002680 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002681 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002682 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002683 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002684 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002685
Bram Moolenaar53900992020-08-22 19:02:02 +02002686 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002687 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002688 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002689 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002690
Bram Moolenaar53900992020-08-22 19:02:02 +02002691 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002692 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002693 Ref2()->assert_equal(1234)
2694 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002695
Bram Moolenaar53900992020-08-22 19:02:02 +02002696 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002697 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002698 Ref2(13)->assert_equal(13)
2699 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002700enddef
2701
Bram Moolenaar9978d472020-07-05 16:01:56 +02002702def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002703 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002704 for n in repeat([1], 3)
2705 res += n
2706 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002707 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002708
2709 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002710 for n in repeat(0z01, 3)->blob2list()
2711 res += n
2712 endfor
2713 res->assert_equal(3)
2714
2715 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002716 for n in add([1, 2], 3)
2717 res += n
2718 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002719 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002720enddef
2721
Bram Moolenaar846178a2020-07-05 17:04:13 +02002722def Test_argv_return_type()
2723 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002724 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002725 for name in argv()
2726 res ..= name
2727 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002728 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002729enddef
2730
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002731def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002732 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002733 RefVoid = g:FuncNoArgNoRet
2734 RefVoid = g:FuncOneArgNoRet
2735 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 +00002736 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 +02002737
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002738 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002739 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002740 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002741 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2742 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 +02002743
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002744 var RefAnyNoArgs: func: any = RefAny
2745
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002746 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002747 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002748 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002749 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 +00002750 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 +02002751
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002752 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002753 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002754 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002755 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2756 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 +02002757enddef
2758
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002759def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002760 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002761
Bram Moolenaar62aec932022-01-29 21:45:34 +00002762 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2763 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002764 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 +00002765 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2766 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
2767 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 +02002768
Bram Moolenaar62aec932022-01-29 21:45:34 +00002769 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2770 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2771 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:')
2772 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002773enddef
2774
Bram Moolenaar89228602020-04-05 22:14:54 +02002775def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002776 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002777 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002778 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002779
2780 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002781 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002782
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002783 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002784 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002785 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002786
Bram Moolenaar62aec932022-01-29 21:45:34 +00002787 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002788enddef
2789
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002790def Test_func_common_type()
2791 def FuncOne(n: number): number
2792 return n
2793 enddef
2794 def FuncTwo(s: string): number
2795 return len(s)
2796 enddef
2797 def FuncThree(n: number, s: string): number
2798 return n + len(s)
2799 enddef
2800 var list = [FuncOne, FuncTwo, FuncThree]
2801 assert_equal(8, list[0](8))
2802 assert_equal(4, list[1]('word'))
2803 assert_equal(7, list[2](3, 'word'))
2804enddef
2805
Bram Moolenaar62aec932022-01-29 21:45:34 +00002806def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002807 arg1: string,
2808 arg2 = 1234,
2809 ...rest: list<string>
2810 ): string
2811 return arg1 .. arg2 .. join(rest, '-')
2812enddef
2813
Bram Moolenaar2c330432020-04-13 14:41:35 +02002814def MultiLineComment(
2815 arg1: string, # comment
2816 arg2 = 1234, # comment
2817 ...rest: list<string> # comment
2818 ): string # comment
2819 return arg1 .. arg2 .. join(rest, '-')
2820enddef
2821
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002822def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002823 MultiLine('text')->assert_equal('text1234')
2824 MultiLine('text', 777)->assert_equal('text777')
2825 MultiLine('text', 777, 'one')->assert_equal('text777one')
2826 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002827enddef
2828
Bram Moolenaar23e03252020-04-12 22:22:31 +02002829func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002830 call s:MultiLine('text')->assert_equal('text1234')
2831 call s:MultiLine('text', 777)->assert_equal('text777')
2832 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2833 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002834endfunc
2835
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002836
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002837" When using CheckScriptFailure() for the below test, E1010 is generated instead
2838" of E1056.
2839func Test_E1056_1059()
2840 let caught_1056 = 0
2841 try
2842 def F():
2843 return 1
2844 enddef
2845 catch /E1056:/
2846 let caught_1056 = 1
2847 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002848 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002849
2850 let caught_1059 = 0
2851 try
2852 def F5(items : list)
2853 echo 'a'
2854 enddef
2855 catch /E1059:/
2856 let caught_1059 = 1
2857 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002858 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002859endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002860
Bram Moolenaar015f4262020-05-05 21:25:22 +02002861func DelMe()
2862 echo 'DelMe'
2863endfunc
2864
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002865def Test_error_reporting()
2866 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002867 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002868 " comment
2869 def Func()
2870 # comment
2871 # comment
2872 invalid
2873 enddef
2874 defcompile
2875 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002876 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002877 try
2878 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002879 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002880 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002881 v:exception->assert_match('Invalid command: invalid')
2882 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002883 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002884 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002885
2886 # comment lines after the start of the function
2887 lines =<< trim END
2888 " comment
2889 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002890 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002891 # comment
2892 # comment
2893 invalid
2894 enddef
2895 defcompile
2896 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002897 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002898 try
2899 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002900 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002901 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002902 v:exception->assert_match('Invalid command: invalid')
2903 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002904 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002905 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002906
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002907 lines =<< trim END
2908 vim9script
2909 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002910 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002911 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002912 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002913 enddef
2914 defcompile
2915 Func()
2916 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002917 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002918 try
2919 source Xdef
2920 assert_report('should have failed')
2921 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002922 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002923 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002924 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002925enddef
2926
Bram Moolenaar015f4262020-05-05 21:25:22 +02002927def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002928 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002929 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002930 'delfunc g:DelMe',
2931 'echo RefMe()'], 'E117:')
2932enddef
2933
2934def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002935 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002936 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002937 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002938enddef
2939
Bram Moolenaar62aec932022-01-29 21:45:34 +00002940def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002941 return Ref('more')
2942enddef
2943
2944def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002945 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002946 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002947enddef
2948
Bram Moolenaar62aec932022-01-29 21:45:34 +00002949def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002950 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002951 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002952enddef
2953
2954def Test_closure_ref_after_return()
2955 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002956 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002957 unlet g:Ref
2958enddef
2959
Bram Moolenaar62aec932022-01-29 21:45:34 +00002960def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002961 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002962 g:Extend = (s) => local->add(s)
2963 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002964enddef
2965
2966def Test_closure_two_refs()
2967 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002968 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002969 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002970 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002971 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002972 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002973
2974 unlet g:Extend
2975 unlet g:Read
2976enddef
2977
Bram Moolenaar62aec932022-01-29 21:45:34 +00002978def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002979 return join(Ref(), ' ')
2980enddef
2981
Bram Moolenaar62aec932022-01-29 21:45:34 +00002982def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002983 Ref(add)
2984enddef
2985
2986def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002987 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002988 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002989 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002990 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002991 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002992 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002993
2994 unlet g:Extend
2995 unlet g:Read
2996enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002997
Bram Moolenaar62aec932022-01-29 21:45:34 +00002998def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002999 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003000 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003001enddef
3002
Bram Moolenaar62aec932022-01-29 21:45:34 +00003003def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003004 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003005 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003006enddef
3007
3008def Test_closure_using_argument()
3009 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003010 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003011
3012 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003013 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003014
3015 unlet g:UseArg
3016 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003017
3018 var lines =<< trim END
3019 vim9script
3020 def Test(Fun: func(number): number): list<number>
3021 return map([1, 2, 3], (_, i) => Fun(i))
3022 enddef
3023 def Inc(nr: number): number
3024 return nr + 2
3025 enddef
3026 assert_equal([3, 4, 5], Test(Inc))
3027 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003028 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003029enddef
3030
Bram Moolenaar62aec932022-01-29 21:45:34 +00003031def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003032 var local = 'a'
3033
3034 def Append(arg: string)
3035 local ..= arg
3036 enddef
3037 g:Append = Append
3038
3039 def Get(): string
3040 return local
3041 enddef
3042 g:Get = Get
3043enddef
3044
3045def Test_closure_append_get()
3046 MakeGetAndAppendRefs()
3047 g:Get()->assert_equal('a')
3048 g:Append('-b')
3049 g:Get()->assert_equal('a-b')
3050 g:Append('-c')
3051 g:Get()->assert_equal('a-b-c')
3052
3053 unlet g:Append
3054 unlet g:Get
3055enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003056
Bram Moolenaar04b12692020-05-04 23:24:44 +02003057def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003058 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003059 def Closure(arg: string): string
3060 return local .. arg
3061 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003062 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003063enddef
3064
Bram Moolenaar62aec932022-01-29 21:45:34 +00003065func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003066 return a:Ref('some')
3067endfunc
3068
3069def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003070 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003071 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003072 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003073enddef
3074
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003075def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003076 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003077 vim9script
3078 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003079 var name = 0
3080 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003081 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003082 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003083 enddef
3084 Func()
3085 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003086 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003087enddef
3088
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003089def Test_nested_closure_used()
3090 var lines =<< trim END
3091 vim9script
3092 def Func()
3093 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003094 var Closure = () => x
3095 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003096 enddef
3097 Func()
3098 assert_equal('hello', g:Myclosure())
3099 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003100 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003101enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003102
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003103def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003104 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003105 vim9script
3106 def FuncA()
3107 FuncB(0)
3108 enddef
3109 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003110 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003111 enddef
3112 FuncA()
3113 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003114 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003115enddef
3116
Bram Moolenaar6de22962022-09-09 21:35:36 +01003117def Run_Test_closure_in_for_loop_fails()
3118 var lines =<< trim END
3119 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003120 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003121 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003122 # time should be enough for startup to finish
3123 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003124 echo n
3125 })
3126 endfor
3127 END
3128 writefile(lines, 'XTest_closure_fails', 'D')
3129
3130 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003131 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003132 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003133
3134 # clean up
3135 g:StopVimInTerminal(buf)
3136enddef
3137
3138func Test_closure_in_for_loop_fails()
3139 CheckScreendump
3140 call Run_Test_closure_in_for_loop_fails()
3141endfunc
3142
Bram Moolenaarf112f302020-12-20 17:47:52 +01003143def Test_global_closure()
3144 var lines =<< trim END
3145 vim9script
3146 def ReverseEveryNLines(n: number, line1: number, line2: number)
3147 var mods = 'sil keepj keepp lockm '
3148 var range = ':' .. line1 .. ',' .. line2
3149 def g:Offset(): number
3150 var offset = (line('.') - line1 + 1) % n
3151 return offset != 0 ? offset : n
3152 enddef
3153 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3154 enddef
3155
3156 new
3157 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3158 ReverseEveryNLines(3, 1, 9)
3159 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003160 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003161 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3162 assert_equal(expected, getline(1, 9))
3163 bwipe!
3164enddef
3165
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003166def Test_global_closure_called_directly()
3167 var lines =<< trim END
3168 vim9script
3169 def Outer()
3170 var x = 1
3171 def g:Inner()
3172 var y = x
3173 x += 1
3174 assert_equal(1, y)
3175 enddef
3176 g:Inner()
3177 assert_equal(2, x)
3178 enddef
3179 Outer()
3180 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003181 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003182 delfunc g:Inner
3183enddef
3184
Bram Moolenaar69c76172021-12-02 16:38:52 +00003185def Test_closure_called_from_legacy()
3186 var lines =<< trim END
3187 vim9script
3188 def Func()
3189 var outer = 'foo'
3190 var F = () => {
3191 outer = 'bar'
3192 }
3193 execute printf('call %s()', string(F))
3194 enddef
3195 Func()
3196 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003197 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003198enddef
3199
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003200def Test_failure_in_called_function()
3201 # this was using the frame index as the return value
3202 var lines =<< trim END
3203 vim9script
3204 au TerminalWinOpen * eval [][0]
3205 def PopupTerm(a: any)
3206 # make sure typvals on stack are string
3207 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3208 FireEvent()
3209 enddef
3210 def FireEvent()
3211 do TerminalWinOpen
3212 enddef
3213 # use try/catch to make eval fail
3214 try
3215 call PopupTerm(0)
3216 catch
3217 endtry
3218 au! TerminalWinOpen
3219 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003220 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003221enddef
3222
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003223def Test_nested_lambda()
3224 var lines =<< trim END
3225 vim9script
3226 def Func()
3227 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003228 var Lambda1 = () => 7
3229 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003230 var res = Lambda2()
3231 assert_equal([7, 4], res)
3232 enddef
3233 Func()
3234 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003235 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003236enddef
3237
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003238def Test_double_nested_lambda()
3239 var lines =<< trim END
3240 vim9script
3241 def F(head: string): func(string): func(string): string
3242 return (sep: string): func(string): string => ((tail: string): string => {
3243 return head .. sep .. tail
3244 })
3245 enddef
3246 assert_equal('hello-there', F('hello')('-')('there'))
3247 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003248 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003249enddef
3250
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003251def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003252 var lines =<< trim END
3253 vim9script
3254 def F(text: string): func(string): func(string): string
3255 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003256 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003257 })
3258 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003259 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003260 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003261 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003262
3263 lines =<< trim END
3264 vim9script
3265 echo range(4)->mapnew((_, v) => {
3266 return range(v) ->mapnew((_, s) => {
3267 return string(s)
3268 })
3269 })
3270 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003271 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003272
3273 lines =<< trim END
3274 vim9script
3275
Bram Moolenaara749a422022-02-12 19:52:25 +00003276 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003277 range(10)
3278 ->mapnew((_, _) => ({
3279 key: range(10)->mapnew((_, _) => {
3280 return ' '
3281 }),
3282 }))
3283 enddef
3284
3285 defcomp
3286 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003287 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003288enddef
3289
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003290def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003291 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003292 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003293enddef
3294
3295def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003296 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003297enddef
3298
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003299def Test_compiling_referenced_func_no_shadow()
3300 var lines =<< trim END
3301 vim9script
3302
3303 def InitializeReply(lspserver: dict<any>)
3304 enddef
3305
3306 def ProcessReply(lspserver: dict<any>)
3307 var lsp_reply_handlers: dict<func> =
3308 { 'initialize': InitializeReply }
3309 lsp_reply_handlers['initialize'](lspserver)
3310 enddef
3311
3312 call ProcessReply({})
3313 END
3314 v9.CheckScriptSuccess(lines)
3315enddef
3316
Bram Moolenaar62aec932022-01-29 21:45:34 +00003317def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003318 var path: string = empty(dir)
3319 \ ? 'empty'
3320 \ : 'full'
3321 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003322enddef
3323
3324def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003325 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003326enddef
3327
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003328def Test_script_var_in_lambda()
3329 var lines =<< trim END
3330 vim9script
3331 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003332 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003333 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003334 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003335enddef
3336
Bram Moolenaar62aec932022-01-29 21:45:34 +00003337def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003338 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003339 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003340 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003341 ->reverse()
3342 return x
3343enddef
3344
3345def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003346 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003347
3348 var lines =<< trim END
3349 vim9script
3350 var res = [{n: 1, m: 2, s: 'xxx'}]
3351 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3352 v.n,
3353 v.m,
3354 substitute(v.s, '.*', 'yyy', '')
3355 ))
3356 assert_equal(['1:2:yyy'], res)
3357 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003358 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003359enddef
3360
Bram Moolenaarb6571982021-01-08 22:24:19 +01003361def Test_list_lambda()
3362 timer_start(1000, (_) => 0)
3363 var body = execute(timer_info()[0].callback
3364 ->string()
3365 ->substitute("('", ' ', '')
3366 ->substitute("')", '', '')
3367 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003368 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003369enddef
3370
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003371def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003372 var lines =<< trim END
3373 vim9script
3374 var flist: list<func>
3375 for i in range(10)
3376 var inloop = i
3377 flist[i] = () => inloop
3378 endfor
3379 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003380 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003381
3382 lines =<< trim END
3383 vim9script
3384 if true
3385 var outloop = 5
3386 var flist: list<func>
3387 for i in range(10)
3388 flist[i] = () => outloop
3389 endfor
3390 endif
3391 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003392 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003393
3394 lines =<< trim END
3395 vim9script
3396 if true
3397 var outloop = 5
3398 endif
3399 var flist: list<func>
3400 for i in range(10)
3401 flist[i] = () => outloop
3402 endfor
3403 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003404 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003405
3406 lines =<< trim END
3407 vim9script
3408 for i in range(10)
3409 var Ref = () => 0
3410 endfor
3411 assert_equal(0, ((i) => 0)(0))
3412 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003413 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003414enddef
3415
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003416def Test_legacy_lambda()
3417 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003418
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003419 var lines =<< trim END
3420 echo {x -> 'hello ' .. x}('foo')
3421 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003422 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003423
3424 lines =<< trim END
3425 vim9script
3426 def Func()
3427 echo (() => 'no error')()
3428 enddef
3429 legacy call s:Func()
3430 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003431 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003432enddef
3433
Bram Moolenaarce024c32021-06-26 13:00:49 +02003434def Test_legacy()
3435 var lines =<< trim END
3436 vim9script
3437 func g:LegacyFunction()
3438 let g:legacyvar = 1
3439 endfunc
3440 def Testit()
3441 legacy call g:LegacyFunction()
3442 enddef
3443 Testit()
3444 assert_equal(1, g:legacyvar)
3445 unlet g:legacyvar
3446 delfunc g:LegacyFunction
3447 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003448 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003449enddef
3450
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003451def Test_legacy_errors()
3452 for cmd in ['if', 'elseif', 'else', 'endif',
3453 'for', 'endfor', 'continue', 'break',
3454 'while', 'endwhile',
3455 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003456 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003457 endfor
3458enddef
3459
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003460def Test_call_legacy_with_dict()
3461 var lines =<< trim END
3462 vim9script
3463 func Legacy() dict
3464 let g:result = self.value
3465 endfunc
3466 def TestDirect()
3467 var d = {value: 'yes', func: Legacy}
3468 d.func()
3469 enddef
3470 TestDirect()
3471 assert_equal('yes', g:result)
3472 unlet g:result
3473
3474 def TestIndirect()
3475 var d = {value: 'foo', func: Legacy}
3476 var Fi = d.func
3477 Fi()
3478 enddef
3479 TestIndirect()
3480 assert_equal('foo', g:result)
3481 unlet g:result
3482
3483 var d = {value: 'bar', func: Legacy}
3484 d.func()
3485 assert_equal('bar', g:result)
3486 unlet g:result
3487 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003488 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003489enddef
3490
Bram Moolenaar62aec932022-01-29 21:45:34 +00003491def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003492 # closure nested inside another closure using argument
3493 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3494 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3495enddef
3496
3497def Test_nested_closure_using_argument()
3498 assert_equal(['x', 'x2'], DoFilterThis('x'))
3499enddef
3500
Bram Moolenaar0186e582021-01-10 18:33:11 +01003501def Test_triple_nested_closure()
3502 var what = 'x'
3503 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3504 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3505 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3506enddef
3507
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003508func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003509 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003510 call Run_Test_silent_echo()
3511endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003512
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003513def Run_Test_silent_echo()
3514 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003515 vim9script
3516 def EchoNothing()
3517 silent echo ''
3518 enddef
3519 defcompile
3520 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003521 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003522
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003523 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003524 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003525 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003526 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003527
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003528 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003529 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003530enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003531
Bram Moolenaar171fb922020-10-28 16:54:47 +01003532def SilentlyError()
3533 execute('silent! invalid')
3534 g:did_it = 'yes'
3535enddef
3536
Bram Moolenaar62aec932022-01-29 21:45:34 +00003537func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003538 silent! invalid
3539endfunc
3540
3541def SilentlyUserError()
3542 UserError()
3543 g:did_it = 'yes'
3544enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003545
3546" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003547func Test_ignore_silent_error()
3548 let g:did_it = 'no'
3549 call SilentlyError()
3550 call assert_equal('yes', g:did_it)
3551
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003552 let g:did_it = 'no'
3553 call SilentlyUserError()
3554 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003555
3556 unlet g:did_it
3557endfunc
3558
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003559def Test_ignore_silent_error_in_filter()
3560 var lines =<< trim END
3561 vim9script
3562 def Filter(winid: number, key: string): bool
3563 if key == 'o'
3564 silent! eval [][0]
3565 return true
3566 endif
3567 return popup_filter_menu(winid, key)
3568 enddef
3569
Bram Moolenaare0de1712020-12-02 17:36:54 +01003570 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003571 feedkeys("o\r", 'xnt')
3572 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003573 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003574enddef
3575
Bram Moolenaar62aec932022-01-29 21:45:34 +00003576def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003577 if n < 2
3578 return n
3579 else
3580 return Fibonacci(n - 1) + Fibonacci(n - 2)
3581 endif
3582enddef
3583
Bram Moolenaar985116a2020-07-12 17:31:09 +02003584def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003585 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003586enddef
3587
Bram Moolenaar62aec932022-01-29 21:45:34 +00003588def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003589 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003590 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003591 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003592 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003593 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003594enddef
3595
3596def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003597 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003598 writefile(['111'], 'XclosureDir/file1')
3599 writefile(['222'], 'XclosureDir/file2')
3600 writefile(['333'], 'XclosureDir/tdir/file3')
3601
Bram Moolenaare0de1712020-12-02 17:36:54 +01003602 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003603enddef
3604
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003605def Test_invalid_function_name()
3606 var lines =<< trim END
3607 vim9script
3608 def s: list<string>
3609 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003610 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003611
3612 lines =<< trim END
3613 vim9script
3614 def g: list<string>
3615 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003616 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003617
3618 lines =<< trim END
3619 vim9script
3620 def <SID>: list<string>
3621 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003622 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003623
3624 lines =<< trim END
3625 vim9script
3626 def F list<string>
3627 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003628 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003629enddef
3630
Bram Moolenaara90afb92020-07-15 22:38:56 +02003631def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003632 var lines =<< trim END
3633 var Xsetlist: func
3634 Xsetlist = function('setloclist', [0])
3635 Xsetlist([], ' ', {title: 'test'})
3636 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003637
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003638 Xsetlist = function('setloclist', [0, [], ' '])
3639 Xsetlist({title: 'test'})
3640 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003641
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003642 Xsetlist = function('setqflist')
3643 Xsetlist([], ' ', {title: 'test'})
3644 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003645
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003646 Xsetlist = function('setqflist', [[], ' '])
3647 Xsetlist({title: 'test'})
3648 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003649
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003650 var Len: func: number = function('len', ['word'])
3651 assert_equal(4, Len())
3652
3653 var RepeatFunc = function('repeat', ['o'])
3654 assert_equal('ooooo', RepeatFunc(5))
3655 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003656 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003657
3658 lines =<< trim END
3659 vim9script
3660 def Foo(Parser: any)
3661 enddef
3662 var Expr: func(dict<any>): dict<any>
3663 const Call = Foo(Expr)
3664 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003665 v9.CheckScriptFailure(lines, 'E1031:')
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02003666
3667 # Test for calling a partial that takes a single argument.
3668 # This used to produce a "E340: Internal error" message.
3669 lines =<< trim END
3670 def Foo(n: number): number
3671 return n * 2
3672 enddef
3673 var Fn = function(Foo, [10])
3674 assert_equal(20, Fn())
3675 END
3676 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara90afb92020-07-15 22:38:56 +02003677enddef
3678
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003679def Test_partial_double_nested()
3680 var idx = 123
3681 var Get = () => idx
3682 var Ref = function(Get, [])
3683 var RefRef = function(Ref, [])
3684 assert_equal(123, RefRef())
3685enddef
3686
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003687def Test_partial_null_function()
3688 var lines =<< trim END
3689 var d: dict<func> = {f: null_function}
3690 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003691 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003692 END
3693 v9.CheckDefAndScriptSuccess(lines)
3694enddef
3695
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003696def Test_cmd_modifier()
3697 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003698 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003699enddef
3700
3701def Test_restore_modifiers()
3702 # check that when compiling a :def function command modifiers are not messed
3703 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003704 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003705 vim9script
3706 set eventignore=
3707 autocmd QuickFixCmdPost * copen
3708 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003709 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003710 enddef
3711 func Func()
3712 noautocmd call s:AutocmdsDisabled()
3713 let g:ei_after = &eventignore
3714 endfunc
3715 Func()
3716 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003717 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003718 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003719enddef
3720
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003721def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003722 eval 1 + 2
3723 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003724 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003725 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003726enddef
3727
3728def StackBot()
3729 # throw an error
3730 eval [][0]
3731enddef
3732
3733def Test_callstack_def()
3734 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003735 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003736 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003737 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003738 endtry
3739enddef
3740
Bram Moolenaare8211a32020-10-09 22:04:29 +02003741" Re-using spot for variable used in block
3742def Test_block_scoped_var()
3743 var lines =<< trim END
3744 vim9script
3745 def Func()
3746 var x = ['a', 'b', 'c']
3747 if 1
3748 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003749 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003750 endif
3751 var z = x
3752 assert_equal(['x', 'x', 'x'], z)
3753 enddef
3754 Func()
3755 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003756 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003757enddef
3758
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003759def Test_reset_did_emsg()
3760 var lines =<< trim END
3761 @s = 'blah'
3762 au BufWinLeave * #
3763 def Func()
3764 var winid = popup_create('popup', {})
3765 exe '*s'
3766 popup_close(winid)
3767 enddef
3768 Func()
3769 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003770 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003771 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003772enddef
3773
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003774def Test_did_emsg_reset()
3775 # executing an autocommand resets did_emsg, this should not result in a
3776 # builtin function considered failing
3777 var lines =<< trim END
3778 vim9script
3779 au BufWinLeave * #
3780 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003781 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003782 eval [][0]
3783 enddef
3784 nno <F3> <cmd>call <sid>Func()<cr>
3785 feedkeys("\<F3>\e", 'xt')
3786 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003787 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003788 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003789
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003790 nunmap <F3>
3791 au! BufWinLeave
3792enddef
3793
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003794def Test_abort_with_silent_call()
3795 var lines =<< trim END
3796 vim9script
3797 g:result = 'none'
3798 def Func()
3799 g:result += 3
3800 g:result = 'yes'
3801 enddef
3802 # error is silenced, but function aborts on error
3803 silent! Func()
3804 assert_equal('none', g:result)
3805 unlet g:result
3806 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003807 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003808enddef
3809
Bram Moolenaarf665e972020-12-05 19:17:16 +01003810def Test_continues_with_silent_error()
3811 var lines =<< trim END
3812 vim9script
3813 g:result = 'none'
3814 def Func()
3815 silent! g:result += 3
3816 g:result = 'yes'
3817 enddef
3818 # error is silenced, function does not abort
3819 Func()
3820 assert_equal('yes', g:result)
3821 unlet g:result
3822 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003823 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003824enddef
3825
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003826def Test_abort_even_with_silent()
3827 var lines =<< trim END
3828 vim9script
3829 g:result = 'none'
3830 def Func()
3831 eval {-> ''}() .. '' .. {}['X']
3832 g:result = 'yes'
3833 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003834 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003835 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003836 unlet g:result
3837 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003838 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003839enddef
3840
Bram Moolenaarf665e972020-12-05 19:17:16 +01003841def Test_cmdmod_silent_restored()
3842 var lines =<< trim END
3843 vim9script
3844 def Func()
3845 g:result = 'none'
3846 silent! g:result += 3
3847 g:result = 'none'
3848 g:result += 3
3849 enddef
3850 Func()
3851 END
3852 # can't use CheckScriptFailure, it ignores the :silent!
3853 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003854 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003855 var caught = 'no'
3856 try
3857 exe 'source ' .. fname
3858 catch /E1030:/
3859 caught = 'yes'
3860 assert_match('Func, line 4', v:throwpoint)
3861 endtry
3862 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003863enddef
3864
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003865def Test_cmdmod_silent_nested()
3866 var lines =<< trim END
3867 vim9script
3868 var result = ''
3869
3870 def Error()
3871 result ..= 'Eb'
3872 eval [][0]
3873 result ..= 'Ea'
3874 enddef
3875
3876 def Crash()
3877 result ..= 'Cb'
3878 sil! Error()
3879 result ..= 'Ca'
3880 enddef
3881
3882 Crash()
3883 assert_equal('CbEbEaCa', result)
3884 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003885 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003886enddef
3887
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003888def Test_dict_member_with_silent()
3889 var lines =<< trim END
3890 vim9script
3891 g:result = 'none'
3892 var d: dict<any>
3893 def Func()
3894 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003895 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003896 catch
3897 endtry
3898 enddef
3899 silent! Func()
3900 assert_equal('0', g:result)
3901 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003902 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003903 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003904enddef
3905
Bram Moolenaarf9041332021-01-21 19:41:16 +01003906def Test_skip_cmds_with_silent()
3907 var lines =<< trim END
3908 vim9script
3909
3910 def Func(b: bool)
3911 Crash()
3912 enddef
3913
3914 def Crash()
3915 sil! :/not found/d _
3916 sil! :/not found/put _
3917 enddef
3918
3919 Func(true)
3920 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003921 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003922enddef
3923
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003924def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003925 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003926 def g:Opfunc(_: any): string
3927 setline(1, 'ASDF')
3928 return ''
3929 enddef
3930 new
3931 setline(1, 'asdf')
3932 feedkeys("\<F3>$", 'x')
3933 assert_equal('ASDF', getline(1))
3934
3935 bwipe!
3936 nunmap <F3>
3937enddef
3938
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003939func Test_opfunc_error()
3940 CheckScreendump
3941 call Run_Test_opfunc_error()
3942endfunc
3943
3944def Run_Test_opfunc_error()
3945 # test that the error from Opfunc() is displayed right away
3946 var lines =<< trim END
3947 vim9script
3948
3949 def Opfunc(type: string)
3950 try
3951 eval [][0]
3952 catch /nothing/ # error not caught
3953 endtry
3954 enddef
3955 &operatorfunc = Opfunc
3956 nnoremap <expr> l <SID>L()
3957 def L(): string
3958 return 'l'
3959 enddef
3960 'x'->repeat(10)->setline(1)
3961 feedkeys('g@l', 'n')
3962 feedkeys('llll')
3963 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003964 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003965
Bram Moolenaar62aec932022-01-29 21:45:34 +00003966 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3967 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003968 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003969
3970 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003971 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003972enddef
3973
Bram Moolenaar077a4232020-12-22 18:33:27 +01003974" this was crashing on exit
3975def Test_nested_lambda_in_closure()
3976 var lines =<< trim END
3977 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003978 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003979 def Outer()
3980 def g:Inner()
3981 echo map([1, 2, 3], {_, v -> v + 1})
3982 enddef
3983 g:Inner()
3984 enddef
3985 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003986 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003987 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003988 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003989 return
3990 endif
3991 assert_equal(['Done'], readfile('XnestedDone'))
3992 delete('XnestedDone')
3993enddef
3994
Bram Moolenaar92368aa2022-02-07 17:50:39 +00003995def Test_nested_closure_funcref()
3996 var lines =<< trim END
3997 vim9script
3998 def Func()
3999 var n: number
4000 def Nested()
4001 ++n
4002 enddef
4003 Nested()
4004 g:result_one = n
4005 var Ref = function(Nested)
4006 Ref()
4007 g:result_two = n
4008 enddef
4009 Func()
4010 END
4011 v9.CheckScriptSuccess(lines)
4012 assert_equal(1, g:result_one)
4013 assert_equal(2, g:result_two)
4014 unlet g:result_one g:result_two
4015enddef
4016
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004017def Test_nested_closure_in_dict()
4018 var lines =<< trim END
4019 vim9script
4020 def Func(): dict<any>
4021 var n: number
4022 def Inc(): number
4023 ++n
4024 return n
4025 enddef
4026 return {inc: function(Inc)}
4027 enddef
4028 disas Func
4029 var d = Func()
4030 assert_equal(1, d.inc())
4031 assert_equal(2, d.inc())
4032 END
4033 v9.CheckScriptSuccess(lines)
4034enddef
4035
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004036def Test_script_local_other_script()
4037 var lines =<< trim END
4038 function LegacyJob()
4039 let FuncRef = function('s:close_cb')
4040 endfunction
4041 function s:close_cb(...)
4042 endfunction
4043 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004044 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004045 source Xlegacy.vim
4046 g:LegacyJob()
4047 g:LegacyJob()
4048 g:LegacyJob()
4049
4050 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004051enddef
4052
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004053def Test_check_func_arg_types()
4054 var lines =<< trim END
4055 vim9script
4056 def F1(x: string): string
4057 return x
4058 enddef
4059
4060 def F2(x: number): number
4061 return x + 1
4062 enddef
4063
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004064 def G(Fg: func): dict<func>
4065 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004066 enddef
4067
4068 def H(d: dict<func>): string
4069 return d.f('a')
4070 enddef
4071 END
4072
Bram Moolenaar62aec932022-01-29 21:45:34 +00004073 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4074 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004075
4076 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004077enddef
4078
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004079def Test_call_func_with_null()
4080 var lines =<< trim END
4081 def Fstring(v: string)
4082 assert_equal(null_string, v)
4083 enddef
4084 Fstring(null_string)
4085 def Fblob(v: blob)
4086 assert_equal(null_blob, v)
4087 enddef
4088 Fblob(null_blob)
4089 def Flist(v: list<number>)
4090 assert_equal(null_list, v)
4091 enddef
4092 Flist(null_list)
4093 def Fdict(v: dict<number>)
4094 assert_equal(null_dict, v)
4095 enddef
4096 Fdict(null_dict)
4097 def Ffunc(Fv: func(number): number)
4098 assert_equal(null_function, Fv)
4099 enddef
4100 Ffunc(null_function)
4101 if has('channel')
4102 def Fchannel(v: channel)
4103 assert_equal(null_channel, v)
4104 enddef
4105 Fchannel(null_channel)
4106 def Fjob(v: job)
4107 assert_equal(null_job, v)
4108 enddef
4109 Fjob(null_job)
4110 endif
4111 END
4112 v9.CheckDefAndScriptSuccess(lines)
4113enddef
4114
4115def Test_null_default_argument()
4116 var lines =<< trim END
4117 def Fstring(v: string = null_string)
4118 assert_equal(null_string, v)
4119 enddef
4120 Fstring()
4121 def Fblob(v: blob = null_blob)
4122 assert_equal(null_blob, v)
4123 enddef
4124 Fblob()
4125 def Flist(v: list<number> = null_list)
4126 assert_equal(null_list, v)
4127 enddef
4128 Flist()
4129 def Fdict(v: dict<number> = null_dict)
4130 assert_equal(null_dict, v)
4131 enddef
4132 Fdict()
4133 def Ffunc(Fv: func(number): number = null_function)
4134 assert_equal(null_function, Fv)
4135 enddef
4136 Ffunc()
4137 if has('channel')
4138 def Fchannel(v: channel = null_channel)
4139 assert_equal(null_channel, v)
4140 enddef
4141 Fchannel()
4142 def Fjob(v: job = null_job)
4143 assert_equal(null_job, v)
4144 enddef
4145 Fjob()
4146 endif
4147 END
4148 v9.CheckDefAndScriptSuccess(lines)
4149enddef
4150
4151def Test_null_return()
4152 var lines =<< trim END
4153 def Fstring(): string
4154 return null_string
4155 enddef
4156 assert_equal(null_string, Fstring())
4157 def Fblob(): blob
4158 return null_blob
4159 enddef
4160 assert_equal(null_blob, Fblob())
4161 def Flist(): list<number>
4162 return null_list
4163 enddef
4164 assert_equal(null_list, Flist())
4165 def Fdict(): dict<number>
4166 return null_dict
4167 enddef
4168 assert_equal(null_dict, Fdict())
4169 def Ffunc(): func(number): number
4170 return null_function
4171 enddef
4172 assert_equal(null_function, Ffunc())
4173 if has('channel')
4174 def Fchannel(): channel
4175 return null_channel
4176 enddef
4177 assert_equal(null_channel, Fchannel())
4178 def Fjob(): job
4179 return null_job
4180 enddef
4181 assert_equal(null_job, Fjob())
4182 endif
4183 END
4184 v9.CheckDefAndScriptSuccess(lines)
4185enddef
4186
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004187def Test_list_any_type_checked()
4188 var lines =<< trim END
4189 vim9script
4190 def Foo()
4191 --decl--
4192 Bar(l)
4193 enddef
4194 def Bar(ll: list<dict<any>>)
4195 enddef
4196 Foo()
4197 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004198 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004199 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004200 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004201 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004202 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004203
4204 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004205 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004206enddef
4207
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004208def Test_compile_error()
4209 var lines =<< trim END
4210 def g:Broken()
4211 echo 'a' + {}
4212 enddef
4213 call g:Broken()
4214 END
4215 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004216 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004217
4218 # Second call won't try compiling again
4219 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004220 delfunc g:Broken
4221
4222 # No error when compiling with :silent!
4223 lines =<< trim END
4224 def g:Broken()
4225 echo 'a' + []
4226 enddef
4227 silent! defcompile
4228 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004229 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004230
4231 # Calling the function won't try compiling again
4232 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4233 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004234enddef
4235
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004236def Test_ignored_argument()
4237 var lines =<< trim END
4238 vim9script
4239 def Ignore(_, _): string
4240 return 'yes'
4241 enddef
4242 assert_equal('yes', Ignore(1, 2))
4243
4244 func Ok(_)
4245 return a:_
4246 endfunc
4247 assert_equal('ok', Ok('ok'))
4248
4249 func Oktoo()
4250 let _ = 'too'
4251 return _
4252 endfunc
4253 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004254
4255 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004256 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004257 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004258
4259 lines =<< trim END
4260 def Ignore(_: string): string
4261 return _
4262 enddef
4263 defcompile
4264 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004265 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004266
4267 lines =<< trim END
4268 var _ = 1
4269 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004270 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004271
4272 lines =<< trim END
4273 var x = _
4274 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004275 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004276enddef
4277
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004278def Test_too_many_arguments()
4279 var lines =<< trim END
4280 echo [0, 1, 2]->map(() => 123)
4281 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004282 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004283
4284 lines =<< trim END
4285 echo [0, 1, 2]->map((_) => 123)
4286 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004287 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004288
4289 lines =<< trim END
4290 vim9script
4291 def OneArgument(arg: string)
4292 echo arg
4293 enddef
4294 var Ref = OneArgument
4295 Ref('a', 'b')
4296 END
4297 v9.CheckScriptFailure(lines, 'E118:')
4298enddef
4299
4300def Test_funcref_with_base()
4301 var lines =<< trim END
4302 vim9script
4303 def TwoArguments(str: string, nr: number)
4304 echo str nr
4305 enddef
4306 var Ref = TwoArguments
4307 Ref('a', 12)
4308 'b'->Ref(34)
4309 END
4310 v9.CheckScriptSuccess(lines)
4311
4312 lines =<< trim END
4313 vim9script
4314 def TwoArguments(str: string, nr: number)
4315 echo str nr
4316 enddef
4317 var Ref = TwoArguments
4318 'a'->Ref('b')
4319 END
4320 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4321
4322 lines =<< trim END
4323 vim9script
4324 def TwoArguments(str: string, nr: number)
4325 echo str nr
4326 enddef
4327 var Ref = TwoArguments
4328 123->Ref(456)
4329 END
4330 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4331
4332 lines =<< trim END
4333 vim9script
4334 def TwoArguments(nr: number, str: string)
4335 echo str nr
4336 enddef
4337 var Ref = TwoArguments
4338 123->Ref('b')
4339 def AndNowCompiled()
4340 456->Ref('x')
4341 enddef
4342 AndNowCompiled()
4343 END
4344 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004345enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004346
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004347def Test_closing_brace_at_start_of_line()
4348 var lines =<< trim END
4349 def Func()
4350 enddef
4351 Func(
4352 )
4353 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004354 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004355enddef
4356
Bram Moolenaar62aec932022-01-29 21:45:34 +00004357func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004358 let g:mydict = {}
4359 func g:mydict.afunc()
4360 let g:result = self.key
4361 endfunc
4362endfunc
4363
4364def Test_numbered_function_reference()
4365 CreateMydict()
4366 var output = execute('legacy func g:mydict.afunc')
4367 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4368 execute 'function(' .. funcName .. ', [], {key: 42})()'
4369 # check that the function still exists
4370 assert_equal(output, execute('legacy func g:mydict.afunc'))
4371 unlet g:mydict
4372enddef
4373
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004374def Test_numbered_function_call()
4375 var lines =<< trim END
4376 let s:legacyscript = {}
4377 func s:legacyscript.Helper() abort
4378 return "Success"
4379 endfunc
4380 let g:legacyscript = deepcopy(s:legacyscript)
4381
4382 let g:legacy_result = eval("g:legacyscript.Helper()")
4383 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4384 END
4385 v9.CheckScriptSuccess(lines)
4386 assert_equal('Success', g:legacy_result)
4387 assert_equal('Success', g:vim9_result)
4388
4389 unlet g:legacy_result
4390 unlet g:vim9_result
4391enddef
4392
Bram Moolenaard3a11782022-01-05 16:50:40 +00004393def Test_go_beyond_end_of_cmd()
4394 # this was reading the byte after the end of the line
4395 var lines =<< trim END
4396 def F()
4397 cal
4398 enddef
4399 defcompile
4400 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004401 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004402enddef
4403
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004404" Test for memory allocation failure when defining a new lambda
4405func Test_lambda_allocation_failure()
4406 new
4407 let lines =<< trim END
4408 vim9script
4409 g:Xlambda = (x): number => {
4410 return x + 1
4411 }
4412 END
4413 call setline(1, lines)
4414 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4415 call assert_fails('source', 'E342:')
4416 call assert_false(exists('g:Xlambda'))
4417 bw!
4418endfunc
4419
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004420def Test_lambda_argument_type_check()
4421 var lines =<< trim END
4422 vim9script
4423
4424 def Scan(ll: list<any>): func(func(any))
4425 return (Emit: func(any)) => {
4426 for e in ll
4427 Emit(e)
4428 endfor
4429 }
4430 enddef
4431
4432 def Sum(Cont: func(func(any))): any
4433 var sum = 0.0
4434 Cont((v: float) => { # <== NOTE: the lambda expects a float
4435 sum += v
4436 })
4437 return sum
4438 enddef
4439
Bram Moolenaar47bba532023-01-20 18:49:46 +00004440 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004441 echo Scan(ml)->Sum()
4442 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004443 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004444enddef
4445
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004446def Test_multiple_funcref()
4447 # This was using a NULL pointer
4448 var lines =<< trim END
4449 vim9script
4450 def A(F: func, ...args: list<any>): func
4451 return funcref(F, args)
4452 enddef
4453
4454 def B(F: func): func
4455 return funcref(A, [F])
4456 enddef
4457
4458 def Test(n: number)
4459 enddef
4460
4461 const X = B(Test)
4462 X(1)
4463 END
4464 v9.CheckScriptSuccess(lines)
4465
4466 # slightly different case
4467 lines =<< trim END
4468 vim9script
4469
4470 def A(F: func, ...args: list<any>): any
4471 return call(F, args)
4472 enddef
4473
4474 def B(F: func): func
4475 return funcref(A, [F])
4476 enddef
4477
4478 def Test(n: number)
4479 enddef
4480
4481 const X = B(Test)
4482 X(1)
4483 END
4484 v9.CheckScriptSuccess(lines)
4485enddef
4486
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004487def Test_cexpr_errmsg_line_number()
4488 var lines =<< trim END
4489 vim9script
4490 def Func()
4491 var qfl = {}
4492 cexpr qfl
4493 enddef
4494 Func()
4495 END
4496 v9.CheckScriptFailure(lines, 'E777', 2)
4497enddef
4498
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004499def AddDefer(s: string)
4500 g:deferred->extend([s])
4501enddef
4502
4503def DeferTwo()
4504 g:deferred->extend(['in Two'])
4505 for n in range(3)
4506 defer g:AddDefer('two' .. n)
4507 endfor
4508 g:deferred->extend(['end Two'])
4509enddef
4510
4511def DeferOne()
4512 g:deferred->extend(['in One'])
4513 defer g:AddDefer('one')
4514 g:DeferTwo()
4515 g:deferred->extend(['end One'])
4516
4517 writefile(['text'], 'XdeferFile')
4518 defer delete('XdeferFile')
4519enddef
4520
4521def Test_defer()
4522 g:deferred = []
4523 g:DeferOne()
4524 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4525 unlet g:deferred
4526 assert_equal('', glob('XdeferFile'))
4527enddef
4528
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004529def Test_invalid_redir()
4530 var lines =<< trim END
4531 def Tone()
4532 if 1
4533 redi =>@�0
4534 redi END
4535 endif
4536 enddef
4537 defcompile
4538 END
4539 v9.CheckScriptFailure(lines, 'E354:')
4540 delfunc g:Tone
4541
4542 # this was reading past the end of the line
4543 lines =<< trim END
4544 def Ttwo()
4545 if 0
4546 redi =>@�0
4547 redi END
4548 endif
4549 enddef
4550 defcompile
4551 END
4552 v9.CheckScriptFailure(lines, 'E354:')
4553 delfunc g:Ttwo
4554enddef
4555
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004556func Test_keytyped_in_nested_function()
4557 CheckRunVimInTerminal
4558
4559 call Run_Test_keytyped_in_nested_function()
4560endfunc
4561
4562def Run_Test_keytyped_in_nested_function()
4563 var lines =<< trim END
4564 vim9script
4565 autocmd CmdlineEnter * sample#Init()
4566
4567 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4568 END
4569 writefile(lines, 'Xkeytyped', 'D')
4570
4571 var dir = 'Xrtpdir/autoload'
4572 mkdir(dir, 'pR')
4573
4574 lines =<< trim END
4575 vim9script
4576 export def Init(): void
4577 cnoremap <expr>" <SID>Quote('"')
4578 enddef
4579 def Quote(str: string): string
4580 def InPair(): number
4581 return 0
4582 enddef
4583 return str
4584 enddef
4585 END
4586 writefile(lines, dir .. '/sample.vim')
4587
4588 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4589
4590 term_sendkeys(buf, ':"')
4591 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4592
4593 # clean up
4594 term_sendkeys(buf, "\<Esc>")
4595 g:StopVimInTerminal(buf)
4596enddef
4597
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004598" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004599if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004600 def Test_python3_command()
4601 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004602 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004603 assert_equal('yes', g:done)
4604 unlet g:done
4605 enddef
4606
Bram Moolenaar20677332021-06-06 17:02:53 +02004607 def Test_python3_heredoc()
4608 py3 << trim EOF
4609 import vim
4610 vim.vars['didit'] = 'yes'
4611 EOF
4612 assert_equal('yes', g:didit)
4613
4614 python3 << trim EOF
4615 import vim
4616 vim.vars['didit'] = 'again'
4617 EOF
4618 assert_equal('again', g:didit)
4619 enddef
4620endif
4621
Bram Moolenaar20677332021-06-06 17:02:53 +02004622if has('lua')
4623 def Test_lua_heredoc()
4624 g:d = {}
4625 lua << trim EOF
4626 x = vim.eval('g:d')
4627 x['key'] = 'val'
4628 EOF
4629 assert_equal('val', g:d.key)
4630 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004631
4632 def Test_lua_heredoc_fails()
4633 var lines = [
4634 'vim9script',
4635 'def ExeLua()',
4636 'lua << trim EOLUA',
4637 "x = vim.eval('g:nodict')",
4638 'EOLUA',
4639 'enddef',
4640 'ExeLua()',
4641 ]
4642 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4643 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004644endif
4645
Bram Moolenaard881d152022-05-13 13:50:36 +01004646if has('perl')
4647 def Test_perl_heredoc_nested()
4648 var lines =<< trim END
4649 vim9script
4650 def F(): string
4651 def G(): string
4652 perl << EOF
4653 EOF
4654 return 'done'
4655 enddef
4656 return G()
4657 enddef
4658 assert_equal('done', F())
4659 END
4660 v9.CheckScriptSuccess(lines)
4661 enddef
4662endif
4663
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004664
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004665" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker