blob: 852f3a7edec49b7277bb5141ef7481cfcbeb7875 [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
1998 v9.CheckScriptSuccess(lines)
1999enddef
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:')
Bram Moolenaara90afb92020-07-15 22:38:56 +02003666enddef
3667
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003668def Test_partial_double_nested()
3669 var idx = 123
3670 var Get = () => idx
3671 var Ref = function(Get, [])
3672 var RefRef = function(Ref, [])
3673 assert_equal(123, RefRef())
3674enddef
3675
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003676def Test_partial_null_function()
3677 var lines =<< trim END
3678 var d: dict<func> = {f: null_function}
3679 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003680 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003681 END
3682 v9.CheckDefAndScriptSuccess(lines)
3683enddef
3684
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003685def Test_cmd_modifier()
3686 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003687 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003688enddef
3689
3690def Test_restore_modifiers()
3691 # check that when compiling a :def function command modifiers are not messed
3692 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003693 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003694 vim9script
3695 set eventignore=
3696 autocmd QuickFixCmdPost * copen
3697 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003698 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003699 enddef
3700 func Func()
3701 noautocmd call s:AutocmdsDisabled()
3702 let g:ei_after = &eventignore
3703 endfunc
3704 Func()
3705 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003706 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003707 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003708enddef
3709
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003710def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003711 eval 1 + 2
3712 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003713 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003714 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003715enddef
3716
3717def StackBot()
3718 # throw an error
3719 eval [][0]
3720enddef
3721
3722def Test_callstack_def()
3723 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003724 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003725 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003726 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003727 endtry
3728enddef
3729
Bram Moolenaare8211a32020-10-09 22:04:29 +02003730" Re-using spot for variable used in block
3731def Test_block_scoped_var()
3732 var lines =<< trim END
3733 vim9script
3734 def Func()
3735 var x = ['a', 'b', 'c']
3736 if 1
3737 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003738 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003739 endif
3740 var z = x
3741 assert_equal(['x', 'x', 'x'], z)
3742 enddef
3743 Func()
3744 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003745 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003746enddef
3747
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003748def Test_reset_did_emsg()
3749 var lines =<< trim END
3750 @s = 'blah'
3751 au BufWinLeave * #
3752 def Func()
3753 var winid = popup_create('popup', {})
3754 exe '*s'
3755 popup_close(winid)
3756 enddef
3757 Func()
3758 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003759 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003760 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003761enddef
3762
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003763def Test_did_emsg_reset()
3764 # executing an autocommand resets did_emsg, this should not result in a
3765 # builtin function considered failing
3766 var lines =<< trim END
3767 vim9script
3768 au BufWinLeave * #
3769 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003770 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003771 eval [][0]
3772 enddef
3773 nno <F3> <cmd>call <sid>Func()<cr>
3774 feedkeys("\<F3>\e", 'xt')
3775 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003776 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003777 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003778
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003779 nunmap <F3>
3780 au! BufWinLeave
3781enddef
3782
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003783def Test_abort_with_silent_call()
3784 var lines =<< trim END
3785 vim9script
3786 g:result = 'none'
3787 def Func()
3788 g:result += 3
3789 g:result = 'yes'
3790 enddef
3791 # error is silenced, but function aborts on error
3792 silent! Func()
3793 assert_equal('none', g:result)
3794 unlet g:result
3795 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003796 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003797enddef
3798
Bram Moolenaarf665e972020-12-05 19:17:16 +01003799def Test_continues_with_silent_error()
3800 var lines =<< trim END
3801 vim9script
3802 g:result = 'none'
3803 def Func()
3804 silent! g:result += 3
3805 g:result = 'yes'
3806 enddef
3807 # error is silenced, function does not abort
3808 Func()
3809 assert_equal('yes', g:result)
3810 unlet g:result
3811 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003812 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003813enddef
3814
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003815def Test_abort_even_with_silent()
3816 var lines =<< trim END
3817 vim9script
3818 g:result = 'none'
3819 def Func()
3820 eval {-> ''}() .. '' .. {}['X']
3821 g:result = 'yes'
3822 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003823 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003824 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003825 unlet g:result
3826 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003827 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003828enddef
3829
Bram Moolenaarf665e972020-12-05 19:17:16 +01003830def Test_cmdmod_silent_restored()
3831 var lines =<< trim END
3832 vim9script
3833 def Func()
3834 g:result = 'none'
3835 silent! g:result += 3
3836 g:result = 'none'
3837 g:result += 3
3838 enddef
3839 Func()
3840 END
3841 # can't use CheckScriptFailure, it ignores the :silent!
3842 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003843 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003844 var caught = 'no'
3845 try
3846 exe 'source ' .. fname
3847 catch /E1030:/
3848 caught = 'yes'
3849 assert_match('Func, line 4', v:throwpoint)
3850 endtry
3851 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003852enddef
3853
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003854def Test_cmdmod_silent_nested()
3855 var lines =<< trim END
3856 vim9script
3857 var result = ''
3858
3859 def Error()
3860 result ..= 'Eb'
3861 eval [][0]
3862 result ..= 'Ea'
3863 enddef
3864
3865 def Crash()
3866 result ..= 'Cb'
3867 sil! Error()
3868 result ..= 'Ca'
3869 enddef
3870
3871 Crash()
3872 assert_equal('CbEbEaCa', result)
3873 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003874 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003875enddef
3876
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003877def Test_dict_member_with_silent()
3878 var lines =<< trim END
3879 vim9script
3880 g:result = 'none'
3881 var d: dict<any>
3882 def Func()
3883 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003884 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003885 catch
3886 endtry
3887 enddef
3888 silent! Func()
3889 assert_equal('0', g:result)
3890 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003891 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003892 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003893enddef
3894
Bram Moolenaarf9041332021-01-21 19:41:16 +01003895def Test_skip_cmds_with_silent()
3896 var lines =<< trim END
3897 vim9script
3898
3899 def Func(b: bool)
3900 Crash()
3901 enddef
3902
3903 def Crash()
3904 sil! :/not found/d _
3905 sil! :/not found/put _
3906 enddef
3907
3908 Func(true)
3909 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003910 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003911enddef
3912
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003913def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003914 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003915 def g:Opfunc(_: any): string
3916 setline(1, 'ASDF')
3917 return ''
3918 enddef
3919 new
3920 setline(1, 'asdf')
3921 feedkeys("\<F3>$", 'x')
3922 assert_equal('ASDF', getline(1))
3923
3924 bwipe!
3925 nunmap <F3>
3926enddef
3927
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003928func Test_opfunc_error()
3929 CheckScreendump
3930 call Run_Test_opfunc_error()
3931endfunc
3932
3933def Run_Test_opfunc_error()
3934 # test that the error from Opfunc() is displayed right away
3935 var lines =<< trim END
3936 vim9script
3937
3938 def Opfunc(type: string)
3939 try
3940 eval [][0]
3941 catch /nothing/ # error not caught
3942 endtry
3943 enddef
3944 &operatorfunc = Opfunc
3945 nnoremap <expr> l <SID>L()
3946 def L(): string
3947 return 'l'
3948 enddef
3949 'x'->repeat(10)->setline(1)
3950 feedkeys('g@l', 'n')
3951 feedkeys('llll')
3952 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003953 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003954
Bram Moolenaar62aec932022-01-29 21:45:34 +00003955 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3956 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003957 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003958
3959 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003960 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003961enddef
3962
Bram Moolenaar077a4232020-12-22 18:33:27 +01003963" this was crashing on exit
3964def Test_nested_lambda_in_closure()
3965 var lines =<< trim END
3966 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003967 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003968 def Outer()
3969 def g:Inner()
3970 echo map([1, 2, 3], {_, v -> v + 1})
3971 enddef
3972 g:Inner()
3973 enddef
3974 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003975 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003976 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003977 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003978 return
3979 endif
3980 assert_equal(['Done'], readfile('XnestedDone'))
3981 delete('XnestedDone')
3982enddef
3983
Bram Moolenaar92368aa2022-02-07 17:50:39 +00003984def Test_nested_closure_funcref()
3985 var lines =<< trim END
3986 vim9script
3987 def Func()
3988 var n: number
3989 def Nested()
3990 ++n
3991 enddef
3992 Nested()
3993 g:result_one = n
3994 var Ref = function(Nested)
3995 Ref()
3996 g:result_two = n
3997 enddef
3998 Func()
3999 END
4000 v9.CheckScriptSuccess(lines)
4001 assert_equal(1, g:result_one)
4002 assert_equal(2, g:result_two)
4003 unlet g:result_one g:result_two
4004enddef
4005
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004006def Test_nested_closure_in_dict()
4007 var lines =<< trim END
4008 vim9script
4009 def Func(): dict<any>
4010 var n: number
4011 def Inc(): number
4012 ++n
4013 return n
4014 enddef
4015 return {inc: function(Inc)}
4016 enddef
4017 disas Func
4018 var d = Func()
4019 assert_equal(1, d.inc())
4020 assert_equal(2, d.inc())
4021 END
4022 v9.CheckScriptSuccess(lines)
4023enddef
4024
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004025def Test_script_local_other_script()
4026 var lines =<< trim END
4027 function LegacyJob()
4028 let FuncRef = function('s:close_cb')
4029 endfunction
4030 function s:close_cb(...)
4031 endfunction
4032 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004033 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004034 source Xlegacy.vim
4035 g:LegacyJob()
4036 g:LegacyJob()
4037 g:LegacyJob()
4038
4039 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004040enddef
4041
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004042def Test_check_func_arg_types()
4043 var lines =<< trim END
4044 vim9script
4045 def F1(x: string): string
4046 return x
4047 enddef
4048
4049 def F2(x: number): number
4050 return x + 1
4051 enddef
4052
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004053 def G(Fg: func): dict<func>
4054 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004055 enddef
4056
4057 def H(d: dict<func>): string
4058 return d.f('a')
4059 enddef
4060 END
4061
Bram Moolenaar62aec932022-01-29 21:45:34 +00004062 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4063 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004064
4065 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004066enddef
4067
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004068def Test_call_func_with_null()
4069 var lines =<< trim END
4070 def Fstring(v: string)
4071 assert_equal(null_string, v)
4072 enddef
4073 Fstring(null_string)
4074 def Fblob(v: blob)
4075 assert_equal(null_blob, v)
4076 enddef
4077 Fblob(null_blob)
4078 def Flist(v: list<number>)
4079 assert_equal(null_list, v)
4080 enddef
4081 Flist(null_list)
4082 def Fdict(v: dict<number>)
4083 assert_equal(null_dict, v)
4084 enddef
4085 Fdict(null_dict)
4086 def Ffunc(Fv: func(number): number)
4087 assert_equal(null_function, Fv)
4088 enddef
4089 Ffunc(null_function)
4090 if has('channel')
4091 def Fchannel(v: channel)
4092 assert_equal(null_channel, v)
4093 enddef
4094 Fchannel(null_channel)
4095 def Fjob(v: job)
4096 assert_equal(null_job, v)
4097 enddef
4098 Fjob(null_job)
4099 endif
4100 END
4101 v9.CheckDefAndScriptSuccess(lines)
4102enddef
4103
4104def Test_null_default_argument()
4105 var lines =<< trim END
4106 def Fstring(v: string = null_string)
4107 assert_equal(null_string, v)
4108 enddef
4109 Fstring()
4110 def Fblob(v: blob = null_blob)
4111 assert_equal(null_blob, v)
4112 enddef
4113 Fblob()
4114 def Flist(v: list<number> = null_list)
4115 assert_equal(null_list, v)
4116 enddef
4117 Flist()
4118 def Fdict(v: dict<number> = null_dict)
4119 assert_equal(null_dict, v)
4120 enddef
4121 Fdict()
4122 def Ffunc(Fv: func(number): number = null_function)
4123 assert_equal(null_function, Fv)
4124 enddef
4125 Ffunc()
4126 if has('channel')
4127 def Fchannel(v: channel = null_channel)
4128 assert_equal(null_channel, v)
4129 enddef
4130 Fchannel()
4131 def Fjob(v: job = null_job)
4132 assert_equal(null_job, v)
4133 enddef
4134 Fjob()
4135 endif
4136 END
4137 v9.CheckDefAndScriptSuccess(lines)
4138enddef
4139
4140def Test_null_return()
4141 var lines =<< trim END
4142 def Fstring(): string
4143 return null_string
4144 enddef
4145 assert_equal(null_string, Fstring())
4146 def Fblob(): blob
4147 return null_blob
4148 enddef
4149 assert_equal(null_blob, Fblob())
4150 def Flist(): list<number>
4151 return null_list
4152 enddef
4153 assert_equal(null_list, Flist())
4154 def Fdict(): dict<number>
4155 return null_dict
4156 enddef
4157 assert_equal(null_dict, Fdict())
4158 def Ffunc(): func(number): number
4159 return null_function
4160 enddef
4161 assert_equal(null_function, Ffunc())
4162 if has('channel')
4163 def Fchannel(): channel
4164 return null_channel
4165 enddef
4166 assert_equal(null_channel, Fchannel())
4167 def Fjob(): job
4168 return null_job
4169 enddef
4170 assert_equal(null_job, Fjob())
4171 endif
4172 END
4173 v9.CheckDefAndScriptSuccess(lines)
4174enddef
4175
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004176def Test_list_any_type_checked()
4177 var lines =<< trim END
4178 vim9script
4179 def Foo()
4180 --decl--
4181 Bar(l)
4182 enddef
4183 def Bar(ll: list<dict<any>>)
4184 enddef
4185 Foo()
4186 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004187 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004188 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004189 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004190 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004191 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004192
4193 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004194 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004195enddef
4196
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004197def Test_compile_error()
4198 var lines =<< trim END
4199 def g:Broken()
4200 echo 'a' + {}
4201 enddef
4202 call g:Broken()
4203 END
4204 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004205 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004206
4207 # Second call won't try compiling again
4208 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004209 delfunc g:Broken
4210
4211 # No error when compiling with :silent!
4212 lines =<< trim END
4213 def g:Broken()
4214 echo 'a' + []
4215 enddef
4216 silent! defcompile
4217 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004218 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004219
4220 # Calling the function won't try compiling again
4221 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4222 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004223enddef
4224
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004225def Test_ignored_argument()
4226 var lines =<< trim END
4227 vim9script
4228 def Ignore(_, _): string
4229 return 'yes'
4230 enddef
4231 assert_equal('yes', Ignore(1, 2))
4232
4233 func Ok(_)
4234 return a:_
4235 endfunc
4236 assert_equal('ok', Ok('ok'))
4237
4238 func Oktoo()
4239 let _ = 'too'
4240 return _
4241 endfunc
4242 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004243
4244 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004245 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004246 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004247
4248 lines =<< trim END
4249 def Ignore(_: string): string
4250 return _
4251 enddef
4252 defcompile
4253 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004254 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004255
4256 lines =<< trim END
4257 var _ = 1
4258 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004259 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004260
4261 lines =<< trim END
4262 var x = _
4263 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004264 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004265enddef
4266
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004267def Test_too_many_arguments()
4268 var lines =<< trim END
4269 echo [0, 1, 2]->map(() => 123)
4270 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004271 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004272
4273 lines =<< trim END
4274 echo [0, 1, 2]->map((_) => 123)
4275 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004276 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004277
4278 lines =<< trim END
4279 vim9script
4280 def OneArgument(arg: string)
4281 echo arg
4282 enddef
4283 var Ref = OneArgument
4284 Ref('a', 'b')
4285 END
4286 v9.CheckScriptFailure(lines, 'E118:')
4287enddef
4288
4289def Test_funcref_with_base()
4290 var lines =<< trim END
4291 vim9script
4292 def TwoArguments(str: string, nr: number)
4293 echo str nr
4294 enddef
4295 var Ref = TwoArguments
4296 Ref('a', 12)
4297 'b'->Ref(34)
4298 END
4299 v9.CheckScriptSuccess(lines)
4300
4301 lines =<< trim END
4302 vim9script
4303 def TwoArguments(str: string, nr: number)
4304 echo str nr
4305 enddef
4306 var Ref = TwoArguments
4307 'a'->Ref('b')
4308 END
4309 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4310
4311 lines =<< trim END
4312 vim9script
4313 def TwoArguments(str: string, nr: number)
4314 echo str nr
4315 enddef
4316 var Ref = TwoArguments
4317 123->Ref(456)
4318 END
4319 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4320
4321 lines =<< trim END
4322 vim9script
4323 def TwoArguments(nr: number, str: string)
4324 echo str nr
4325 enddef
4326 var Ref = TwoArguments
4327 123->Ref('b')
4328 def AndNowCompiled()
4329 456->Ref('x')
4330 enddef
4331 AndNowCompiled()
4332 END
4333 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004334enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004335
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004336def Test_closing_brace_at_start_of_line()
4337 var lines =<< trim END
4338 def Func()
4339 enddef
4340 Func(
4341 )
4342 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004343 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004344enddef
4345
Bram Moolenaar62aec932022-01-29 21:45:34 +00004346func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004347 let g:mydict = {}
4348 func g:mydict.afunc()
4349 let g:result = self.key
4350 endfunc
4351endfunc
4352
4353def Test_numbered_function_reference()
4354 CreateMydict()
4355 var output = execute('legacy func g:mydict.afunc')
4356 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4357 execute 'function(' .. funcName .. ', [], {key: 42})()'
4358 # check that the function still exists
4359 assert_equal(output, execute('legacy func g:mydict.afunc'))
4360 unlet g:mydict
4361enddef
4362
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004363def Test_numbered_function_call()
4364 var lines =<< trim END
4365 let s:legacyscript = {}
4366 func s:legacyscript.Helper() abort
4367 return "Success"
4368 endfunc
4369 let g:legacyscript = deepcopy(s:legacyscript)
4370
4371 let g:legacy_result = eval("g:legacyscript.Helper()")
4372 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4373 END
4374 v9.CheckScriptSuccess(lines)
4375 assert_equal('Success', g:legacy_result)
4376 assert_equal('Success', g:vim9_result)
4377
4378 unlet g:legacy_result
4379 unlet g:vim9_result
4380enddef
4381
Bram Moolenaard3a11782022-01-05 16:50:40 +00004382def Test_go_beyond_end_of_cmd()
4383 # this was reading the byte after the end of the line
4384 var lines =<< trim END
4385 def F()
4386 cal
4387 enddef
4388 defcompile
4389 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004390 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004391enddef
4392
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004393" Test for memory allocation failure when defining a new lambda
4394func Test_lambda_allocation_failure()
4395 new
4396 let lines =<< trim END
4397 vim9script
4398 g:Xlambda = (x): number => {
4399 return x + 1
4400 }
4401 END
4402 call setline(1, lines)
4403 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4404 call assert_fails('source', 'E342:')
4405 call assert_false(exists('g:Xlambda'))
4406 bw!
4407endfunc
4408
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004409def Test_lambda_argument_type_check()
4410 var lines =<< trim END
4411 vim9script
4412
4413 def Scan(ll: list<any>): func(func(any))
4414 return (Emit: func(any)) => {
4415 for e in ll
4416 Emit(e)
4417 endfor
4418 }
4419 enddef
4420
4421 def Sum(Cont: func(func(any))): any
4422 var sum = 0.0
4423 Cont((v: float) => { # <== NOTE: the lambda expects a float
4424 sum += v
4425 })
4426 return sum
4427 enddef
4428
Bram Moolenaar47bba532023-01-20 18:49:46 +00004429 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004430 echo Scan(ml)->Sum()
4431 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004432 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004433enddef
4434
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004435def Test_multiple_funcref()
4436 # This was using a NULL pointer
4437 var lines =<< trim END
4438 vim9script
4439 def A(F: func, ...args: list<any>): func
4440 return funcref(F, args)
4441 enddef
4442
4443 def B(F: func): func
4444 return funcref(A, [F])
4445 enddef
4446
4447 def Test(n: number)
4448 enddef
4449
4450 const X = B(Test)
4451 X(1)
4452 END
4453 v9.CheckScriptSuccess(lines)
4454
4455 # slightly different case
4456 lines =<< trim END
4457 vim9script
4458
4459 def A(F: func, ...args: list<any>): any
4460 return call(F, args)
4461 enddef
4462
4463 def B(F: func): func
4464 return funcref(A, [F])
4465 enddef
4466
4467 def Test(n: number)
4468 enddef
4469
4470 const X = B(Test)
4471 X(1)
4472 END
4473 v9.CheckScriptSuccess(lines)
4474enddef
4475
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004476def Test_cexpr_errmsg_line_number()
4477 var lines =<< trim END
4478 vim9script
4479 def Func()
4480 var qfl = {}
4481 cexpr qfl
4482 enddef
4483 Func()
4484 END
4485 v9.CheckScriptFailure(lines, 'E777', 2)
4486enddef
4487
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004488def AddDefer(s: string)
4489 g:deferred->extend([s])
4490enddef
4491
4492def DeferTwo()
4493 g:deferred->extend(['in Two'])
4494 for n in range(3)
4495 defer g:AddDefer('two' .. n)
4496 endfor
4497 g:deferred->extend(['end Two'])
4498enddef
4499
4500def DeferOne()
4501 g:deferred->extend(['in One'])
4502 defer g:AddDefer('one')
4503 g:DeferTwo()
4504 g:deferred->extend(['end One'])
4505
4506 writefile(['text'], 'XdeferFile')
4507 defer delete('XdeferFile')
4508enddef
4509
4510def Test_defer()
4511 g:deferred = []
4512 g:DeferOne()
4513 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4514 unlet g:deferred
4515 assert_equal('', glob('XdeferFile'))
4516enddef
4517
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004518def Test_invalid_redir()
4519 var lines =<< trim END
4520 def Tone()
4521 if 1
4522 redi =>@�0
4523 redi END
4524 endif
4525 enddef
4526 defcompile
4527 END
4528 v9.CheckScriptFailure(lines, 'E354:')
4529 delfunc g:Tone
4530
4531 # this was reading past the end of the line
4532 lines =<< trim END
4533 def Ttwo()
4534 if 0
4535 redi =>@�0
4536 redi END
4537 endif
4538 enddef
4539 defcompile
4540 END
4541 v9.CheckScriptFailure(lines, 'E354:')
4542 delfunc g:Ttwo
4543enddef
4544
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004545func Test_keytyped_in_nested_function()
4546 CheckRunVimInTerminal
4547
4548 call Run_Test_keytyped_in_nested_function()
4549endfunc
4550
4551def Run_Test_keytyped_in_nested_function()
4552 var lines =<< trim END
4553 vim9script
4554 autocmd CmdlineEnter * sample#Init()
4555
4556 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4557 END
4558 writefile(lines, 'Xkeytyped', 'D')
4559
4560 var dir = 'Xrtpdir/autoload'
4561 mkdir(dir, 'pR')
4562
4563 lines =<< trim END
4564 vim9script
4565 export def Init(): void
4566 cnoremap <expr>" <SID>Quote('"')
4567 enddef
4568 def Quote(str: string): string
4569 def InPair(): number
4570 return 0
4571 enddef
4572 return str
4573 enddef
4574 END
4575 writefile(lines, dir .. '/sample.vim')
4576
4577 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4578
4579 term_sendkeys(buf, ':"')
4580 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4581
4582 # clean up
4583 term_sendkeys(buf, "\<Esc>")
4584 g:StopVimInTerminal(buf)
4585enddef
4586
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004587" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004588if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004589 def Test_python3_command()
4590 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004591 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004592 assert_equal('yes', g:done)
4593 unlet g:done
4594 enddef
4595
Bram Moolenaar20677332021-06-06 17:02:53 +02004596 def Test_python3_heredoc()
4597 py3 << trim EOF
4598 import vim
4599 vim.vars['didit'] = 'yes'
4600 EOF
4601 assert_equal('yes', g:didit)
4602
4603 python3 << trim EOF
4604 import vim
4605 vim.vars['didit'] = 'again'
4606 EOF
4607 assert_equal('again', g:didit)
4608 enddef
4609endif
4610
Bram Moolenaar20677332021-06-06 17:02:53 +02004611if has('lua')
4612 def Test_lua_heredoc()
4613 g:d = {}
4614 lua << trim EOF
4615 x = vim.eval('g:d')
4616 x['key'] = 'val'
4617 EOF
4618 assert_equal('val', g:d.key)
4619 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004620
4621 def Test_lua_heredoc_fails()
4622 var lines = [
4623 'vim9script',
4624 'def ExeLua()',
4625 'lua << trim EOLUA',
4626 "x = vim.eval('g:nodict')",
4627 'EOLUA',
4628 'enddef',
4629 'ExeLua()',
4630 ]
4631 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4632 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004633endif
4634
Bram Moolenaard881d152022-05-13 13:50:36 +01004635if has('perl')
4636 def Test_perl_heredoc_nested()
4637 var lines =<< trim END
4638 vim9script
4639 def F(): string
4640 def G(): string
4641 perl << EOF
4642 EOF
4643 return 'done'
4644 enddef
4645 return G()
4646 enddef
4647 assert_equal('done', F())
4648 END
4649 v9.CheckScriptSuccess(lines)
4650 enddef
4651endif
4652
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004653
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004654" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker