blob: 27585a90490095170c27da4064092f6d1c0e86f4 [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
Christian Brabandte4a450a2023-12-08 20:57:38 +0100865 def Func(f=
866 )
867 enddef
868 END
869 v9.CheckScriptFailure(lines, 'E125:', 2)
870
871 lines =<< trim END
Bram Moolenaarcef12702021-01-04 14:09:43 +0100872 def Func(
873 arg: string# comment
874 )
875 enddef
876 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000877 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100878
879 lines =<< trim END
880 def Func(
881 arg: string
882 )# comment
883 enddef
884 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000885 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100886enddef
887
Bram Moolenaar04b12692020-05-04 23:24:44 +0200888def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000889 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200890 return 'nested ' .. arg
891 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000892 NestedDef(':def')->assert_equal('nested :def')
893
894 func NestedFunc(arg)
895 return 'nested ' .. a:arg
896 endfunc
897 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200898
Bram Moolenaar62aec932022-01-29 21:45:34 +0000899 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
900 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200901
Bram Moolenaar62aec932022-01-29 21:45:34 +0000902 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
903 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200904
Bram Moolenaar54021752020-12-06 18:50:36 +0100905 var lines =<< trim END
906 def Outer()
907 def Inner()
908 # comment
909 enddef
910 def Inner()
911 enddef
912 enddef
913 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000914 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100915
916 lines =<< trim END
917 def Outer()
918 def Inner()
919 # comment
920 enddef
921 def! Inner()
922 enddef
923 enddef
924 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000925 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100926
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000927 lines =<< trim END
928 vim9script
929 def Outer()
930 def Inner()
931 g:result = 'ok'
932 enddef
933 Inner()
934 enddef
935 Outer()
936 Inner()
937 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000938 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000939 assert_equal('ok', g:result)
940 unlet g:result
941
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000942 lines =<< trim END
943 vim9script
944 def Outer()
945 def _Inner()
946 echo 'bad'
947 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000948 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000949 enddef
950 defcompile
951 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000952 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000953
954 lines =<< trim END
955 vim9script
956 def Outer()
957 def g:inner()
958 echo 'bad'
959 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000960 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000961 enddef
962 defcompile
963 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000964 v9.CheckScriptFailure(lines, 'E1267:')
965
966 lines =<< trim END
967 vim9script
968 def g:_Func()
969 echo 'bad'
970 enddef
971 END
972 v9.CheckScriptFailure(lines, 'E1267:')
973
974 lines =<< trim END
975 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +0000976 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +0000977 echo 'bad'
978 enddef
979 END
980 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000981
Bram Moolenaar54021752020-12-06 18:50:36 +0100982 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +0100983 lines =<< trim END
984 vim9script
985 var thecount = 0
986 if true
987 def Test(): number
988 def TheFunc(): number
989 thecount += 1
990 return thecount
991 enddef
992 return TheFunc()
993 enddef
994 endif
995 defcompile
996 assert_equal(1, Test())
997 assert_equal(2, Test())
998 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000999 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001000
1001 # also works when "thecount" is inside the "if" block
1002 lines =<< trim END
1003 vim9script
1004 if true
1005 var thecount = 0
1006 def Test(): number
1007 def TheFunc(): number
1008 thecount += 1
1009 return thecount
1010 enddef
1011 return TheFunc()
1012 enddef
1013 endif
1014 defcompile
1015 assert_equal(1, Test())
1016 assert_equal(2, Test())
1017 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001018 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001019
Bram Moolenaara915fa02022-03-23 11:29:15 +00001020 # nested function with recursive call
1021 lines =<< trim END
1022 vim9script
1023
1024 def MyFunc(): number
1025 def Fib(n: number): number
1026 if n < 2
1027 return 1
1028 endif
1029 return Fib(n - 2) + Fib(n - 1)
1030 enddef
1031
1032 return Fib(5)
1033 enddef
1034
1035 assert_equal(8, MyFunc())
1036 END
1037 v9.CheckScriptSuccess(lines)
1038
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001039 lines =<< trim END
1040 vim9script
1041 def Outer()
1042 def Inner()
1043 echo 'hello'
1044 enddef burp
1045 enddef
1046 defcompile
1047 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001048 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001049enddef
1050
Bram Moolenaar1889f492022-08-16 19:34:44 +01001051def Test_nested_function_fails()
1052 var lines =<< trim END
1053 def T()
1054 def Func(g: string):string
1055 enddef
1056 Func()
1057 enddef
1058 silent! defcompile
1059 END
1060 v9.CheckScriptFailure(lines, 'E1069:')
1061enddef
1062
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001063def Test_not_nested_function()
1064 echo printf('%d',
1065 function('len')('xxx'))
1066enddef
1067
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001068func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001069 call MyDefaultArgs()->assert_equal('string')
1070 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001071 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001072endfunc
1073
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001074def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001075 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001076 vim9script
1077 def Outer()
1078 def g:Inner(): string
1079 return 'inner'
1080 enddef
1081 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001082 defcompile
1083 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001084 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001085 delfunc g:Inner
1086 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001087 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001088 delfunc g:Inner
1089 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001090 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001091 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001092 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001093 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001094
1095 lines =<< trim END
1096 vim9script
1097 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001098 func g:Inner()
1099 return 'inner'
1100 endfunc
1101 enddef
1102 defcompile
1103 Outer()
1104 g:Inner()->assert_equal('inner')
1105 delfunc g:Inner
1106 Outer()
1107 g:Inner()->assert_equal('inner')
1108 delfunc g:Inner
1109 Outer()
1110 g:Inner()->assert_equal('inner')
1111 delfunc g:Inner
1112 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001113 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001114
1115 lines =<< trim END
1116 vim9script
1117 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001118 def g:Inner(): string
1119 return 'inner'
1120 enddef
1121 enddef
1122 defcompile
1123 Outer()
1124 Outer()
1125 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001126 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001127 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001128
1129 lines =<< trim END
1130 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001131 def Outer()
1132 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001133 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001134 enddef
1135 g:Inner()
1136 enddef
1137 Outer()
1138 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001139 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001140 delfunc g:Inner
1141
1142 lines =<< trim END
1143 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001144 def Func()
1145 echo 'script'
1146 enddef
1147 def Outer()
1148 def Func()
1149 echo 'inner'
1150 enddef
1151 enddef
1152 defcompile
1153 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001154 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001155
1156 lines =<< trim END
1157 vim9script
1158 def Func()
1159 echo 'script'
1160 enddef
1161 def Func()
1162 echo 'script'
1163 enddef
1164 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001165 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001166enddef
1167
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001168def DefListAll()
1169 def
1170enddef
1171
1172def DefListOne()
1173 def DefListOne
1174enddef
1175
1176def DefListMatches()
1177 def /DefList
1178enddef
1179
1180def Test_nested_def_list()
1181 var funcs = split(execute('call DefListAll()'), "\n")
1182 assert_true(len(funcs) > 10)
1183 assert_true(funcs->index('def DefListAll()') >= 0)
1184
1185 funcs = split(execute('call DefListOne()'), "\n")
1186 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1187
1188 funcs = split(execute('call DefListMatches()'), "\n")
1189 assert_true(len(funcs) >= 3)
1190 assert_true(funcs->index('def DefListAll()') >= 0)
1191 assert_true(funcs->index('def DefListOne()') >= 0)
1192 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001193
1194 var lines =<< trim END
1195 vim9script
1196 def Func()
1197 def +Func+
1198 enddef
1199 defcompile
1200 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001201 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001202enddef
1203
Bram Moolenaare08be092022-02-17 13:08:26 +00001204def Test_global_function_not_found()
1205 var lines =<< trim END
1206 g:Ref = 123
1207 call g:Ref()
1208 END
1209 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1210enddef
1211
Bram Moolenaar333894b2020-08-01 18:53:07 +02001212def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001213 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001214 vim9script
1215 def g:Func(): string
1216 return 'global'
1217 enddef
1218 def Func(): string
1219 return 'local'
1220 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001221 g:Func()->assert_equal('global')
1222 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001223 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001224 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001225 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001226
1227 lines =<< trim END
1228 vim9script
1229 def g:Funcy()
1230 echo 'funcy'
1231 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001232 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001233 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001234 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001235enddef
1236
Bram Moolenaar0f769812020-09-12 18:32:34 +02001237def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001238 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001239 vim9script
1240 def g:Gfunc(): string
1241 return 'global'
1242 enddef
1243 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001244 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001245 return Gfunc('testing')
1246 enddef
1247 g:Gfunc()->assert_equal('global')
1248 AnotherFunc()->assert_equal(7)
1249 delfunc g:Gfunc
1250 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001251 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001252
1253 lines =<< trim END
1254 vim9script
1255 def g:Func(): string
1256 return 'global'
1257 enddef
1258 def AnotherFunc()
1259 g:Func = function('len')
1260 enddef
1261 AnotherFunc()
1262 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001263 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001264 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001265
Bram Moolenaar62aec932022-01-29 21:45:34 +00001266 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001267 lines =<< trim END
1268 vim9script
1269 def g:Func(): string
1270 return 'global'
1271 enddef
1272 def AnotherFunc(): string
1273 return Func()
1274 enddef
1275 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001276 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001277 v9.CheckScriptFailure(lines, 'E117:')
1278 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001279
1280 lines =<< trim END
1281 vim9script
1282 def g:Func(): string
1283 return 'global'
1284 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001285 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001286 delfunc g:Func
1287 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001288 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001289
1290 # This does not shadow "i" which is visible only inside the for loop
1291 lines =<< trim END
1292 vim9script
1293
1294 def Foo(i: number)
1295 echo i
1296 enddef
1297
1298 for i in range(3)
1299 # Foo() is compiled here
1300 Foo(i)
1301 endfor
1302 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001303 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001304enddef
1305
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001306func TakesOneArg(arg)
1307 echo a:arg
1308endfunc
1309
1310def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001311 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1312 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1313 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1314 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001315
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001316 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001317 vim9script
1318 def Func(s: string)
1319 echo s
1320 enddef
1321 Func([])
1322 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01001323 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<any>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001324
Bram Moolenaar9a015112021-12-31 14:06:45 +00001325 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001326 lines =<< trim END
1327 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001328 var name = 'piet'
1329 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001330 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001331 enddef
1332 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001333 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001334
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001335 # same, inside the same block
1336 lines =<< trim END
1337 vim9script
1338 if true
1339 var name = 'piet'
1340 def FuncOne(name: string)
1341 echo name
1342 enddef
1343 endif
1344 END
1345 v9.CheckScriptFailure(lines, 'E1168:')
1346
1347 # variable in other block is OK
1348 lines =<< trim END
1349 vim9script
1350 if true
1351 var name = 'piet'
1352 endif
1353 def FuncOne(name: string)
1354 echo name
1355 enddef
1356 END
1357 v9.CheckScriptSuccess(lines)
1358
Bram Moolenaardce24412022-02-08 20:35:30 +00001359 # with another variable in another block
1360 lines =<< trim END
1361 vim9script
1362 if true
1363 var name = 'piet'
1364 # define a function so that the variable isn't cleared
1365 def GetItem(): string
1366 return item
1367 enddef
1368 endif
1369 if true
1370 var name = 'peter'
1371 def FuncOne(name: string)
1372 echo name
1373 enddef
1374 endif
1375 END
1376 v9.CheckScriptFailure(lines, 'E1168:')
1377
1378 # only variable in another block is OK
1379 lines =<< trim END
1380 vim9script
1381 if true
1382 var name = 'piet'
1383 # define a function so that the variable isn't cleared
1384 def GetItem(): string
1385 return item
1386 enddef
1387 endif
1388 if true
1389 def FuncOne(name: string)
1390 echo name
1391 enddef
1392 endif
1393 END
1394 v9.CheckScriptSuccess(lines)
1395
Bram Moolenaar9a015112021-12-31 14:06:45 +00001396 # argument name declared later is only found when compiling
1397 lines =<< trim END
1398 vim9script
1399 def FuncOne(name: string)
1400 echo nr
1401 enddef
1402 var name = 'piet'
1403 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001404 v9.CheckScriptSuccess(lines)
1405 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001406
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001407 lines =<< trim END
1408 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001409 def FuncOne(nr: number)
1410 echo nr
1411 enddef
1412 def FuncTwo()
1413 FuncOne()
1414 enddef
1415 defcompile
1416 END
1417 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001418 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001419 try
1420 source Xscript
1421 catch
1422 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1423 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1424 didCatch = true
1425 endtry
1426 assert_true(didCatch)
1427
1428 lines =<< trim END
1429 vim9script
1430 def FuncOne(nr: number)
1431 echo nr
1432 enddef
1433 def FuncTwo()
1434 FuncOne(1, 2)
1435 enddef
1436 defcompile
1437 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001438 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001439 didCatch = false
1440 try
1441 source Xscript
1442 catch
1443 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1444 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1445 didCatch = true
1446 endtry
1447 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001448enddef
1449
Bram Moolenaar50824712020-12-20 21:10:17 +01001450def Test_call_funcref_wrong_args()
1451 var head =<< trim END
1452 vim9script
1453 def Func3(a1: string, a2: number, a3: list<number>)
1454 echo a1 .. a2 .. a3[0]
1455 enddef
1456 def Testme()
1457 var funcMap: dict<func> = {func: Func3}
1458 END
1459 var tail =<< trim END
1460 enddef
1461 Testme()
1462 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001463 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001464
Bram Moolenaar62aec932022-01-29 21:45:34 +00001465 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1466 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001467
1468 var lines =<< trim END
1469 vim9script
1470 var Ref: func(number): any
1471 Ref = (j) => !j
1472 echo Ref(false)
1473 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001474 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001475
1476 lines =<< trim END
1477 vim9script
1478 var Ref: func(number): any
1479 Ref = (j) => !j
1480 call Ref(false)
1481 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001482 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001483enddef
1484
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001485def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001486 var lines =<< trim END
1487 var Callback = (..._) => 'anything'
1488 assert_equal('anything', Callback())
1489 assert_equal('anything', Callback(1))
1490 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001491
1492 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001493 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001494 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001495
Bram Moolenaar62aec932022-01-29 21:45:34 +00001496 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001497 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001498
Bram Moolenaar2a389082021-04-09 20:24:31 +02001499 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001500 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001501 echo Ref(1, 'x')
1502 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001503 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001504
1505 lines =<< trim END
1506 var Ref: func(job, string, number)
1507 Ref = (x, y) => 0
1508 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001509 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001510
1511 lines =<< trim END
1512 var Ref: func(job, string)
1513 Ref = (x, y, z) => 0
1514 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001515 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001516
1517 lines =<< trim END
1518 var one = 1
1519 var l = [1, 2, 3]
1520 echo map(l, (one) => one)
1521 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001522 v9.CheckDefFailure(lines, 'E1167:')
1523 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001524
1525 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001526 var Ref: func(any, ?any): bool
1527 Ref = (_, y = 1) => false
1528 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001529 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001530
1531 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001532 var a = 0
1533 var b = (a == 0 ? 1 : 2)
1534 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001535 var txt = 'a'
1536 b = (txt =~ 'x' ? 1 : 2)
1537 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001538 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001539 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001540
1541 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001542 def ShadowLocal()
1543 var one = 1
1544 var l = [1, 2, 3]
1545 echo map(l, (one) => one)
1546 enddef
1547 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001548 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001549
1550 lines =<< trim END
1551 def Shadowarg(one: number)
1552 var l = [1, 2, 3]
1553 echo map(l, (one) => one)
1554 enddef
1555 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001556 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001557
1558 lines =<< trim END
1559 echo ((a) => a)('aa', 'bb')
1560 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001561 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001562
1563 lines =<< trim END
1564 echo 'aa'->((a) => a)('bb')
1565 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001566 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1567 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001568enddef
1569
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001570def Test_lambda_line_nr()
1571 var lines =<< trim END
1572 vim9script
1573 # comment
1574 # comment
1575 var id = timer_start(1'000, (_) => 0)
1576 var out = execute('verbose ' .. timer_info(id)[0].callback
1577 ->string()
1578 ->substitute("('\\|')", ' ', 'g'))
1579 assert_match('Last set from .* line 4', out)
1580 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001581 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001582enddef
1583
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001584def FilterWithCond(x: string, Cond: func(string): bool): bool
1585 return Cond(x)
1586enddef
1587
Bram Moolenaar0346b792021-01-31 22:18:29 +01001588def Test_lambda_return_type()
1589 var lines =<< trim END
1590 var Ref = (): => 123
1591 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001592 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001593
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001594 # no space before the return type
1595 lines =<< trim END
1596 var Ref = (x):number => x + 1
1597 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001598 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001599
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001600 # this works
1601 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001602 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001603 endfor
1604
1605 # this fails
1606 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001607 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001608 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001609 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 +02001610
1611 lines =<< trim END
1612 var Lambda1 = (x) => {
1613 return x
1614 }
1615 assert_equal('asdf', Lambda1('asdf'))
1616 var Lambda2 = (x): string => {
1617 return x
1618 }
1619 assert_equal('foo', Lambda2('foo'))
1620 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001621 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001622
1623 lines =<< trim END
1624 var Lambda = (x): string => {
1625 return x
1626 }
1627 echo Lambda(['foo'])
1628 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001629 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001630enddef
1631
Bram Moolenaar709664c2020-12-12 14:33:41 +01001632def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001633 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001634 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001635 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001636enddef
1637
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001638def Test_lambda_invalid_block()
1639 var lines =<< trim END
1640 timer_start(0, (_) => { # echo
1641 echo 'yes'
1642 })
1643 END
1644 v9.CheckDefAndScriptSuccess(lines)
1645
1646 lines =<< trim END
1647 timer_start(0, (_) => { " echo
1648 echo 'yes'
1649 })
1650 END
1651 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1652
1653 lines =<< trim END
1654 timer_start(0, (_) => { | echo
1655 echo 'yes'
1656 })
1657 END
1658 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1659enddef
1660
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001661def Test_lambda_with_following_cmd()
1662 var lines =<< trim END
1663 set ts=2
1664 var Lambda = () => {
1665 set ts=4
1666 } | set ts=3
1667 assert_equal(3, &ts)
1668 Lambda()
1669 assert_equal(4, &ts)
1670 END
1671 v9.CheckDefAndScriptSuccess(lines)
1672 set ts=8
1673enddef
1674
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001675def Test_pass_legacy_lambda_to_def_func()
1676 var lines =<< trim END
1677 vim9script
1678 func Foo()
1679 eval s:Bar({x -> 0})
1680 endfunc
1681 def Bar(y: any)
1682 enddef
1683 Foo()
1684 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001685 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001686
1687 lines =<< trim END
1688 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001689 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001690 enddef
1691 legacy call g:TestFunc({-> 0})
1692 delfunc g:TestFunc
1693
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001694 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001695 enddef
1696 legacy call g:TestFunc({nr -> 0})
1697 delfunc g:TestFunc
1698 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001699 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001700enddef
1701
Bram Moolenaar844fb642021-10-23 13:32:30 +01001702def Test_lambda_in_reduce_line_break()
1703 # this was using freed memory
1704 var lines =<< trim END
1705 vim9script
1706 const result: dict<number> =
1707 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1708 ->reduce((acc, val) => {
1709 if has_key(acc, val)
1710 acc[val] += 1
1711 return acc
1712 else
1713 acc[val] = 1
1714 return acc
1715 endif
1716 }, {})
1717 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1718 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001719 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001720enddef
1721
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001722def Test_set_opfunc_to_lambda()
1723 var lines =<< trim END
1724 vim9script
1725 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1726 def CountSpaces(type = ''): string
1727 if type == ''
1728 &operatorfunc = (t) => CountSpaces(t)
1729 return 'g@'
1730 endif
1731 normal! '[V']y
1732 g:result = getreg('"')->count(' ')
1733 return ''
1734 enddef
1735 new
1736 'a b c d e'->setline(1)
1737 feedkeys("\<F4>", 'x')
1738 assert_equal(4, g:result)
1739 bwipe!
1740 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001741 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001742enddef
1743
Bram Moolenaaref082e12021-12-12 21:02:03 +00001744def Test_set_opfunc_to_global_function()
1745 var lines =<< trim END
1746 vim9script
1747 def g:CountSpaces(type = ''): string
1748 normal! '[V']y
1749 g:result = getreg('"')->count(' ')
1750 return ''
1751 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001752 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001753 &operatorfunc = g:CountSpaces
1754 new
1755 'a b c d e'->setline(1)
1756 feedkeys("g@_", 'x')
1757 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001758
1759 &operatorfunc = ''
1760 g:result = 0
1761 # global function works in :def function
1762 def Func()
1763 &operatorfunc = g:CountSpaces
1764 enddef
1765 Func()
1766 feedkeys("g@_", 'x')
1767 assert_equal(4, g:result)
1768
Bram Moolenaaref082e12021-12-12 21:02:03 +00001769 bwipe!
1770 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001771 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001772 &operatorfunc = ''
1773enddef
1774
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001775def Test_use_script_func_name_with_prefix()
1776 var lines =<< trim END
1777 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001778 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001779 return 'it'
1780 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001781 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001782 assert_equal('it', Fn())
1783 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001784 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001785enddef
1786
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001787def Test_lambda_type_allocated()
1788 # Check that unreferencing a partial using a lambda can use the variable type
1789 # after the lambda has been freed and does not leak memory.
1790 var lines =<< trim END
1791 vim9script
1792
1793 func MyomniFunc1(val, findstart, base)
1794 return a:findstart ? 0 : []
1795 endfunc
1796
1797 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1798 &omnifunc = Lambda
1799 Lambda = (a, b) => MyomniFunc1(20, a, b)
1800 &omnifunc = string(Lambda)
1801 Lambda = (a, b) => strlen(a)
1802 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001803 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001804enddef
1805
Bram Moolenaara7583c42022-05-07 21:14:05 +01001806def Test_define_lambda_in_execute()
1807 var lines =<< trim [CODE]
1808 vim9script
1809
1810 def BuildFuncMultiLine(): func
1811 var x =<< trim END
1812 g:SomeRandomFunc = (d: dict<any>) => {
1813 return d.k1 + d.k2
1814 }
1815 END
1816 execute(x)
1817 return g:SomeRandomFunc
1818 enddef
1819 var ResultPlus = BuildFuncMultiLine()
1820 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1821 [CODE]
1822 v9.CheckScriptSuccess(lines)
1823 unlet g:SomeRandomFunc
1824enddef
1825
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001826" Default arg and varargs
1827def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001828 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001829 for s in rest
1830 res ..= ',' .. s
1831 endfor
1832 return res
1833enddef
1834
1835def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001836 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1837 g:MyDefVarargs('one')->assert_equal('one,foo')
1838 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1839 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1840 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001841 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001842 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001843 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001844
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001845 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001846 vim9script
1847 def Func(...l: list<string>)
1848 echo l
1849 enddef
1850 Func('a', 'b', 'c')
1851 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001852 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001853
1854 lines =<< trim END
1855 vim9script
1856 def Func(...l: list<string>)
1857 echo l
1858 enddef
1859 Func()
1860 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001861 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001862
1863 lines =<< trim END
1864 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001865 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001866 echo l
1867 enddef
1868 Func(0)
1869 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001870 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001871
1872 lines =<< trim END
1873 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001874 def Func(...l: any)
1875 echo l
1876 enddef
1877 Func(0)
1878 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001879 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001880
1881 lines =<< trim END
1882 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001883 def Func(..._l: list<string>)
1884 echo _l
1885 enddef
1886 Func('a', 'b', 'c')
1887 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001888 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001889
1890 lines =<< trim END
1891 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001892 def Func(...l: list<string>)
1893 echo l
1894 enddef
1895 Func(1, 2, 3)
1896 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001897 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001898
1899 lines =<< trim END
1900 vim9script
1901 def Func(...l: list<string>)
1902 echo l
1903 enddef
1904 Func('a', 9)
1905 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001906 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001907
1908 lines =<< trim END
1909 vim9script
1910 def Func(...l: list<string>)
1911 echo l
1912 enddef
1913 Func(1, 'a')
1914 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001915 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001916
1917 lines =<< trim END
1918 vim9script
1919 def Func( # some comment
1920 ...l = []
1921 )
1922 echo l
1923 enddef
1924 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001925 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001926
1927 lines =<< trim END
1928 vim9script
1929 def DoIt()
1930 g:Later('')
1931 enddef
1932 defcompile
1933 def g:Later(...l: list<number>)
1934 enddef
1935 DoIt()
1936 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001937 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001938enddef
1939
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001940let s:value = ''
1941
1942def FuncOneDefArg(opt = 'text')
1943 s:value = opt
1944enddef
1945
1946def FuncTwoDefArg(nr = 123, opt = 'text'): string
1947 return nr .. opt
1948enddef
1949
1950def FuncVarargs(...arg: list<string>): string
1951 return join(arg, ',')
1952enddef
1953
1954def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001955 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001956 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001957 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001958 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001959 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001960 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001961
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001962 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001963 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001964 RefDef2Arg()->assert_equal('123text')
1965 RefDef2Arg(99)->assert_equal('99text')
1966 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001967
Bram Moolenaar62aec932022-01-29 21:45:34 +00001968 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
1969 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001970
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001971 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001972 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001973 RefVarargs()->assert_equal('')
1974 RefVarargs('one')->assert_equal('one')
1975 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001976
Bram Moolenaar62aec932022-01-29 21:45:34 +00001977 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
1978 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001979enddef
1980
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001981" Only varargs
1982def MyVarargsOnly(...args: list<string>): string
1983 return join(args, ',')
1984enddef
1985
1986def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001987 g:MyVarargsOnly()->assert_equal('')
1988 g:MyVarargsOnly('one')->assert_equal('one')
1989 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
1990 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
1991 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02001992enddef
1993
Bram Moolenaar36818a92023-01-03 12:33:26 +00001994def Test_varargs_mismatch()
1995 var lines =<< trim END
1996 vim9script
1997
1998 def Map(Fn: func(...any): number): number
1999 return Fn('12')
2000 enddef
2001
2002 var res = Map((v) => str2nr(v))
2003 assert_equal(12, res)
2004 END
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002005 v9.CheckScriptFailure(lines, 'E1180: Variable arguments type must be a list: any')
Bram Moolenaar36818a92023-01-03 12:33:26 +00002006enddef
2007
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002008def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00002009 var lines =<< trim END
2010 def Func(x: number)
2011 var x = 234
2012 enddef
2013 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002014 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002015
2016 lines =<< trim END
2017 def Func(Ref: number)
2018 def Ref()
2019 enddef
2020 enddef
2021 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002022 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002023enddef
2024
Bram Moolenaar62aec932022-01-29 21:45:34 +00002025def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002026 arg['key'] = 'value'
2027enddef
2028
Bram Moolenaar62aec932022-01-29 21:45:34 +00002029def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002030 arg[0] = 'value'
2031enddef
2032
2033def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002034 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002035 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002036 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002037 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002038 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002039 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002040 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002041
Bram Moolenaar62aec932022-01-29 21:45:34 +00002042 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002043 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002044enddef
2045
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002046" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002047def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002048 return firstline .. lastline
2049enddef
2050
2051def Test_argument_names()
2052 assert_equal('OK', WithReservedNames('O', 'K'))
2053enddef
2054
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002055def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002056 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002057 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002058enddef
2059
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002060func DefinedLater(arg)
2061 return a:arg
2062endfunc
2063
2064def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002065 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002066 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002067 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002068
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002069 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002070 vim9script
2071 def RetNumber(): number
2072 return 123
2073 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002074 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002075 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002076 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002077 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002078
2079 lines =<< trim END
2080 vim9script
2081 def RetNumber(): number
2082 return 123
2083 enddef
2084 def Bar(F: func: number): number
2085 return F()
2086 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002087 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002088 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002089 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002090 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002091
2092 lines =<< trim END
2093 vim9script
2094 def UseNumber(nr: number)
2095 echo nr
2096 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002097 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002098 Funcref(123)
2099 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002100 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002101
2102 lines =<< trim END
2103 vim9script
2104 def UseNumber(nr: number)
2105 echo nr
2106 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002107 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002108 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002109 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002110
2111 lines =<< trim END
2112 vim9script
2113 def EchoNr(nr = 34)
2114 g:echo = nr
2115 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002116 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002117 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002118 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002119 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002120 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002121 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002122 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002123
2124 lines =<< trim END
2125 vim9script
2126 def EchoList(...l: list<number>)
2127 g:echo = l
2128 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002129 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002130 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002131 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002132 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002133 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002134 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002135 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002136
2137 lines =<< trim END
2138 vim9script
2139 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2140 g:optarg = opt
2141 g:listarg = l
2142 return nr
2143 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002144 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002145 Funcref(10)->assert_equal(10)
2146 g:optarg->assert_equal(12)
2147 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002148
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002149 Funcref(11, 22)->assert_equal(11)
2150 g:optarg->assert_equal(22)
2151 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002152
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002153 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2154 g:optarg->assert_equal(18)
2155 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002156 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002157 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002158
2159 lines =<< trim END
2160 function s:func(num)
2161 return a:num * 2
2162 endfunction
2163
2164 def s:CallFuncref()
2165 var Funcref = function('s:func')
2166 Funcref(3)->assert_equal(6)
2167 enddef
2168 call s:CallFuncref()
2169 END
2170 v9.CheckScriptSuccess(lines)
2171
2172 lines =<< trim END
2173 function s:func(num)
2174 return a:num * 2
2175 endfunction
2176
2177 def s:CallFuncref()
2178 var Funcref = function(s:func)
2179 Funcref(3)->assert_equal(6)
2180 enddef
2181 call s:CallFuncref()
2182 END
2183 v9.CheckScriptSuccess(lines)
2184
2185 lines =<< trim END
2186 function s:func(num)
2187 return a:num * 2
2188 endfunction
2189
2190 def s:CallFuncref()
2191 var Funcref = s:func
2192 Funcref(3)->assert_equal(6)
2193 enddef
2194 call s:CallFuncref()
2195 END
2196 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002197enddef
2198
2199let SomeFunc = function('len')
2200let NotAFunc = 'text'
2201
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002202def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002203 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002204 var Ref1: func(bool): string
2205 var Ref2: func(bool): number
2206 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002207 Ref3 = g:cond ? Ref1 : Ref2
2208
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002209 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002210 var Refa1: func(bool): number
2211 var Refa2: func(bool, number): number
2212 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002213 Refa3 = g:cond ? Refa1 : Refa2
2214
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002215 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002216 var Refb1: func(bool, string): number
2217 var Refb2: func(string, number): number
2218 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002219 Refb3 = g:cond ? Refb1 : Refb2
2220enddef
2221
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002222def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002223 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002224enddef
2225
2226def DefinedEvenLater(arg: string): string
2227 return arg
2228enddef
2229
2230def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002231 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002232 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002233enddef
2234
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002235def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002236 var lines =<< trim END
2237 vim9script
2238 # Define an outer function
2239 def FirstFunction()
2240 # Define an inner function
2241 def SecondFunction()
2242 # the function has a body, a double free is detected.
2243 AAAAA
2244
2245 # enddef followed by | or } followed by # one or more characters
2246 enddef|BBBB
2247 enddef
2248
2249 # Compile all functions
2250 defcompile
2251 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002252 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002253enddef
2254
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002255def Test_nested_function_with_args_split()
2256 var lines =<< trim END
2257 vim9script
2258 def FirstFunction()
2259 def SecondFunction(
2260 )
2261 # had a double free if the right parenthesis of the nested function is
2262 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002263
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002264 enddef|BBBB
2265 enddef
2266 # Compile all functions
2267 defcompile
2268 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002269 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002270
2271 lines =<< trim END
2272 vim9script
2273 def FirstFunction()
2274 func SecondFunction()
2275 endfunc|BBBB
2276 enddef
2277 defcompile
2278 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002279 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002280enddef
2281
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002282def Test_error_in_function_args()
2283 var lines =<< trim END
2284 def FirstFunction()
2285 def SecondFunction(J =
2286 # Nois
2287 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002288
2289 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002290 enddef
2291 # Compile all functions
2292 defcompile
2293 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002294 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002295enddef
2296
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002297def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002298 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002299 'def Func(): number',
2300 'return "a"',
2301 'enddef',
2302 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002303 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002304 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002305 'def Func(): string',
2306 'return 1',
2307 'enddef',
2308 'defcompile'], 'expected string but got number')
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(): void',
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 Moolenaar62aec932022-01-29 21:45:34 +00002317 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002318 'def Func()',
2319 'return "a"',
2320 'enddef',
2321 'defcompile'],
2322 'E1096: Returning a value in a function without a return type')
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 Moolenaar5a849da2020-08-08 16:47:30 +02002326 'def Func(): number',
2327 'return',
2328 'enddef',
2329 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002330 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002331
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'], 'E1069:')
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 Moolenaar62aec932022-01-29 21:45:34 +00002346 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002347 'def Func() : number',
2348 'return 123',
2349 'enddef',
2350 'defcompile'], 'E1059:')
2351 delfunc! g:Func
2352
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002353 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002354 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002355 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002356 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002357 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002358 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002359
Bram Moolenaar62aec932022-01-29 21:45:34 +00002360 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002361 'vim9script',
2362 'def FuncB()',
2363 ' return 123',
2364 'enddef',
2365 'def FuncA()',
2366 ' FuncB()',
2367 'enddef',
2368 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002369enddef
2370
2371def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002372 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002373 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2374 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2375 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2376 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2377 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002378enddef
2379
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002380def Test_white_space_before_comma()
2381 var lines =<< trim END
2382 vim9script
2383 def Func(a: number , b: number)
2384 enddef
2385 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002386 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002387 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002388enddef
2389
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002390def Test_white_space_after_comma()
2391 var lines =<< trim END
2392 vim9script
2393 def Func(a: number,b: number)
2394 enddef
2395 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002396 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002397
2398 # OK in legacy function
2399 lines =<< trim END
2400 vim9script
2401 func Func(a,b)
2402 endfunc
2403 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002404 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002405enddef
2406
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002407def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002408 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002409 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002410 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002411 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002412 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002413 enddef
2414 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002415 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002416
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002417 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002418 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002419 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002420
Bram Moolenaar67979662020-06-20 22:50:47 +02002421 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002422 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002423 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002424
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002425 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002426 def ListFunc(arg: list<number>)
2427 listvar = arg
2428 enddef
2429 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002430 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002431
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002432 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002433 def DictFunc(arg: dict<number>)
2434 dictvar = arg
2435 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002436 {a: 1, b: 2}->DictFunc()
2437 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002438 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002439 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002440 enddef
2441 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002442 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002443
Bram Moolenaare0de1712020-12-02 17:36:54 +01002444 {a: 3, b: 4}->DictFunc()
2445 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002446
2447 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002448 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002449 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002450 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002451
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002452 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002453 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002454 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002455 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002456 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002457 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002458
2459 def UseString()
2460 'xyork'->MyFunc()
2461 enddef
2462 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002463 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002464
Bram Moolenaar10409562020-07-29 20:00:38 +02002465 def UseString2()
2466 "knife"->MyFunc()
2467 enddef
2468 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002469 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002470
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002471 # prepending a colon makes it a mark
2472 new
2473 setline(1, ['aaa', 'bbb', 'ccc'])
2474 normal! 3Gmt1G
2475 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002476 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002477 bwipe!
2478
Bram Moolenaare6b53242020-07-01 17:28:33 +02002479 MyFunc(
2480 'continued'
2481 )
2482 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002483 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002484 )
2485
2486 call MyFunc(
2487 'more'
2488 ..
2489 'lines'
2490 )
2491 assert_equal(
2492 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002493 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002494 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002495 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002496 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002497enddef
2498
2499def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002500 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002501 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002502 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002503 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002504 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002505 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002506 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002507 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002508 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002509enddef
2510
Bram Moolenaar65b95452020-07-19 14:03:09 +02002511def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002512 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002513 vim9script
2514 def MyFunc(arg: string)
2515 echo arg
2516 enddef
2517 MyFunc(1234)
2518 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002519 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002520enddef
2521
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002522def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002523 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002524 vim9script
2525 const var = ''
2526 def MyFunc(arg: string)
2527 var = 'asdf'
2528 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002529 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002530 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002531 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002532 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002533
2534 lines =<< trim END
2535 const g:Aconst = 77
2536 def Change()
2537 # comment
2538 g:Aconst = 99
2539 enddef
2540 call Change()
2541 unlet g:Aconst
2542 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002543 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002544enddef
2545
2546" Test that inside :function a Python function can be defined, :def is not
2547" recognized.
2548func Test_function_python()
2549 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002550 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002551 execute py "<< EOF"
2552def do_something():
2553 return 1
2554EOF
2555endfunc
2556
2557def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002558 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002559 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002560 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002561 echo 'hello'
2562 enddef
2563
2564 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002565 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002566 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002567 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002568
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002569 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002570 CallGoneSoon()
2571 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002572 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002573 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2574 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002575enddef
2576
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002577func Test_free_dict_while_in_funcstack()
2578 " relies on the sleep command
2579 CheckUnix
2580 call Run_Test_free_dict_while_in_funcstack()
2581endfunc
2582
2583def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002584 # this was freeing the TermRun() default argument dictionary while it was
2585 # still referenced in a funcstack_T
2586 var lines =<< trim END
2587 vim9script
2588
2589 &updatetime = 400
2590 def TermRun(_ = {})
2591 def Post()
2592 enddef
2593 def Exec()
2594 term_start('sleep 1', {
2595 term_finish: 'close',
2596 exit_cb: (_, _) => Post(),
2597 })
2598 enddef
2599 Exec()
2600 enddef
2601 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2602 timer_start(100, (_) => feedkeys("\<F4>"))
2603 timer_start(1000, (_) => feedkeys("\<F4>"))
2604 sleep 1500m
2605 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002606 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002607 nunmap <F4>
2608 set updatetime&
2609enddef
2610
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002611def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002612 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002613 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002614 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002615 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002616 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002617 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002618 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002619 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002620 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002621
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002622 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002623 g:Func1()->assert_equal('Func1')
2624 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002625
2626 delfunc! Func0
2627 delfunc! Func1
2628 delfunc! Func2
2629enddef
2630
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002631def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002632 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002633 vim9script
2634 func Func(arg)
2635 echo a:arg
2636 endfunc
2637 Func('text')
2638 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002639 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002640 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002641enddef
2642
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002643let s:funcResult = 0
2644
2645def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002646 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002647enddef
2648
2649def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002650 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002651 return 1234
2652enddef
2653
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002654def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002655 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002656 return 'text'
2657enddef
2658
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002659def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002660 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002661enddef
2662
2663def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002664 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002665 return arg
2666enddef
2667
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002668def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002669 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002670enddef
2671
Bram Moolenaar62aec932022-01-29 21:45:34 +00002672def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002673 return arg
2674enddef
2675
Bram Moolenaar62aec932022-01-29 21:45:34 +00002676def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002677 return arg
2678enddef
2679
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002680def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002681 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002682 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002683 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002684 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002685 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002686
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002687 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002688 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002689 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002690 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002691 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002692
Bram Moolenaar53900992020-08-22 19:02:02 +02002693 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002694 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002695 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002696 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002697
Bram Moolenaar53900992020-08-22 19:02:02 +02002698 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002699 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002700 Ref2()->assert_equal(1234)
2701 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002702
Bram Moolenaar53900992020-08-22 19:02:02 +02002703 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002704 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002705 Ref2(13)->assert_equal(13)
2706 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002707enddef
2708
Bram Moolenaar9978d472020-07-05 16:01:56 +02002709def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002710 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002711 for n in repeat([1], 3)
2712 res += n
2713 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002714 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002715
2716 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002717 for n in repeat(0z01, 3)->blob2list()
2718 res += n
2719 endfor
2720 res->assert_equal(3)
2721
2722 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002723 for n in add([1, 2], 3)
2724 res += n
2725 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002726 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002727enddef
2728
Bram Moolenaar846178a2020-07-05 17:04:13 +02002729def Test_argv_return_type()
2730 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002731 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002732 for name in argv()
2733 res ..= name
2734 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002735 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002736enddef
2737
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002738def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002739 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002740 RefVoid = g:FuncNoArgNoRet
2741 RefVoid = g:FuncOneArgNoRet
2742 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 +00002743 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 +02002744
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002745 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002746 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002747 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002748 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2749 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 +02002750
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002751 var RefAnyNoArgs: func: any = RefAny
2752
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002753 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002754 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002755 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002756 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 +00002757 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 +02002758
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002759 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002760 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002761 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002762 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2763 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 +02002764enddef
2765
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002766def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002767 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002768
Bram Moolenaar62aec932022-01-29 21:45:34 +00002769 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2770 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002771 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 +00002772 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2773 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002774 v9.CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1180: Variable arguments type must be a list: bool')
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002775
Bram Moolenaar62aec932022-01-29 21:45:34 +00002776 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2777 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2778 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:')
2779 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002780enddef
2781
Bram Moolenaar89228602020-04-05 22:14:54 +02002782def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002783 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002784 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002785 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002786
2787 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002788 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002789
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002790 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002791 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002792 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002793
Bram Moolenaar62aec932022-01-29 21:45:34 +00002794 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002795enddef
2796
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002797def Test_func_common_type()
2798 def FuncOne(n: number): number
2799 return n
2800 enddef
2801 def FuncTwo(s: string): number
2802 return len(s)
2803 enddef
2804 def FuncThree(n: number, s: string): number
2805 return n + len(s)
2806 enddef
2807 var list = [FuncOne, FuncTwo, FuncThree]
2808 assert_equal(8, list[0](8))
2809 assert_equal(4, list[1]('word'))
2810 assert_equal(7, list[2](3, 'word'))
2811enddef
2812
Bram Moolenaar62aec932022-01-29 21:45:34 +00002813def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002814 arg1: string,
2815 arg2 = 1234,
2816 ...rest: list<string>
2817 ): string
2818 return arg1 .. arg2 .. join(rest, '-')
2819enddef
2820
Bram Moolenaar2c330432020-04-13 14:41:35 +02002821def MultiLineComment(
2822 arg1: string, # comment
2823 arg2 = 1234, # comment
2824 ...rest: list<string> # comment
2825 ): string # comment
2826 return arg1 .. arg2 .. join(rest, '-')
2827enddef
2828
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002829def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002830 MultiLine('text')->assert_equal('text1234')
2831 MultiLine('text', 777)->assert_equal('text777')
2832 MultiLine('text', 777, 'one')->assert_equal('text777one')
2833 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002834enddef
2835
Bram Moolenaar23e03252020-04-12 22:22:31 +02002836func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002837 call s:MultiLine('text')->assert_equal('text1234')
2838 call s:MultiLine('text', 777)->assert_equal('text777')
2839 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2840 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002841endfunc
2842
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002843
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002844" When using CheckScriptFailure() for the below test, E1010 is generated instead
2845" of E1056.
2846func Test_E1056_1059()
2847 let caught_1056 = 0
2848 try
2849 def F():
2850 return 1
2851 enddef
2852 catch /E1056:/
2853 let caught_1056 = 1
2854 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002855 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002856
2857 let caught_1059 = 0
2858 try
2859 def F5(items : list)
2860 echo 'a'
2861 enddef
2862 catch /E1059:/
2863 let caught_1059 = 1
2864 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002865 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002866endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002867
Bram Moolenaar015f4262020-05-05 21:25:22 +02002868func DelMe()
2869 echo 'DelMe'
2870endfunc
2871
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002872def Test_error_reporting()
2873 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002874 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002875 " comment
2876 def Func()
2877 # comment
2878 # comment
2879 invalid
2880 enddef
2881 defcompile
2882 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002883 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002884 try
2885 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002886 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002887 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002888 v:exception->assert_match('Invalid command: invalid')
2889 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002890 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002891 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002892
2893 # comment lines after the start of the function
2894 lines =<< trim END
2895 " comment
2896 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002897 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002898 # comment
2899 # comment
2900 invalid
2901 enddef
2902 defcompile
2903 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002904 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002905 try
2906 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002907 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002908 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002909 v:exception->assert_match('Invalid command: invalid')
2910 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002911 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002912 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002913
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002914 lines =<< trim END
2915 vim9script
2916 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002917 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002918 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002919 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002920 enddef
2921 defcompile
2922 Func()
2923 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002924 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002925 try
2926 source Xdef
2927 assert_report('should have failed')
2928 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002929 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002930 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002931 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002932enddef
2933
Bram Moolenaar015f4262020-05-05 21:25:22 +02002934def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002935 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002936 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002937 'delfunc g:DelMe',
2938 'echo RefMe()'], 'E117:')
2939enddef
2940
2941def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002942 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002943 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002944 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002945enddef
2946
Bram Moolenaar62aec932022-01-29 21:45:34 +00002947def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002948 return Ref('more')
2949enddef
2950
2951def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002952 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002953 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002954enddef
2955
Bram Moolenaar62aec932022-01-29 21:45:34 +00002956def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002957 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002958 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002959enddef
2960
2961def Test_closure_ref_after_return()
2962 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002963 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002964 unlet g:Ref
2965enddef
2966
Bram Moolenaar62aec932022-01-29 21:45:34 +00002967def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002968 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002969 g:Extend = (s) => local->add(s)
2970 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002971enddef
2972
2973def Test_closure_two_refs()
2974 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002975 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002976 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002977 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002978 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002979 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002980
2981 unlet g:Extend
2982 unlet g:Read
2983enddef
2984
Bram Moolenaar62aec932022-01-29 21:45:34 +00002985def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002986 return join(Ref(), ' ')
2987enddef
2988
Bram Moolenaar62aec932022-01-29 21:45:34 +00002989def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002990 Ref(add)
2991enddef
2992
2993def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002994 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002995 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002996 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002997 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02002998 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002999 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003000
3001 unlet g:Extend
3002 unlet g:Read
3003enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003004
Bram Moolenaar62aec932022-01-29 21:45:34 +00003005def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003006 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003007 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003008enddef
3009
Bram Moolenaar62aec932022-01-29 21:45:34 +00003010def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003011 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003012 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003013enddef
3014
3015def Test_closure_using_argument()
3016 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003017 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003018
3019 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003020 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003021
3022 unlet g:UseArg
3023 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003024
3025 var lines =<< trim END
3026 vim9script
3027 def Test(Fun: func(number): number): list<number>
3028 return map([1, 2, 3], (_, i) => Fun(i))
3029 enddef
3030 def Inc(nr: number): number
3031 return nr + 2
3032 enddef
3033 assert_equal([3, 4, 5], Test(Inc))
3034 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003035 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003036enddef
3037
Bram Moolenaar62aec932022-01-29 21:45:34 +00003038def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003039 var local = 'a'
3040
3041 def Append(arg: string)
3042 local ..= arg
3043 enddef
3044 g:Append = Append
3045
3046 def Get(): string
3047 return local
3048 enddef
3049 g:Get = Get
3050enddef
3051
3052def Test_closure_append_get()
3053 MakeGetAndAppendRefs()
3054 g:Get()->assert_equal('a')
3055 g:Append('-b')
3056 g:Get()->assert_equal('a-b')
3057 g:Append('-c')
3058 g:Get()->assert_equal('a-b-c')
3059
3060 unlet g:Append
3061 unlet g:Get
3062enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003063
Bram Moolenaar04b12692020-05-04 23:24:44 +02003064def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003065 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003066 def Closure(arg: string): string
3067 return local .. arg
3068 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003069 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003070enddef
3071
Bram Moolenaar62aec932022-01-29 21:45:34 +00003072func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003073 return a:Ref('some')
3074endfunc
3075
3076def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003077 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003078 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003079 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003080enddef
3081
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003082def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003083 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003084 vim9script
3085 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003086 var name = 0
3087 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003088 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003089 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003090 enddef
3091 Func()
3092 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003093 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003094enddef
3095
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003096def Test_nested_closure_used()
3097 var lines =<< trim END
3098 vim9script
3099 def Func()
3100 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003101 var Closure = () => x
3102 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003103 enddef
3104 Func()
3105 assert_equal('hello', g:Myclosure())
3106 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003107 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003108enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003109
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003110def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003111 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003112 vim9script
3113 def FuncA()
3114 FuncB(0)
3115 enddef
3116 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003117 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003118 enddef
3119 FuncA()
3120 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003121 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003122enddef
3123
Bram Moolenaar6de22962022-09-09 21:35:36 +01003124def Run_Test_closure_in_for_loop_fails()
3125 var lines =<< trim END
3126 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003127 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003128 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003129 # time should be enough for startup to finish
3130 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003131 echo n
3132 })
3133 endfor
3134 END
3135 writefile(lines, 'XTest_closure_fails', 'D')
3136
3137 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003138 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003139 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003140
3141 # clean up
3142 g:StopVimInTerminal(buf)
3143enddef
3144
3145func Test_closure_in_for_loop_fails()
3146 CheckScreendump
3147 call Run_Test_closure_in_for_loop_fails()
3148endfunc
3149
Bram Moolenaarf112f302020-12-20 17:47:52 +01003150def Test_global_closure()
3151 var lines =<< trim END
3152 vim9script
3153 def ReverseEveryNLines(n: number, line1: number, line2: number)
3154 var mods = 'sil keepj keepp lockm '
3155 var range = ':' .. line1 .. ',' .. line2
3156 def g:Offset(): number
3157 var offset = (line('.') - line1 + 1) % n
3158 return offset != 0 ? offset : n
3159 enddef
3160 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3161 enddef
3162
3163 new
3164 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3165 ReverseEveryNLines(3, 1, 9)
3166 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003167 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003168 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3169 assert_equal(expected, getline(1, 9))
3170 bwipe!
3171enddef
3172
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003173def Test_global_closure_called_directly()
3174 var lines =<< trim END
3175 vim9script
3176 def Outer()
3177 var x = 1
3178 def g:Inner()
3179 var y = x
3180 x += 1
3181 assert_equal(1, y)
3182 enddef
3183 g:Inner()
3184 assert_equal(2, x)
3185 enddef
3186 Outer()
3187 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003188 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003189 delfunc g:Inner
3190enddef
3191
Bram Moolenaar69c76172021-12-02 16:38:52 +00003192def Test_closure_called_from_legacy()
3193 var lines =<< trim END
3194 vim9script
3195 def Func()
3196 var outer = 'foo'
3197 var F = () => {
3198 outer = 'bar'
3199 }
3200 execute printf('call %s()', string(F))
3201 enddef
3202 Func()
3203 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003204 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003205enddef
3206
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003207def Test_failure_in_called_function()
3208 # this was using the frame index as the return value
3209 var lines =<< trim END
3210 vim9script
3211 au TerminalWinOpen * eval [][0]
3212 def PopupTerm(a: any)
3213 # make sure typvals on stack are string
3214 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3215 FireEvent()
3216 enddef
3217 def FireEvent()
3218 do TerminalWinOpen
3219 enddef
3220 # use try/catch to make eval fail
3221 try
3222 call PopupTerm(0)
3223 catch
3224 endtry
3225 au! TerminalWinOpen
3226 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003227 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003228enddef
3229
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003230def Test_nested_lambda()
3231 var lines =<< trim END
3232 vim9script
3233 def Func()
3234 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003235 var Lambda1 = () => 7
3236 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003237 var res = Lambda2()
3238 assert_equal([7, 4], res)
3239 enddef
3240 Func()
3241 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003242 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003243enddef
3244
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003245def Test_double_nested_lambda()
3246 var lines =<< trim END
3247 vim9script
3248 def F(head: string): func(string): func(string): string
3249 return (sep: string): func(string): string => ((tail: string): string => {
3250 return head .. sep .. tail
3251 })
3252 enddef
3253 assert_equal('hello-there', F('hello')('-')('there'))
3254 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003255 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003256enddef
3257
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003258def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003259 var lines =<< trim END
3260 vim9script
3261 def F(text: string): func(string): func(string): string
3262 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003263 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003264 })
3265 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003266 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003267 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003268 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003269
3270 lines =<< trim END
3271 vim9script
3272 echo range(4)->mapnew((_, v) => {
3273 return range(v) ->mapnew((_, s) => {
3274 return string(s)
3275 })
3276 })
3277 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003278 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003279
3280 lines =<< trim END
3281 vim9script
3282
Bram Moolenaara749a422022-02-12 19:52:25 +00003283 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003284 range(10)
3285 ->mapnew((_, _) => ({
3286 key: range(10)->mapnew((_, _) => {
3287 return ' '
3288 }),
3289 }))
3290 enddef
3291
3292 defcomp
3293 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003294 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003295enddef
3296
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003297def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003298 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003299 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003300enddef
3301
3302def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003303 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003304enddef
3305
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003306def Test_compiling_referenced_func_no_shadow()
3307 var lines =<< trim END
3308 vim9script
3309
3310 def InitializeReply(lspserver: dict<any>)
3311 enddef
3312
3313 def ProcessReply(lspserver: dict<any>)
3314 var lsp_reply_handlers: dict<func> =
3315 { 'initialize': InitializeReply }
3316 lsp_reply_handlers['initialize'](lspserver)
3317 enddef
3318
3319 call ProcessReply({})
3320 END
3321 v9.CheckScriptSuccess(lines)
3322enddef
3323
Bram Moolenaar62aec932022-01-29 21:45:34 +00003324def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003325 var path: string = empty(dir)
3326 \ ? 'empty'
3327 \ : 'full'
3328 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003329enddef
3330
3331def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003332 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003333enddef
3334
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003335def Test_script_var_in_lambda()
3336 var lines =<< trim END
3337 vim9script
3338 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003339 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003340 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003341 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003342enddef
3343
Bram Moolenaar62aec932022-01-29 21:45:34 +00003344def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003345 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003346 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003347 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003348 ->reverse()
3349 return x
3350enddef
3351
3352def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003353 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003354
3355 var lines =<< trim END
3356 vim9script
3357 var res = [{n: 1, m: 2, s: 'xxx'}]
3358 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3359 v.n,
3360 v.m,
3361 substitute(v.s, '.*', 'yyy', '')
3362 ))
3363 assert_equal(['1:2:yyy'], res)
3364 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003365 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003366enddef
3367
Bram Moolenaarb6571982021-01-08 22:24:19 +01003368def Test_list_lambda()
3369 timer_start(1000, (_) => 0)
3370 var body = execute(timer_info()[0].callback
3371 ->string()
3372 ->substitute("('", ' ', '')
3373 ->substitute("')", '', '')
3374 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003375 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003376enddef
3377
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003378def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003379 var lines =<< trim END
3380 vim9script
3381 var flist: list<func>
3382 for i in range(10)
3383 var inloop = i
3384 flist[i] = () => inloop
3385 endfor
3386 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003387 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003388
3389 lines =<< trim END
3390 vim9script
3391 if true
3392 var outloop = 5
3393 var flist: list<func>
3394 for i in range(10)
3395 flist[i] = () => outloop
3396 endfor
3397 endif
3398 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003399 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003400
3401 lines =<< trim END
3402 vim9script
3403 if true
3404 var outloop = 5
3405 endif
3406 var flist: list<func>
3407 for i in range(10)
3408 flist[i] = () => outloop
3409 endfor
3410 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003411 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003412
3413 lines =<< trim END
3414 vim9script
3415 for i in range(10)
3416 var Ref = () => 0
3417 endfor
3418 assert_equal(0, ((i) => 0)(0))
3419 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003420 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003421enddef
3422
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003423def Test_legacy_lambda()
3424 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003425
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003426 var lines =<< trim END
3427 echo {x -> 'hello ' .. x}('foo')
3428 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003429 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003430
3431 lines =<< trim END
3432 vim9script
3433 def Func()
3434 echo (() => 'no error')()
3435 enddef
3436 legacy call s:Func()
3437 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003438 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003439enddef
3440
Bram Moolenaarce024c32021-06-26 13:00:49 +02003441def Test_legacy()
3442 var lines =<< trim END
3443 vim9script
3444 func g:LegacyFunction()
3445 let g:legacyvar = 1
3446 endfunc
3447 def Testit()
3448 legacy call g:LegacyFunction()
3449 enddef
3450 Testit()
3451 assert_equal(1, g:legacyvar)
3452 unlet g:legacyvar
3453 delfunc g:LegacyFunction
3454 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003455 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003456enddef
3457
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003458def Test_legacy_errors()
3459 for cmd in ['if', 'elseif', 'else', 'endif',
3460 'for', 'endfor', 'continue', 'break',
3461 'while', 'endwhile',
3462 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003463 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003464 endfor
3465enddef
3466
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003467def Test_call_legacy_with_dict()
3468 var lines =<< trim END
3469 vim9script
3470 func Legacy() dict
3471 let g:result = self.value
3472 endfunc
3473 def TestDirect()
3474 var d = {value: 'yes', func: Legacy}
3475 d.func()
3476 enddef
3477 TestDirect()
3478 assert_equal('yes', g:result)
3479 unlet g:result
3480
3481 def TestIndirect()
3482 var d = {value: 'foo', func: Legacy}
3483 var Fi = d.func
3484 Fi()
3485 enddef
3486 TestIndirect()
3487 assert_equal('foo', g:result)
3488 unlet g:result
3489
3490 var d = {value: 'bar', func: Legacy}
3491 d.func()
3492 assert_equal('bar', g:result)
3493 unlet g:result
3494 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003495 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003496enddef
3497
Bram Moolenaar62aec932022-01-29 21:45:34 +00003498def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003499 # closure nested inside another closure using argument
3500 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3501 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3502enddef
3503
3504def Test_nested_closure_using_argument()
3505 assert_equal(['x', 'x2'], DoFilterThis('x'))
3506enddef
3507
Bram Moolenaar0186e582021-01-10 18:33:11 +01003508def Test_triple_nested_closure()
3509 var what = 'x'
3510 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3511 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3512 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3513enddef
3514
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003515func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003516 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003517 call Run_Test_silent_echo()
3518endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003519
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003520def Run_Test_silent_echo()
3521 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003522 vim9script
3523 def EchoNothing()
3524 silent echo ''
3525 enddef
3526 defcompile
3527 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003528 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003529
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003530 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003531 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003532 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003533 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003534
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003535 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003536 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003537enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003538
Bram Moolenaar171fb922020-10-28 16:54:47 +01003539def SilentlyError()
3540 execute('silent! invalid')
3541 g:did_it = 'yes'
3542enddef
3543
Bram Moolenaar62aec932022-01-29 21:45:34 +00003544func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003545 silent! invalid
3546endfunc
3547
3548def SilentlyUserError()
3549 UserError()
3550 g:did_it = 'yes'
3551enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003552
3553" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003554func Test_ignore_silent_error()
3555 let g:did_it = 'no'
3556 call SilentlyError()
3557 call assert_equal('yes', g:did_it)
3558
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003559 let g:did_it = 'no'
3560 call SilentlyUserError()
3561 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003562
3563 unlet g:did_it
3564endfunc
3565
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003566def Test_ignore_silent_error_in_filter()
3567 var lines =<< trim END
3568 vim9script
3569 def Filter(winid: number, key: string): bool
3570 if key == 'o'
3571 silent! eval [][0]
3572 return true
3573 endif
3574 return popup_filter_menu(winid, key)
3575 enddef
3576
Bram Moolenaare0de1712020-12-02 17:36:54 +01003577 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003578 feedkeys("o\r", 'xnt')
3579 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003580 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003581enddef
3582
Bram Moolenaar62aec932022-01-29 21:45:34 +00003583def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003584 if n < 2
3585 return n
3586 else
3587 return Fibonacci(n - 1) + Fibonacci(n - 2)
3588 endif
3589enddef
3590
Bram Moolenaar985116a2020-07-12 17:31:09 +02003591def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003592 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003593enddef
3594
Bram Moolenaar62aec932022-01-29 21:45:34 +00003595def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003596 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003597 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003598 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003599 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003600 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003601enddef
3602
3603def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003604 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003605 writefile(['111'], 'XclosureDir/file1')
3606 writefile(['222'], 'XclosureDir/file2')
3607 writefile(['333'], 'XclosureDir/tdir/file3')
3608
Bram Moolenaare0de1712020-12-02 17:36:54 +01003609 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003610enddef
3611
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003612def Test_invalid_function_name()
3613 var lines =<< trim END
3614 vim9script
3615 def s: list<string>
3616 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003617 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003618
3619 lines =<< trim END
3620 vim9script
3621 def g: list<string>
3622 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003623 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003624
3625 lines =<< trim END
3626 vim9script
3627 def <SID>: list<string>
3628 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003629 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003630
3631 lines =<< trim END
3632 vim9script
3633 def F list<string>
3634 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003635 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003636enddef
3637
Bram Moolenaara90afb92020-07-15 22:38:56 +02003638def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003639 var lines =<< trim END
3640 var Xsetlist: func
3641 Xsetlist = function('setloclist', [0])
3642 Xsetlist([], ' ', {title: 'test'})
3643 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003644
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003645 Xsetlist = function('setloclist', [0, [], ' '])
3646 Xsetlist({title: 'test'})
3647 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003648
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003649 Xsetlist = function('setqflist')
3650 Xsetlist([], ' ', {title: 'test'})
3651 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003652
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003653 Xsetlist = function('setqflist', [[], ' '])
3654 Xsetlist({title: 'test'})
3655 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003656
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003657 var Len: func: number = function('len', ['word'])
3658 assert_equal(4, Len())
3659
3660 var RepeatFunc = function('repeat', ['o'])
3661 assert_equal('ooooo', RepeatFunc(5))
3662 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003663 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003664
3665 lines =<< trim END
3666 vim9script
3667 def Foo(Parser: any)
3668 enddef
3669 var Expr: func(dict<any>): dict<any>
3670 const Call = Foo(Expr)
3671 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003672 v9.CheckScriptFailure(lines, 'E1031:')
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02003673
3674 # Test for calling a partial that takes a single argument.
3675 # This used to produce a "E340: Internal error" message.
3676 lines =<< trim END
3677 def Foo(n: number): number
3678 return n * 2
3679 enddef
3680 var Fn = function(Foo, [10])
3681 assert_equal(20, Fn())
3682 END
3683 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara90afb92020-07-15 22:38:56 +02003684enddef
3685
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003686def Test_partial_double_nested()
3687 var idx = 123
3688 var Get = () => idx
3689 var Ref = function(Get, [])
3690 var RefRef = function(Ref, [])
3691 assert_equal(123, RefRef())
3692enddef
3693
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003694def Test_partial_null_function()
3695 var lines =<< trim END
3696 var d: dict<func> = {f: null_function}
3697 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003698 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003699 END
3700 v9.CheckDefAndScriptSuccess(lines)
3701enddef
3702
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003703def Test_cmd_modifier()
3704 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003705 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003706enddef
3707
3708def Test_restore_modifiers()
3709 # check that when compiling a :def function command modifiers are not messed
3710 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003711 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003712 vim9script
3713 set eventignore=
3714 autocmd QuickFixCmdPost * copen
3715 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003716 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003717 enddef
3718 func Func()
3719 noautocmd call s:AutocmdsDisabled()
3720 let g:ei_after = &eventignore
3721 endfunc
3722 Func()
3723 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003724 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003725 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003726enddef
3727
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003728def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003729 eval 1 + 2
3730 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003731 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003732 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003733enddef
3734
3735def StackBot()
3736 # throw an error
3737 eval [][0]
3738enddef
3739
3740def Test_callstack_def()
3741 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003742 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003743 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003744 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003745 endtry
3746enddef
3747
Bram Moolenaare8211a32020-10-09 22:04:29 +02003748" Re-using spot for variable used in block
3749def Test_block_scoped_var()
3750 var lines =<< trim END
3751 vim9script
3752 def Func()
3753 var x = ['a', 'b', 'c']
3754 if 1
3755 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003756 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003757 endif
3758 var z = x
3759 assert_equal(['x', 'x', 'x'], z)
3760 enddef
3761 Func()
3762 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003763 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003764enddef
3765
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003766def Test_reset_did_emsg()
3767 var lines =<< trim END
3768 @s = 'blah'
3769 au BufWinLeave * #
3770 def Func()
3771 var winid = popup_create('popup', {})
3772 exe '*s'
3773 popup_close(winid)
3774 enddef
3775 Func()
3776 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003777 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003778 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003779enddef
3780
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003781def Test_did_emsg_reset()
3782 # executing an autocommand resets did_emsg, this should not result in a
3783 # builtin function considered failing
3784 var lines =<< trim END
3785 vim9script
3786 au BufWinLeave * #
3787 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003788 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003789 eval [][0]
3790 enddef
3791 nno <F3> <cmd>call <sid>Func()<cr>
3792 feedkeys("\<F3>\e", 'xt')
3793 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003794 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003795 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003796
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003797 nunmap <F3>
3798 au! BufWinLeave
3799enddef
3800
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003801def Test_abort_with_silent_call()
3802 var lines =<< trim END
3803 vim9script
3804 g:result = 'none'
3805 def Func()
3806 g:result += 3
3807 g:result = 'yes'
3808 enddef
3809 # error is silenced, but function aborts on error
3810 silent! Func()
3811 assert_equal('none', g:result)
3812 unlet g:result
3813 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003814 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003815enddef
3816
Bram Moolenaarf665e972020-12-05 19:17:16 +01003817def Test_continues_with_silent_error()
3818 var lines =<< trim END
3819 vim9script
3820 g:result = 'none'
3821 def Func()
3822 silent! g:result += 3
3823 g:result = 'yes'
3824 enddef
3825 # error is silenced, function does not abort
3826 Func()
3827 assert_equal('yes', g:result)
3828 unlet g:result
3829 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003830 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003831enddef
3832
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003833def Test_abort_even_with_silent()
3834 var lines =<< trim END
3835 vim9script
3836 g:result = 'none'
3837 def Func()
3838 eval {-> ''}() .. '' .. {}['X']
3839 g:result = 'yes'
3840 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003841 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003842 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003843 unlet g:result
3844 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003845 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003846enddef
3847
Bram Moolenaarf665e972020-12-05 19:17:16 +01003848def Test_cmdmod_silent_restored()
3849 var lines =<< trim END
3850 vim9script
3851 def Func()
3852 g:result = 'none'
3853 silent! g:result += 3
3854 g:result = 'none'
3855 g:result += 3
3856 enddef
3857 Func()
3858 END
3859 # can't use CheckScriptFailure, it ignores the :silent!
3860 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003861 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003862 var caught = 'no'
3863 try
3864 exe 'source ' .. fname
3865 catch /E1030:/
3866 caught = 'yes'
3867 assert_match('Func, line 4', v:throwpoint)
3868 endtry
3869 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003870enddef
3871
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003872def Test_cmdmod_silent_nested()
3873 var lines =<< trim END
3874 vim9script
3875 var result = ''
3876
3877 def Error()
3878 result ..= 'Eb'
3879 eval [][0]
3880 result ..= 'Ea'
3881 enddef
3882
3883 def Crash()
3884 result ..= 'Cb'
3885 sil! Error()
3886 result ..= 'Ca'
3887 enddef
3888
3889 Crash()
3890 assert_equal('CbEbEaCa', result)
3891 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003892 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003893enddef
3894
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003895def Test_dict_member_with_silent()
3896 var lines =<< trim END
3897 vim9script
3898 g:result = 'none'
3899 var d: dict<any>
3900 def Func()
3901 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003902 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003903 catch
3904 endtry
3905 enddef
3906 silent! Func()
3907 assert_equal('0', g:result)
3908 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003909 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003910 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003911enddef
3912
Bram Moolenaarf9041332021-01-21 19:41:16 +01003913def Test_skip_cmds_with_silent()
3914 var lines =<< trim END
3915 vim9script
3916
3917 def Func(b: bool)
3918 Crash()
3919 enddef
3920
3921 def Crash()
3922 sil! :/not found/d _
3923 sil! :/not found/put _
3924 enddef
3925
3926 Func(true)
3927 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003928 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003929enddef
3930
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003931def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003932 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003933 def g:Opfunc(_: any): string
3934 setline(1, 'ASDF')
3935 return ''
3936 enddef
3937 new
3938 setline(1, 'asdf')
3939 feedkeys("\<F3>$", 'x')
3940 assert_equal('ASDF', getline(1))
3941
3942 bwipe!
3943 nunmap <F3>
3944enddef
3945
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003946func Test_opfunc_error()
3947 CheckScreendump
3948 call Run_Test_opfunc_error()
3949endfunc
3950
3951def Run_Test_opfunc_error()
3952 # test that the error from Opfunc() is displayed right away
3953 var lines =<< trim END
3954 vim9script
3955
3956 def Opfunc(type: string)
3957 try
3958 eval [][0]
3959 catch /nothing/ # error not caught
3960 endtry
3961 enddef
3962 &operatorfunc = Opfunc
3963 nnoremap <expr> l <SID>L()
3964 def L(): string
3965 return 'l'
3966 enddef
3967 'x'->repeat(10)->setline(1)
3968 feedkeys('g@l', 'n')
3969 feedkeys('llll')
3970 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003971 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003972
Bram Moolenaar62aec932022-01-29 21:45:34 +00003973 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
3974 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01003975 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003976
3977 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003978 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003979enddef
3980
Bram Moolenaar077a4232020-12-22 18:33:27 +01003981" this was crashing on exit
3982def Test_nested_lambda_in_closure()
3983 var lines =<< trim END
3984 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003985 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003986 def Outer()
3987 def g:Inner()
3988 echo map([1, 2, 3], {_, v -> v + 1})
3989 enddef
3990 g:Inner()
3991 enddef
3992 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02003993 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01003994 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003995 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01003996 return
3997 endif
3998 assert_equal(['Done'], readfile('XnestedDone'))
3999 delete('XnestedDone')
4000enddef
4001
Bram Moolenaar92368aa2022-02-07 17:50:39 +00004002def Test_nested_closure_funcref()
4003 var lines =<< trim END
4004 vim9script
4005 def Func()
4006 var n: number
4007 def Nested()
4008 ++n
4009 enddef
4010 Nested()
4011 g:result_one = n
4012 var Ref = function(Nested)
4013 Ref()
4014 g:result_two = n
4015 enddef
4016 Func()
4017 END
4018 v9.CheckScriptSuccess(lines)
4019 assert_equal(1, g:result_one)
4020 assert_equal(2, g:result_two)
4021 unlet g:result_one g:result_two
4022enddef
4023
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004024def Test_nested_closure_in_dict()
4025 var lines =<< trim END
4026 vim9script
4027 def Func(): dict<any>
4028 var n: number
4029 def Inc(): number
4030 ++n
4031 return n
4032 enddef
4033 return {inc: function(Inc)}
4034 enddef
4035 disas Func
4036 var d = Func()
4037 assert_equal(1, d.inc())
4038 assert_equal(2, d.inc())
4039 END
4040 v9.CheckScriptSuccess(lines)
4041enddef
4042
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004043def Test_script_local_other_script()
4044 var lines =<< trim END
4045 function LegacyJob()
4046 let FuncRef = function('s:close_cb')
4047 endfunction
4048 function s:close_cb(...)
4049 endfunction
4050 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004051 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004052 source Xlegacy.vim
4053 g:LegacyJob()
4054 g:LegacyJob()
4055 g:LegacyJob()
4056
4057 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004058enddef
4059
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004060def Test_check_func_arg_types()
4061 var lines =<< trim END
4062 vim9script
4063 def F1(x: string): string
4064 return x
4065 enddef
4066
4067 def F2(x: number): number
4068 return x + 1
4069 enddef
4070
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004071 def G(Fg: func): dict<func>
4072 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004073 enddef
4074
4075 def H(d: dict<func>): string
4076 return d.f('a')
4077 enddef
4078 END
4079
Bram Moolenaar62aec932022-01-29 21:45:34 +00004080 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4081 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004082
4083 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004084enddef
4085
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004086def Test_call_func_with_null()
4087 var lines =<< trim END
4088 def Fstring(v: string)
4089 assert_equal(null_string, v)
4090 enddef
4091 Fstring(null_string)
4092 def Fblob(v: blob)
4093 assert_equal(null_blob, v)
4094 enddef
4095 Fblob(null_blob)
4096 def Flist(v: list<number>)
4097 assert_equal(null_list, v)
4098 enddef
4099 Flist(null_list)
4100 def Fdict(v: dict<number>)
4101 assert_equal(null_dict, v)
4102 enddef
4103 Fdict(null_dict)
4104 def Ffunc(Fv: func(number): number)
4105 assert_equal(null_function, Fv)
4106 enddef
4107 Ffunc(null_function)
4108 if has('channel')
4109 def Fchannel(v: channel)
4110 assert_equal(null_channel, v)
4111 enddef
4112 Fchannel(null_channel)
4113 def Fjob(v: job)
4114 assert_equal(null_job, v)
4115 enddef
4116 Fjob(null_job)
4117 endif
4118 END
4119 v9.CheckDefAndScriptSuccess(lines)
4120enddef
4121
4122def Test_null_default_argument()
4123 var lines =<< trim END
4124 def Fstring(v: string = null_string)
4125 assert_equal(null_string, v)
4126 enddef
4127 Fstring()
4128 def Fblob(v: blob = null_blob)
4129 assert_equal(null_blob, v)
4130 enddef
4131 Fblob()
4132 def Flist(v: list<number> = null_list)
4133 assert_equal(null_list, v)
4134 enddef
4135 Flist()
4136 def Fdict(v: dict<number> = null_dict)
4137 assert_equal(null_dict, v)
4138 enddef
4139 Fdict()
4140 def Ffunc(Fv: func(number): number = null_function)
4141 assert_equal(null_function, Fv)
4142 enddef
4143 Ffunc()
4144 if has('channel')
4145 def Fchannel(v: channel = null_channel)
4146 assert_equal(null_channel, v)
4147 enddef
4148 Fchannel()
4149 def Fjob(v: job = null_job)
4150 assert_equal(null_job, v)
4151 enddef
4152 Fjob()
4153 endif
4154 END
4155 v9.CheckDefAndScriptSuccess(lines)
4156enddef
4157
4158def Test_null_return()
4159 var lines =<< trim END
4160 def Fstring(): string
4161 return null_string
4162 enddef
4163 assert_equal(null_string, Fstring())
4164 def Fblob(): blob
4165 return null_blob
4166 enddef
4167 assert_equal(null_blob, Fblob())
4168 def Flist(): list<number>
4169 return null_list
4170 enddef
4171 assert_equal(null_list, Flist())
4172 def Fdict(): dict<number>
4173 return null_dict
4174 enddef
4175 assert_equal(null_dict, Fdict())
4176 def Ffunc(): func(number): number
4177 return null_function
4178 enddef
4179 assert_equal(null_function, Ffunc())
4180 if has('channel')
4181 def Fchannel(): channel
4182 return null_channel
4183 enddef
4184 assert_equal(null_channel, Fchannel())
4185 def Fjob(): job
4186 return null_job
4187 enddef
4188 assert_equal(null_job, Fjob())
4189 endif
4190 END
4191 v9.CheckDefAndScriptSuccess(lines)
4192enddef
4193
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004194def Test_list_any_type_checked()
4195 var lines =<< trim END
4196 vim9script
4197 def Foo()
4198 --decl--
4199 Bar(l)
4200 enddef
4201 def Bar(ll: list<dict<any>>)
4202 enddef
4203 Foo()
4204 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004205 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004206 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004207 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004208 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004209 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004210
4211 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004212 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004213enddef
4214
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004215def Test_compile_error()
4216 var lines =<< trim END
4217 def g:Broken()
4218 echo 'a' + {}
4219 enddef
4220 call g:Broken()
4221 END
4222 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004223 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004224
4225 # Second call won't try compiling again
4226 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004227 delfunc g:Broken
4228
4229 # No error when compiling with :silent!
4230 lines =<< trim END
4231 def g:Broken()
4232 echo 'a' + []
4233 enddef
4234 silent! defcompile
4235 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004236 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004237
4238 # Calling the function won't try compiling again
4239 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4240 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004241enddef
4242
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004243def Test_ignored_argument()
4244 var lines =<< trim END
4245 vim9script
4246 def Ignore(_, _): string
4247 return 'yes'
4248 enddef
4249 assert_equal('yes', Ignore(1, 2))
4250
4251 func Ok(_)
4252 return a:_
4253 endfunc
4254 assert_equal('ok', Ok('ok'))
4255
4256 func Oktoo()
4257 let _ = 'too'
4258 return _
4259 endfunc
4260 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004261
4262 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004263 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004264 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004265
4266 lines =<< trim END
4267 def Ignore(_: string): string
4268 return _
4269 enddef
4270 defcompile
4271 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004272 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004273
4274 lines =<< trim END
4275 var _ = 1
4276 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004277 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004278
4279 lines =<< trim END
4280 var x = _
4281 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004282 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004283enddef
4284
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004285def Test_too_many_arguments()
4286 var lines =<< trim END
4287 echo [0, 1, 2]->map(() => 123)
4288 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004289 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004290
4291 lines =<< trim END
4292 echo [0, 1, 2]->map((_) => 123)
4293 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004294 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004295
4296 lines =<< trim END
4297 vim9script
4298 def OneArgument(arg: string)
4299 echo arg
4300 enddef
4301 var Ref = OneArgument
4302 Ref('a', 'b')
4303 END
4304 v9.CheckScriptFailure(lines, 'E118:')
4305enddef
4306
4307def Test_funcref_with_base()
4308 var lines =<< trim END
4309 vim9script
4310 def TwoArguments(str: string, nr: number)
4311 echo str nr
4312 enddef
4313 var Ref = TwoArguments
4314 Ref('a', 12)
4315 'b'->Ref(34)
4316 END
4317 v9.CheckScriptSuccess(lines)
4318
4319 lines =<< trim END
4320 vim9script
4321 def TwoArguments(str: string, nr: number)
4322 echo str nr
4323 enddef
4324 var Ref = TwoArguments
4325 'a'->Ref('b')
4326 END
4327 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4328
4329 lines =<< trim END
4330 vim9script
4331 def TwoArguments(str: string, nr: number)
4332 echo str nr
4333 enddef
4334 var Ref = TwoArguments
4335 123->Ref(456)
4336 END
4337 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4338
4339 lines =<< trim END
4340 vim9script
4341 def TwoArguments(nr: number, str: string)
4342 echo str nr
4343 enddef
4344 var Ref = TwoArguments
4345 123->Ref('b')
4346 def AndNowCompiled()
4347 456->Ref('x')
4348 enddef
4349 AndNowCompiled()
4350 END
4351 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004352enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004353
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004354def Test_closing_brace_at_start_of_line()
4355 var lines =<< trim END
4356 def Func()
4357 enddef
4358 Func(
4359 )
4360 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004361 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004362enddef
4363
Bram Moolenaar62aec932022-01-29 21:45:34 +00004364func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004365 let g:mydict = {}
4366 func g:mydict.afunc()
4367 let g:result = self.key
4368 endfunc
4369endfunc
4370
4371def Test_numbered_function_reference()
4372 CreateMydict()
4373 var output = execute('legacy func g:mydict.afunc')
4374 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4375 execute 'function(' .. funcName .. ', [], {key: 42})()'
4376 # check that the function still exists
4377 assert_equal(output, execute('legacy func g:mydict.afunc'))
4378 unlet g:mydict
4379enddef
4380
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004381def Test_numbered_function_call()
4382 var lines =<< trim END
4383 let s:legacyscript = {}
4384 func s:legacyscript.Helper() abort
4385 return "Success"
4386 endfunc
4387 let g:legacyscript = deepcopy(s:legacyscript)
4388
4389 let g:legacy_result = eval("g:legacyscript.Helper()")
4390 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4391 END
4392 v9.CheckScriptSuccess(lines)
4393 assert_equal('Success', g:legacy_result)
4394 assert_equal('Success', g:vim9_result)
4395
4396 unlet g:legacy_result
4397 unlet g:vim9_result
4398enddef
4399
Bram Moolenaard3a11782022-01-05 16:50:40 +00004400def Test_go_beyond_end_of_cmd()
4401 # this was reading the byte after the end of the line
4402 var lines =<< trim END
4403 def F()
4404 cal
4405 enddef
4406 defcompile
4407 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004408 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004409enddef
4410
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004411" Test for memory allocation failure when defining a new lambda
4412func Test_lambda_allocation_failure()
4413 new
4414 let lines =<< trim END
4415 vim9script
4416 g:Xlambda = (x): number => {
4417 return x + 1
4418 }
4419 END
4420 call setline(1, lines)
4421 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4422 call assert_fails('source', 'E342:')
4423 call assert_false(exists('g:Xlambda'))
4424 bw!
4425endfunc
4426
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004427def Test_lambda_argument_type_check()
4428 var lines =<< trim END
4429 vim9script
4430
4431 def Scan(ll: list<any>): func(func(any))
4432 return (Emit: func(any)) => {
4433 for e in ll
4434 Emit(e)
4435 endfor
4436 }
4437 enddef
4438
4439 def Sum(Cont: func(func(any))): any
4440 var sum = 0.0
4441 Cont((v: float) => { # <== NOTE: the lambda expects a float
4442 sum += v
4443 })
4444 return sum
4445 enddef
4446
Bram Moolenaar47bba532023-01-20 18:49:46 +00004447 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004448 echo Scan(ml)->Sum()
4449 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004450 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004451enddef
4452
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004453def Test_multiple_funcref()
4454 # This was using a NULL pointer
4455 var lines =<< trim END
4456 vim9script
4457 def A(F: func, ...args: list<any>): func
4458 return funcref(F, args)
4459 enddef
4460
4461 def B(F: func): func
4462 return funcref(A, [F])
4463 enddef
4464
4465 def Test(n: number)
4466 enddef
4467
4468 const X = B(Test)
4469 X(1)
4470 END
4471 v9.CheckScriptSuccess(lines)
4472
4473 # slightly different case
4474 lines =<< trim END
4475 vim9script
4476
4477 def A(F: func, ...args: list<any>): any
4478 return call(F, args)
4479 enddef
4480
4481 def B(F: func): func
4482 return funcref(A, [F])
4483 enddef
4484
4485 def Test(n: number)
4486 enddef
4487
4488 const X = B(Test)
4489 X(1)
4490 END
4491 v9.CheckScriptSuccess(lines)
4492enddef
4493
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004494def Test_cexpr_errmsg_line_number()
4495 var lines =<< trim END
4496 vim9script
4497 def Func()
4498 var qfl = {}
4499 cexpr qfl
4500 enddef
4501 Func()
4502 END
4503 v9.CheckScriptFailure(lines, 'E777', 2)
4504enddef
4505
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004506def AddDefer(s: string)
4507 g:deferred->extend([s])
4508enddef
4509
4510def DeferTwo()
4511 g:deferred->extend(['in Two'])
4512 for n in range(3)
4513 defer g:AddDefer('two' .. n)
4514 endfor
4515 g:deferred->extend(['end Two'])
4516enddef
4517
4518def DeferOne()
4519 g:deferred->extend(['in One'])
4520 defer g:AddDefer('one')
4521 g:DeferTwo()
4522 g:deferred->extend(['end One'])
4523
4524 writefile(['text'], 'XdeferFile')
4525 defer delete('XdeferFile')
4526enddef
4527
4528def Test_defer()
4529 g:deferred = []
4530 g:DeferOne()
4531 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4532 unlet g:deferred
4533 assert_equal('', glob('XdeferFile'))
4534enddef
4535
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004536def Test_invalid_redir()
4537 var lines =<< trim END
4538 def Tone()
4539 if 1
4540 redi =>@�0
4541 redi END
4542 endif
4543 enddef
4544 defcompile
4545 END
4546 v9.CheckScriptFailure(lines, 'E354:')
4547 delfunc g:Tone
4548
4549 # this was reading past the end of the line
4550 lines =<< trim END
4551 def Ttwo()
4552 if 0
4553 redi =>@�0
4554 redi END
4555 endif
4556 enddef
4557 defcompile
4558 END
4559 v9.CheckScriptFailure(lines, 'E354:')
4560 delfunc g:Ttwo
4561enddef
4562
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004563func Test_keytyped_in_nested_function()
4564 CheckRunVimInTerminal
4565
4566 call Run_Test_keytyped_in_nested_function()
4567endfunc
4568
4569def Run_Test_keytyped_in_nested_function()
4570 var lines =<< trim END
4571 vim9script
4572 autocmd CmdlineEnter * sample#Init()
4573
4574 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4575 END
4576 writefile(lines, 'Xkeytyped', 'D')
4577
4578 var dir = 'Xrtpdir/autoload'
4579 mkdir(dir, 'pR')
4580
4581 lines =<< trim END
4582 vim9script
4583 export def Init(): void
4584 cnoremap <expr>" <SID>Quote('"')
4585 enddef
4586 def Quote(str: string): string
4587 def InPair(): number
4588 return 0
4589 enddef
4590 return str
4591 enddef
4592 END
4593 writefile(lines, dir .. '/sample.vim')
4594
4595 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4596
4597 term_sendkeys(buf, ':"')
4598 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4599
4600 # clean up
4601 term_sendkeys(buf, "\<Esc>")
4602 g:StopVimInTerminal(buf)
4603enddef
4604
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004605" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004606if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004607 def Test_python3_command()
4608 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004609 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004610 assert_equal('yes', g:done)
4611 unlet g:done
4612 enddef
4613
Bram Moolenaar20677332021-06-06 17:02:53 +02004614 def Test_python3_heredoc()
4615 py3 << trim EOF
4616 import vim
4617 vim.vars['didit'] = 'yes'
4618 EOF
4619 assert_equal('yes', g:didit)
4620
4621 python3 << trim EOF
4622 import vim
4623 vim.vars['didit'] = 'again'
4624 EOF
4625 assert_equal('again', g:didit)
4626 enddef
4627endif
4628
Bram Moolenaar20677332021-06-06 17:02:53 +02004629if has('lua')
4630 def Test_lua_heredoc()
4631 g:d = {}
4632 lua << trim EOF
4633 x = vim.eval('g:d')
4634 x['key'] = 'val'
4635 EOF
4636 assert_equal('val', g:d.key)
4637 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004638
4639 def Test_lua_heredoc_fails()
4640 var lines = [
4641 'vim9script',
4642 'def ExeLua()',
4643 'lua << trim EOLUA',
4644 "x = vim.eval('g:nodict')",
4645 'EOLUA',
4646 'enddef',
4647 'ExeLua()',
4648 ]
4649 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4650 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004651endif
4652
Bram Moolenaard881d152022-05-13 13:50:36 +01004653if has('perl')
4654 def Test_perl_heredoc_nested()
4655 var lines =<< trim END
4656 vim9script
4657 def F(): string
4658 def G(): string
4659 perl << EOF
4660 EOF
4661 return 'done'
4662 enddef
4663 return G()
4664 enddef
4665 assert_equal('done', F())
4666 END
4667 v9.CheckScriptSuccess(lines)
4668 enddef
4669endif
4670
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004671
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004672" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker