blob: 1d5de42ffbc1c428a8c86958ac2175efc9f6d273 [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
Ernie Raelcb90ea92024-08-19 21:45:23 +0200167
168 lines =<< trim END
169 vim9script
170 var F1_ref: func
171 def Start()
172 F1_ref()
173 enddef
174 Start()
175 END
176 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar22f17a22021-06-21 20:48:58 +0200177enddef
178
Ernie Rael3f821d62024-04-24 20:07:50 +0200179" Check that in a legacy script a :def accesses the correct script variables.
180" Github issue: #14615.
181def Test_access_var_from_legacy_def()
182 # Access a script variable by name WITH "s:" prefix.
183 var lines =<< trim END
184 let s:foo = 'init'
185 let s:xxfoo = 'init'
186 def! AccessVarFromLegacyDef()
187 s:xxfoo = 'CHANGED'
188 enddef
189 call AccessVarFromLegacyDef()
190 call assert_equal('init', s:foo)
191 call assert_equal('CHANGED', s:xxfoo)
192 END
193 v9.CheckScriptSuccess(lines)
194
195 # Access a script variable by name WITHOUT "s:" prefix;
196 # previously this accessed "foo" and not "xxfoo"
197 lines =<< trim END
198 let s:foo = 'init'
199 let s:xxfoo = 'init'
200 def! AccessVarFromLegacyDef()
201 xxfoo = 'CHANGED'
202 enddef
203 call AccessVarFromLegacyDef()
204 call assert_equal('init', s:foo)
205 call assert_equal('CHANGED', s:xxfoo)
206 END
207 v9.CheckScriptSuccess(lines)
208enddef
209
Bram Moolenaard4a9b7f2023-05-23 14:48:42 +0100210def Test_listing_function_error()
211 var lines =<< trim END
212 var filler = 123
213 func DoesNotExist
214 END
215 v9.CheckDefExecFailure(lines, 'E123:', 2)
216enddef
217
Bram Moolenaar3f45d672023-02-27 22:06:51 +0000218def Test_break_in_skipped_block()
219 var lines =<< trim END
220 vim9script
221
222 def FixStackFrame(): string
223 for _ in [2]
224 var path = 'xxx'
225 if !!path
226 if false
227 break
228 else
229 return 'foo'
230 endif
231 endif
232 endfor
233 return 'xxx'
234 enddef
235
236 disas FixStackFrame
237
238 FixStackFrame()
239 END
240 v9.CheckScriptSuccess(lines)
241enddef
242
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200243def Test_autoload_name_mismatch()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100244 var dir = 'Xnamedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100245 mkdir(dir, 'pR')
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200246
247 var lines =<< trim END
248 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000249 export def NoFunction()
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200250 # comment
251 g:runtime = 'yes'
252 enddef
253 END
254 writefile(lines, dir .. '/script.vim')
255
256 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100257 exe 'set rtp=' .. getcwd() .. '/Xnamedir'
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200258 lines =<< trim END
259 call script#Function()
260 END
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000261 v9.CheckScriptFailure(lines, 'E117:', 1)
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200262
263 &rtp = save_rtp
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200264enddef
265
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200266def Test_autoload_names()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100267 var dir = 'Xandir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100268 mkdir(dir, 'pR')
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200269
270 var lines =<< trim END
271 func foobar#function()
272 return 'yes'
273 endfunc
274 let foobar#var = 'no'
275 END
276 writefile(lines, dir .. '/foobar.vim')
277
278 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100279 exe 'set rtp=' .. getcwd() .. '/Xandir'
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200280
281 lines =<< trim END
282 assert_equal('yes', foobar#function())
283 var Function = foobar#function
284 assert_equal('yes', Function())
285
286 assert_equal('no', foobar#var)
287 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000288 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200289
290 &rtp = save_rtp
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200291enddef
292
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200293def Test_autoload_error_in_script()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100294 var dir = 'Xaedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100295 mkdir(dir, 'pR')
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200296
297 var lines =<< trim END
298 func scripterror#function()
299 let g:called_function = 'yes'
300 endfunc
301 let 0 = 1
302 END
303 writefile(lines, dir .. '/scripterror.vim')
304
305 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100306 exe 'set rtp=' .. getcwd() .. '/Xaedir'
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200307
308 g:called_function = 'no'
309 # The error in the autoload script cannot be checked with assert_fails(), use
310 # CheckDefSuccess() instead of CheckDefFailure()
311 try
Bram Moolenaar62aec932022-01-29 21:45:34 +0000312 v9.CheckDefSuccess(['scripterror#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200313 catch
314 assert_match('E121: Undefined variable: 0', v:exception)
315 endtry
316 assert_equal('no', g:called_function)
317
318 lines =<< trim END
319 func scriptcaught#function()
320 let g:called_function = 'yes'
321 endfunc
322 try
323 let 0 = 1
324 catch
325 let g:caught = v:exception
326 endtry
327 END
328 writefile(lines, dir .. '/scriptcaught.vim')
329
330 g:called_function = 'no'
Bram Moolenaar62aec932022-01-29 21:45:34 +0000331 v9.CheckDefSuccess(['scriptcaught#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200332 assert_match('E121: Undefined variable: 0', g:caught)
333 assert_equal('yes', g:called_function)
334
335 &rtp = save_rtp
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200336enddef
337
Bram Moolenaar62aec932022-01-29 21:45:34 +0000338def s:CallRecursive(n: number): number
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100339 return CallRecursive(n + 1)
340enddef
341
Bram Moolenaar62aec932022-01-29 21:45:34 +0000342def s:CallMapRecursive(l: list<number>): number
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100343 return map(l, (_, v) => CallMapRecursive([v]))[0]
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100344enddef
345
346def Test_funcdepth_error()
347 set maxfuncdepth=10
348
349 var caught = false
350 try
351 CallRecursive(1)
352 catch /E132:/
353 caught = true
354 endtry
355 assert_true(caught)
356
357 caught = false
358 try
359 CallMapRecursive([1])
360 catch /E132:/
361 caught = true
362 endtry
363 assert_true(caught)
364
365 set maxfuncdepth&
366enddef
367
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100368def Test_endfunc_enddef()
369 var lines =<< trim END
370 def Test()
371 echo 'test'
372 endfunc
373 enddef
374 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000375 v9.CheckScriptFailure(lines, 'E1151:', 3)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100376
377 lines =<< trim END
378 def Test()
379 func Nested()
380 echo 'test'
381 enddef
382 enddef
383 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000384 v9.CheckScriptFailure(lines, 'E1152:', 4)
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100385
386 lines =<< trim END
387 def Ok()
388 echo 'hello'
389 enddef | echo 'there'
390 def Bad()
391 echo 'hello'
392 enddef there
393 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000394 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100395enddef
396
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100397def Test_missing_endfunc_enddef()
398 var lines =<< trim END
399 vim9script
400 def Test()
401 echo 'test'
402 endef
403 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000404 v9.CheckScriptFailure(lines, 'E1057:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100405
406 lines =<< trim END
407 vim9script
408 func Some()
409 echo 'test'
410 enfffunc
411 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000412 v9.CheckScriptFailure(lines, 'E126:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100413enddef
414
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100415def Test_white_space_before_paren()
416 var lines =<< trim END
417 vim9script
418 def Test ()
419 echo 'test'
420 enddef
421 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000422 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100423
424 lines =<< trim END
425 vim9script
426 func Test ()
427 echo 'test'
428 endfunc
429 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000430 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100431
432 lines =<< trim END
433 def Test ()
434 echo 'test'
435 enddef
436 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000437 v9.CheckScriptFailure(lines, 'E1068:', 1)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100438
439 lines =<< trim END
440 func Test ()
441 echo 'test'
442 endfunc
443 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000444 v9.CheckScriptSuccess(lines)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100445enddef
446
Bram Moolenaar832ea892021-01-08 21:55:26 +0100447def Test_enddef_dict_key()
448 var d = {
449 enddef: 'x',
450 endfunc: 'y',
451 }
452 assert_equal({enddef: 'x', endfunc: 'y'}, d)
453enddef
454
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200455def ReturnString(): string
456 return 'string'
457enddef
458
459def ReturnNumber(): number
460 return 123
461enddef
462
463let g:notNumber = 'string'
464
465def ReturnGlobal(): number
466 return g:notNumber
467enddef
468
469def Test_return_something()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000470 g:ReturnString()->assert_equal('string')
471 g:ReturnNumber()->assert_equal(123)
Bram Moolenaar848fadd2022-01-30 15:28:30 +0000472 assert_fails('g:ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaaref7aadb2022-01-18 18:46:07 +0000473
474 var lines =<< trim END
475 vim9script
476
477 def Msg()
478 echomsg 'in Msg()...'
479 enddef
480
481 def Func()
482 return Msg()
483 enddef
484 defcompile
485 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000486 v9.CheckScriptFailure(lines, 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200487enddef
488
Bram Moolenaare32e5162021-01-21 20:21:29 +0100489def Test_check_argument_type()
490 var lines =<< trim END
491 vim9script
492 def Val(a: number, b: number): number
493 return 0
494 enddef
495 def Func()
496 var x: any = true
497 Val(0, x)
498 enddef
499 disass Func
500 Func()
501 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000502 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
Bram Moolenaar56310d32022-12-27 17:25:05 +0000503
504 lines =<< trim END
505 vim9script
506
507 def Foobar(Fn: func(any, ?string): any)
508 enddef
509
510 Foobar((t) => 0)
511 END
512 v9.CheckScriptSuccess(lines)
Bram Moolenaare32e5162021-01-21 20:21:29 +0100513enddef
514
Bram Moolenaarefd88552020-06-18 20:50:10 +0200515def Test_missing_return()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000516 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200517 ' if g:cond',
518 ' echo "no return"',
519 ' else',
520 ' return 0',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100521 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200522 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000523 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200524 ' if g:cond',
525 ' return 1',
526 ' else',
527 ' echo "no return"',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100528 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200529 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000530 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200531 ' if g:cond',
532 ' return 1',
533 ' else',
534 ' return 2',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100535 ' endif',
536 ' return 3',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200537 'enddef'], 'E1095:')
538enddef
539
Bram Moolenaarcf2610c2023-05-14 19:59:59 +0100540def Test_not_missing_return()
541 var lines =<< trim END
542 def Funky(): number
543 if false
544 return 0
545 endif
546 throw 'Error'
547 enddef
548 defcompile
549 END
550 v9.CheckScriptSuccess(lines)
551enddef
552
Yegappan Lakshmananab9a8942024-12-30 09:56:34 +0100553" Test for an if-else block ending in a throw statement
554def Test_if_else_with_throw()
555 var lines =<< trim END
556 def Ifelse_Throw1(): number
557 if false
558 return 1
559 else
560 throw 'Error'
561 endif
562 enddef
563 defcompile
564 END
565 v9.CheckScriptSuccess(lines)
566
567 lines =<< trim END
568 def Ifelse_Throw2(): number
569 if true
570 throw 'Error'
571 else
572 return 2
573 endif
574 enddef
575 defcompile
576 END
577 v9.CheckScriptSuccess(lines)
578
579 lines =<< trim END
580 def Ifelse_Throw3(): number
581 if true
582 return 1
583 elseif false
584 throw 'Error'
585 else
586 return 3
587 endif
588 enddef
589 defcompile
590 END
591 v9.CheckScriptSuccess(lines)
592enddef
593
Bram Moolenaar403dc312020-10-17 19:29:51 +0200594def Test_return_bool()
595 var lines =<< trim END
596 vim9script
597 def MenuFilter(id: number, key: string): bool
598 return popup_filter_menu(id, key)
599 enddef
600 def YesnoFilter(id: number, key: string): bool
601 return popup_filter_yesno(id, key)
602 enddef
603 defcompile
604 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000605 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200606enddef
607
mityu500c4442022-12-02 18:12:05 +0000608def Test_return_void_comment_follows()
609 var lines =<< trim END
610 vim9script
611 def ReturnCommentFollows(): void
612 return # Some comment
613 enddef
614 defcompile
615 END
616 v9.CheckScriptSuccess(lines)
617enddef
618
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200619let s:nothing = 0
620def ReturnNothing()
621 s:nothing = 1
622 if true
623 return
624 endif
625 s:nothing = 2
626enddef
627
628def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000629 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200630 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200631enddef
632
Bram Moolenaar648ea762021-01-15 19:04:32 +0100633def Test_return_invalid()
634 var lines =<< trim END
635 vim9script
636 def Func(): invalid
637 return xxx
638 enddef
639 defcompile
640 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000641 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100642
643 lines =<< trim END
644 vim9script
645 def Test(Fun: func(number): number): list<number>
646 return map([1, 2, 3], (_, i) => Fun(i))
647 enddef
648 defcompile
649 def Inc(nr: number): nr
650 return nr + 2
651 enddef
652 echo Test(Inc)
653 END
654 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000655 v9.CheckScriptFailure(lines, 'E1010:')
656 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100657enddef
658
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200659def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000660 # This used to fail but now the actual list type is checked, and since it has
661 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200662 var lines =<< trim END
663 vim9script
664 def Func(): list<string>
665 var l: list<any>
666 l->add('string')
667 return l
668 enddef
669 echo Func()
670 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000671 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000672
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200673 lines =<< trim END
674 vim9script
675 def Func(): list<string>
676 var l: list<any>
677 l += ['string']
678 return l
679 enddef
680 echo Func()
681 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000682 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200683enddef
684
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000685def Test_return_any_two_types()
686 var lines =<< trim END
687 vim9script
688
689 def G(Fn: func(string): any)
690 g:result = Fn("hello")
691 enddef
692
693 def F(a: number, b: string): any
694 echo b
695 if a > 0
696 return 1
697 else
698 return []
699 endif
700 enddef
701
702 G(function(F, [1]))
703 END
704 v9.CheckScriptSuccess(lines)
705 assert_equal(1, g:result)
706 unlet g:result
707enddef
708
Bram Moolenaar62aec932022-01-29 21:45:34 +0000709func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200710 let g:counter += 1
711endfunc
712
713def Test_call_ufunc_count()
714 g:counter = 1
715 Increment()
716 Increment()
717 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200718 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200719 g:counter->assert_equal(4)
720 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200721 unlet g:counter
722enddef
723
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000724def Test_call_ufunc_failure()
725 var lines =<< trim END
726 vim9script
727 def Tryit()
728 g:Global(1, 2, 3)
729 enddef
730
731 func g:Global(a, b, c)
732 echo a:a a:b a:c
733 endfunc
734
735 defcompile
736
737 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000738 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000739 endfunc
740 Tryit()
741 END
742 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
743 delfunc g:Global
744
745 lines =<< trim END
746 vim9script
747
748 g:Ref = function('len')
749 def Tryit()
750 g:Ref('x')
751 enddef
752
753 defcompile
754
755 g:Ref = function('add')
756 Tryit()
757 END
758 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
759 unlet g:Ref
760enddef
761
Bram Moolenaar62aec932022-01-29 21:45:34 +0000762def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200763 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200764 for s in rest
765 res ..= ',' .. s
766 endfor
767 return res
768enddef
769
770def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200771 MyVarargs('one')->assert_equal('one')
772 MyVarargs('one', 'two')->assert_equal('one,two')
773 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200774enddef
775
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200776def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000777 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200778enddef
779
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200780def MyDefaultArgs(name = 'string'): string
781 return name
782enddef
783
Bram Moolenaar62aec932022-01-29 21:45:34 +0000784def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200785 return second ? name : 'none'
786enddef
787
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200788
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200789def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000790 g:MyDefaultArgs()->assert_equal('string')
791 g:MyDefaultArgs(v:none)->assert_equal('string')
792 g:MyDefaultArgs('one')->assert_equal('one')
793 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200794
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200795 MyDefaultSecond('test')->assert_equal('test')
796 MyDefaultSecond('test', true)->assert_equal('test')
797 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200798
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200799 var lines =<< trim END
800 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
801 return name .. aa .. bb
802 enddef
803
804 MyDefaultThird('->')->assert_equal('->aabb')
805 MyDefaultThird('->', v:none)->assert_equal('->aabb')
806 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
807 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
808 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
809 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
810 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200811
812 def DefArg(mandatory: any, optional = mandatory): string
813 return mandatory .. optional
814 enddef
815 DefArg(1234)->assert_equal('12341234')
816 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200817 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000818 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200819
Bram Moolenaar62aec932022-01-29 21:45:34 +0000820 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100821 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000822 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 +0100823 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000824 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100825
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200826 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100827 vim9script
828 def Func(a = b == 0 ? 1 : 2, b = 0)
829 enddef
830 defcompile
831 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000832 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000833
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000834 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000835 lines =<< trim END
836 vim9script
837 var a: any
838 def Func(arg: string = a)
839 echo arg
840 enddef
841 defcompile
842 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000843 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
844 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000845
846 # using global variable does not require type cast
847 lines =<< trim END
848 vim9script
849 def Func(arg: string = g:str)
850 echo arg
851 enddef
852 g:str = 'works'
853 Func()
854 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000855 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200856enddef
857
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100858def Test_using_vnone_default()
859 var lines =<< trim END
860 vim9script
861
862 def F(a: string = v:none)
863 if a isnot v:none
864 var b = a
865 endif
866 enddef
867 F()
868 END
869 v9.CheckScriptSuccess(lines)
870
Bram Moolenaar2ba51232023-05-15 16:22:38 +0100871 lines =<< trim END
872 vim9script
873
874 export def Floats(x: float, y = 2.0, z = 5.0)
875 g:result = printf("%.2f %.2f %.2f", x, y, z)
876 enddef
877 END
878 writefile(lines, 'Xlib.vim', 'D')
879
880 # test using a function reference in script-local variable
881 lines =<< trim END
882 vim9script
883
884 import './Xlib.vim'
885 const Floatfunc = Xlib.Floats
886 Floatfunc(1.0, v:none, 3.0)
887 END
888 v9.CheckScriptSuccess(lines)
889 assert_equal('1.00 2.00 3.00', g:result)
890 unlet g:result
891
892 # test calling the imported function
893 lines =<< trim END
894 vim9script
895
896 import './Xlib.vim'
897 Xlib.Floats(1.0, v:none, 3.0)
898 END
899 v9.CheckScriptSuccess(lines)
900 assert_equal('1.00 2.00 3.00', g:result)
901 unlet g:result
902
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100903 # TODO: this should give an error for using a missing argument
904 # lines =<< trim END
905 # vim9script
906
907 # def F(a: string = v:none)
908 # var b = a
909 # enddef
910 # F()
911 # END
912 # v9.CheckScriptFailure(lines, 'E99:')
913enddef
914
Bram Moolenaar47bba532023-01-20 18:49:46 +0000915def Test_convert_number_to_float()
916 var lines =<< trim END
917 vim9script
918 def Foo(a: float, b: float): float
919 return a + b
920 enddef
921
922 assert_equal(5.3, Foo(3.3, 2))
923 END
924 v9.CheckScriptSuccess(lines)
925enddef
926
Bram Moolenaar62aec932022-01-29 21:45:34 +0000927def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100928 a: number, #comment
929 b: bool, # comment
930 c: string) #comment
931 assert_equal(4, a)
932 assert_equal(true, b)
933 assert_equal('yes', c)
934enddef
935
936def Test_func_with_comments()
937 FuncWithComment(4, true, 'yes')
938
939 var lines =<< trim END
940 def Func(# comment
941 arg: string)
942 enddef
943 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000944 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100945
946 lines =<< trim END
Christian Brabandte4a450a2023-12-08 20:57:38 +0100947 def Func(f=
948 )
949 enddef
950 END
951 v9.CheckScriptFailure(lines, 'E125:', 2)
952
953 lines =<< trim END
Bram Moolenaarcef12702021-01-04 14:09:43 +0100954 def Func(
955 arg: string# comment
956 )
957 enddef
958 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000959 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100960
961 lines =<< trim END
962 def Func(
963 arg: string
964 )# comment
965 enddef
966 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000967 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100968enddef
969
Bram Moolenaar04b12692020-05-04 23:24:44 +0200970def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000971 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200972 return 'nested ' .. arg
973 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000974 NestedDef(':def')->assert_equal('nested :def')
975
976 func NestedFunc(arg)
977 return 'nested ' .. a:arg
978 endfunc
979 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200980
Bram Moolenaar62aec932022-01-29 21:45:34 +0000981 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
982 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200983
Bram Moolenaar62aec932022-01-29 21:45:34 +0000984 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
985 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200986
Bram Moolenaar54021752020-12-06 18:50:36 +0100987 var lines =<< trim END
988 def Outer()
989 def Inner()
990 # comment
991 enddef
992 def Inner()
993 enddef
994 enddef
995 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000996 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100997
998 lines =<< trim END
999 def Outer()
1000 def Inner()
1001 # comment
1002 enddef
1003 def! Inner()
1004 enddef
1005 enddef
1006 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001007 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +01001008
Bram Moolenaardb8e5c22021-12-25 19:58:22 +00001009 lines =<< trim END
1010 vim9script
1011 def Outer()
1012 def Inner()
1013 g:result = 'ok'
1014 enddef
1015 Inner()
1016 enddef
1017 Outer()
1018 Inner()
1019 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001020 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +00001021 assert_equal('ok', g:result)
1022 unlet g:result
1023
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001024 lines =<< trim END
1025 vim9script
1026 def Outer()
1027 def _Inner()
1028 echo 'bad'
1029 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +00001030 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001031 enddef
1032 defcompile
1033 END
Bram Moolenaar3787f262022-02-07 21:54:01 +00001034 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001035
1036 lines =<< trim END
1037 vim9script
1038 def Outer()
1039 def g:inner()
1040 echo 'bad'
1041 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +00001042 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001043 enddef
1044 defcompile
1045 END
Bram Moolenaar3787f262022-02-07 21:54:01 +00001046 v9.CheckScriptFailure(lines, 'E1267:')
1047
1048 lines =<< trim END
1049 vim9script
1050 def g:_Func()
1051 echo 'bad'
1052 enddef
1053 END
1054 v9.CheckScriptFailure(lines, 'E1267:')
1055
1056 lines =<< trim END
1057 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001058 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +00001059 echo 'bad'
1060 enddef
1061 END
1062 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001063
Bram Moolenaar54021752020-12-06 18:50:36 +01001064 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +01001065 lines =<< trim END
1066 vim9script
1067 var thecount = 0
1068 if true
1069 def Test(): number
1070 def TheFunc(): number
1071 thecount += 1
1072 return thecount
1073 enddef
1074 return TheFunc()
1075 enddef
1076 endif
1077 defcompile
1078 assert_equal(1, Test())
1079 assert_equal(2, Test())
1080 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001081 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001082
1083 # also works when "thecount" is inside the "if" block
1084 lines =<< trim END
1085 vim9script
1086 if true
1087 var thecount = 0
1088 def Test(): number
1089 def TheFunc(): number
1090 thecount += 1
1091 return thecount
1092 enddef
1093 return TheFunc()
1094 enddef
1095 endif
1096 defcompile
1097 assert_equal(1, Test())
1098 assert_equal(2, Test())
1099 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001100 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001101
Bram Moolenaara915fa02022-03-23 11:29:15 +00001102 # nested function with recursive call
1103 lines =<< trim END
1104 vim9script
1105
1106 def MyFunc(): number
1107 def Fib(n: number): number
1108 if n < 2
1109 return 1
1110 endif
1111 return Fib(n - 2) + Fib(n - 1)
1112 enddef
1113
1114 return Fib(5)
1115 enddef
1116
1117 assert_equal(8, MyFunc())
1118 END
1119 v9.CheckScriptSuccess(lines)
1120
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001121 lines =<< trim END
1122 vim9script
1123 def Outer()
1124 def Inner()
1125 echo 'hello'
1126 enddef burp
1127 enddef
1128 defcompile
1129 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001130 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001131enddef
1132
Bram Moolenaar1889f492022-08-16 19:34:44 +01001133def Test_nested_function_fails()
1134 var lines =<< trim END
1135 def T()
1136 def Func(g: string):string
1137 enddef
1138 Func()
1139 enddef
1140 silent! defcompile
1141 END
1142 v9.CheckScriptFailure(lines, 'E1069:')
1143enddef
1144
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001145def Test_not_nested_function()
1146 echo printf('%d',
1147 function('len')('xxx'))
1148enddef
1149
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001150func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001151 call MyDefaultArgs()->assert_equal('string')
1152 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001153 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001154endfunc
1155
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001156def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001157 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001158 vim9script
1159 def Outer()
1160 def g:Inner(): string
1161 return 'inner'
1162 enddef
1163 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001164 defcompile
1165 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001166 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001167 delfunc g:Inner
1168 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001169 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001170 delfunc g:Inner
1171 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001172 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001173 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001174 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001175 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001176
1177 lines =<< trim END
1178 vim9script
1179 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001180 func g:Inner()
1181 return 'inner'
1182 endfunc
1183 enddef
1184 defcompile
1185 Outer()
1186 g:Inner()->assert_equal('inner')
1187 delfunc g:Inner
1188 Outer()
1189 g:Inner()->assert_equal('inner')
1190 delfunc g:Inner
1191 Outer()
1192 g:Inner()->assert_equal('inner')
1193 delfunc g:Inner
1194 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001195 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001196
1197 lines =<< trim END
1198 vim9script
1199 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001200 def g:Inner(): string
1201 return 'inner'
1202 enddef
1203 enddef
1204 defcompile
1205 Outer()
1206 Outer()
1207 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001208 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001209 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001210
1211 lines =<< trim END
1212 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001213 def Outer()
1214 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001215 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001216 enddef
1217 g:Inner()
1218 enddef
1219 Outer()
1220 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001221 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001222 delfunc g:Inner
1223
1224 lines =<< trim END
1225 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001226 def Func()
1227 echo 'script'
1228 enddef
1229 def Outer()
1230 def Func()
1231 echo 'inner'
1232 enddef
1233 enddef
1234 defcompile
1235 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001236 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001237
1238 lines =<< trim END
1239 vim9script
1240 def Func()
1241 echo 'script'
1242 enddef
1243 def Func()
1244 echo 'script'
1245 enddef
1246 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001247 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001248enddef
1249
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001250def DefListAll()
1251 def
1252enddef
1253
1254def DefListOne()
1255 def DefListOne
1256enddef
1257
1258def DefListMatches()
1259 def /DefList
1260enddef
1261
1262def Test_nested_def_list()
1263 var funcs = split(execute('call DefListAll()'), "\n")
1264 assert_true(len(funcs) > 10)
1265 assert_true(funcs->index('def DefListAll()') >= 0)
1266
1267 funcs = split(execute('call DefListOne()'), "\n")
1268 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1269
1270 funcs = split(execute('call DefListMatches()'), "\n")
1271 assert_true(len(funcs) >= 3)
1272 assert_true(funcs->index('def DefListAll()') >= 0)
1273 assert_true(funcs->index('def DefListOne()') >= 0)
1274 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001275
1276 var lines =<< trim END
1277 vim9script
1278 def Func()
1279 def +Func+
1280 enddef
1281 defcompile
1282 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001283 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001284enddef
1285
Bram Moolenaare08be092022-02-17 13:08:26 +00001286def Test_global_function_not_found()
1287 var lines =<< trim END
1288 g:Ref = 123
1289 call g:Ref()
1290 END
1291 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1292enddef
1293
Bram Moolenaar333894b2020-08-01 18:53:07 +02001294def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001295 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001296 vim9script
1297 def g:Func(): string
1298 return 'global'
1299 enddef
1300 def Func(): string
1301 return 'local'
1302 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001303 g:Func()->assert_equal('global')
1304 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001305 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001306 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001307 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001308
1309 lines =<< trim END
1310 vim9script
1311 def g:Funcy()
1312 echo 'funcy'
1313 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001314 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001315 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001316 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001317enddef
1318
Bram Moolenaar0f769812020-09-12 18:32:34 +02001319def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001320 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001321 vim9script
1322 def g:Gfunc(): string
1323 return 'global'
1324 enddef
1325 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001326 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001327 return Gfunc('testing')
1328 enddef
1329 g:Gfunc()->assert_equal('global')
1330 AnotherFunc()->assert_equal(7)
1331 delfunc g:Gfunc
1332 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001333 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001334
1335 lines =<< trim END
1336 vim9script
1337 def g:Func(): string
1338 return 'global'
1339 enddef
1340 def AnotherFunc()
1341 g:Func = function('len')
1342 enddef
1343 AnotherFunc()
1344 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001345 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001346 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001347
Bram Moolenaar62aec932022-01-29 21:45:34 +00001348 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001349 lines =<< trim END
1350 vim9script
1351 def g:Func(): string
1352 return 'global'
1353 enddef
1354 def AnotherFunc(): string
1355 return Func()
1356 enddef
1357 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001358 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001359 v9.CheckScriptFailure(lines, 'E117:')
1360 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001361
1362 lines =<< trim END
1363 vim9script
1364 def g:Func(): string
1365 return 'global'
1366 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001367 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001368 delfunc g:Func
1369 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001370 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001371
1372 # This does not shadow "i" which is visible only inside the for loop
1373 lines =<< trim END
1374 vim9script
1375
1376 def Foo(i: number)
1377 echo i
1378 enddef
1379
1380 for i in range(3)
1381 # Foo() is compiled here
1382 Foo(i)
1383 endfor
1384 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001385 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001386enddef
1387
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001388func TakesOneArg(arg)
1389 echo a:arg
1390endfunc
1391
1392def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001393 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1394 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1395 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1396 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001397
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001398 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001399 vim9script
1400 def Func(s: string)
1401 echo s
1402 enddef
1403 Func([])
1404 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01001405 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<any>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001406
Bram Moolenaar9a015112021-12-31 14:06:45 +00001407 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001408 lines =<< trim END
1409 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001410 var name = 'piet'
1411 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001412 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001413 enddef
1414 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001415 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001416
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001417 # same, inside the same block
1418 lines =<< trim END
1419 vim9script
1420 if true
1421 var name = 'piet'
1422 def FuncOne(name: string)
1423 echo name
1424 enddef
1425 endif
1426 END
1427 v9.CheckScriptFailure(lines, 'E1168:')
1428
1429 # variable in other block is OK
1430 lines =<< trim END
1431 vim9script
1432 if true
1433 var name = 'piet'
1434 endif
1435 def FuncOne(name: string)
1436 echo name
1437 enddef
1438 END
1439 v9.CheckScriptSuccess(lines)
1440
Bram Moolenaardce24412022-02-08 20:35:30 +00001441 # with another variable in another block
1442 lines =<< trim END
1443 vim9script
1444 if true
1445 var name = 'piet'
1446 # define a function so that the variable isn't cleared
1447 def GetItem(): string
1448 return item
1449 enddef
1450 endif
1451 if true
1452 var name = 'peter'
1453 def FuncOne(name: string)
1454 echo name
1455 enddef
1456 endif
1457 END
1458 v9.CheckScriptFailure(lines, 'E1168:')
1459
1460 # only variable in another block is OK
1461 lines =<< trim END
1462 vim9script
1463 if true
1464 var name = 'piet'
1465 # define a function so that the variable isn't cleared
1466 def GetItem(): string
1467 return item
1468 enddef
1469 endif
1470 if true
1471 def FuncOne(name: string)
1472 echo name
1473 enddef
1474 endif
1475 END
1476 v9.CheckScriptSuccess(lines)
1477
Bram Moolenaar9a015112021-12-31 14:06:45 +00001478 # argument name declared later is only found when compiling
1479 lines =<< trim END
1480 vim9script
1481 def FuncOne(name: string)
1482 echo nr
1483 enddef
1484 var name = 'piet'
1485 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001486 v9.CheckScriptSuccess(lines)
1487 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001488
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001489 lines =<< trim END
1490 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001491 def FuncOne(nr: number)
1492 echo nr
1493 enddef
1494 def FuncTwo()
1495 FuncOne()
1496 enddef
1497 defcompile
1498 END
1499 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001500 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001501 try
1502 source Xscript
1503 catch
1504 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1505 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1506 didCatch = true
1507 endtry
1508 assert_true(didCatch)
1509
1510 lines =<< trim END
1511 vim9script
1512 def FuncOne(nr: number)
1513 echo nr
1514 enddef
1515 def FuncTwo()
1516 FuncOne(1, 2)
1517 enddef
1518 defcompile
1519 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001520 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001521 didCatch = false
1522 try
1523 source Xscript
1524 catch
1525 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1526 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1527 didCatch = true
1528 endtry
1529 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001530enddef
1531
Bram Moolenaar50824712020-12-20 21:10:17 +01001532def Test_call_funcref_wrong_args()
1533 var head =<< trim END
1534 vim9script
1535 def Func3(a1: string, a2: number, a3: list<number>)
1536 echo a1 .. a2 .. a3[0]
1537 enddef
1538 def Testme()
1539 var funcMap: dict<func> = {func: Func3}
1540 END
1541 var tail =<< trim END
1542 enddef
1543 Testme()
1544 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001545 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001546
Bram Moolenaar62aec932022-01-29 21:45:34 +00001547 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1548 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001549
1550 var lines =<< trim END
1551 vim9script
1552 var Ref: func(number): any
1553 Ref = (j) => !j
1554 echo Ref(false)
1555 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001556 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001557
1558 lines =<< trim END
1559 vim9script
1560 var Ref: func(number): any
1561 Ref = (j) => !j
1562 call Ref(false)
1563 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001564 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001565enddef
1566
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001567def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001568 var lines =<< trim END
1569 var Callback = (..._) => 'anything'
1570 assert_equal('anything', Callback())
1571 assert_equal('anything', Callback(1))
1572 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001573
1574 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001575 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001576 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001577
Bram Moolenaar62aec932022-01-29 21:45:34 +00001578 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001579 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001580
Bram Moolenaar2a389082021-04-09 20:24:31 +02001581 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001582 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001583 echo Ref(1, 'x')
1584 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001585 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001586
1587 lines =<< trim END
1588 var Ref: func(job, string, number)
1589 Ref = (x, y) => 0
1590 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001591 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001592
1593 lines =<< trim END
1594 var Ref: func(job, string)
1595 Ref = (x, y, z) => 0
1596 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001597 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001598
1599 lines =<< trim END
1600 var one = 1
1601 var l = [1, 2, 3]
1602 echo map(l, (one) => one)
1603 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001604 v9.CheckDefFailure(lines, 'E1167:')
1605 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001606
1607 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001608 var Ref: func(any, ?any): bool
1609 Ref = (_, y = 1) => false
1610 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001611 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001612
1613 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001614 var a = 0
1615 var b = (a == 0 ? 1 : 2)
1616 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001617 var txt = 'a'
1618 b = (txt =~ 'x' ? 1 : 2)
1619 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001620 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001621 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001622
1623 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001624 def ShadowLocal()
1625 var one = 1
1626 var l = [1, 2, 3]
1627 echo map(l, (one) => one)
1628 enddef
1629 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001630 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001631
1632 lines =<< trim END
1633 def Shadowarg(one: number)
1634 var l = [1, 2, 3]
1635 echo map(l, (one) => one)
1636 enddef
1637 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001638 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001639
1640 lines =<< trim END
1641 echo ((a) => a)('aa', 'bb')
1642 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001643 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001644
1645 lines =<< trim END
1646 echo 'aa'->((a) => a)('bb')
1647 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001648 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1649 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001650enddef
1651
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001652def Test_lambda_line_nr()
1653 var lines =<< trim END
1654 vim9script
1655 # comment
1656 # comment
1657 var id = timer_start(1'000, (_) => 0)
1658 var out = execute('verbose ' .. timer_info(id)[0].callback
1659 ->string()
1660 ->substitute("('\\|')", ' ', 'g'))
1661 assert_match('Last set from .* line 4', out)
1662 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001663 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001664enddef
1665
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001666def FilterWithCond(x: string, Cond: func(string): bool): bool
1667 return Cond(x)
1668enddef
1669
Bram Moolenaar0346b792021-01-31 22:18:29 +01001670def Test_lambda_return_type()
1671 var lines =<< trim END
1672 var Ref = (): => 123
1673 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001674 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001675
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001676 # no space before the return type
1677 lines =<< trim END
1678 var Ref = (x):number => x + 1
1679 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001680 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001681
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001682 # this works
1683 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001684 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001685 endfor
1686
1687 # this fails
1688 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001689 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001690 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001691 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 +02001692
1693 lines =<< trim END
1694 var Lambda1 = (x) => {
1695 return x
1696 }
1697 assert_equal('asdf', Lambda1('asdf'))
1698 var Lambda2 = (x): string => {
1699 return x
1700 }
1701 assert_equal('foo', Lambda2('foo'))
1702 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001703 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001704
1705 lines =<< trim END
1706 var Lambda = (x): string => {
1707 return x
1708 }
1709 echo Lambda(['foo'])
1710 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001711 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001712enddef
1713
Bram Moolenaar709664c2020-12-12 14:33:41 +01001714def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001715 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001716 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001717 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001718enddef
1719
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001720def Test_lambda_invalid_block()
1721 var lines =<< trim END
1722 timer_start(0, (_) => { # echo
1723 echo 'yes'
1724 })
1725 END
1726 v9.CheckDefAndScriptSuccess(lines)
1727
1728 lines =<< trim END
1729 timer_start(0, (_) => { " echo
1730 echo 'yes'
1731 })
1732 END
1733 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1734
1735 lines =<< trim END
1736 timer_start(0, (_) => { | echo
1737 echo 'yes'
1738 })
1739 END
1740 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1741enddef
1742
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001743def Test_lambda_with_following_cmd()
1744 var lines =<< trim END
1745 set ts=2
1746 var Lambda = () => {
1747 set ts=4
1748 } | set ts=3
1749 assert_equal(3, &ts)
1750 Lambda()
1751 assert_equal(4, &ts)
1752 END
1753 v9.CheckDefAndScriptSuccess(lines)
1754 set ts=8
1755enddef
1756
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001757def Test_pass_legacy_lambda_to_def_func()
1758 var lines =<< trim END
1759 vim9script
1760 func Foo()
1761 eval s:Bar({x -> 0})
1762 endfunc
1763 def Bar(y: any)
1764 enddef
1765 Foo()
1766 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001767 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001768
1769 lines =<< trim END
1770 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001771 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001772 enddef
1773 legacy call g:TestFunc({-> 0})
1774 delfunc g:TestFunc
1775
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001776 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001777 enddef
1778 legacy call g:TestFunc({nr -> 0})
1779 delfunc g:TestFunc
1780 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001781 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001782enddef
1783
Bram Moolenaar844fb642021-10-23 13:32:30 +01001784def Test_lambda_in_reduce_line_break()
1785 # this was using freed memory
1786 var lines =<< trim END
1787 vim9script
1788 const result: dict<number> =
1789 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1790 ->reduce((acc, val) => {
1791 if has_key(acc, val)
1792 acc[val] += 1
1793 return acc
1794 else
1795 acc[val] = 1
1796 return acc
1797 endif
1798 }, {})
1799 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1800 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001801 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001802enddef
1803
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001804def Test_set_opfunc_to_lambda()
1805 var lines =<< trim END
1806 vim9script
1807 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1808 def CountSpaces(type = ''): string
1809 if type == ''
1810 &operatorfunc = (t) => CountSpaces(t)
1811 return 'g@'
1812 endif
1813 normal! '[V']y
1814 g:result = getreg('"')->count(' ')
1815 return ''
1816 enddef
1817 new
1818 'a b c d e'->setline(1)
1819 feedkeys("\<F4>", 'x')
1820 assert_equal(4, g:result)
1821 bwipe!
1822 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001823 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001824enddef
1825
Bram Moolenaaref082e12021-12-12 21:02:03 +00001826def Test_set_opfunc_to_global_function()
1827 var lines =<< trim END
1828 vim9script
1829 def g:CountSpaces(type = ''): string
1830 normal! '[V']y
1831 g:result = getreg('"')->count(' ')
1832 return ''
1833 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001834 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001835 &operatorfunc = g:CountSpaces
1836 new
1837 'a b c d e'->setline(1)
1838 feedkeys("g@_", 'x')
1839 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001840
1841 &operatorfunc = ''
1842 g:result = 0
1843 # global function works in :def function
1844 def Func()
1845 &operatorfunc = g:CountSpaces
1846 enddef
1847 Func()
1848 feedkeys("g@_", 'x')
1849 assert_equal(4, g:result)
1850
Bram Moolenaaref082e12021-12-12 21:02:03 +00001851 bwipe!
1852 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001853 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001854 &operatorfunc = ''
1855enddef
1856
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001857def Test_use_script_func_name_with_prefix()
1858 var lines =<< trim END
1859 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001860 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001861 return 'it'
1862 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001863 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001864 assert_equal('it', Fn())
1865 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001866 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001867enddef
1868
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001869def Test_lambda_type_allocated()
1870 # Check that unreferencing a partial using a lambda can use the variable type
1871 # after the lambda has been freed and does not leak memory.
1872 var lines =<< trim END
1873 vim9script
1874
1875 func MyomniFunc1(val, findstart, base)
1876 return a:findstart ? 0 : []
1877 endfunc
1878
1879 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1880 &omnifunc = Lambda
1881 Lambda = (a, b) => MyomniFunc1(20, a, b)
1882 &omnifunc = string(Lambda)
1883 Lambda = (a, b) => strlen(a)
1884 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001885 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001886enddef
1887
Bram Moolenaara7583c42022-05-07 21:14:05 +01001888def Test_define_lambda_in_execute()
1889 var lines =<< trim [CODE]
1890 vim9script
1891
1892 def BuildFuncMultiLine(): func
1893 var x =<< trim END
1894 g:SomeRandomFunc = (d: dict<any>) => {
1895 return d.k1 + d.k2
1896 }
1897 END
1898 execute(x)
1899 return g:SomeRandomFunc
1900 enddef
1901 var ResultPlus = BuildFuncMultiLine()
1902 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1903 [CODE]
1904 v9.CheckScriptSuccess(lines)
1905 unlet g:SomeRandomFunc
1906enddef
1907
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001908" Default arg and varargs
1909def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001910 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001911 for s in rest
1912 res ..= ',' .. s
1913 endfor
1914 return res
1915enddef
1916
1917def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001918 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1919 g:MyDefVarargs('one')->assert_equal('one,foo')
1920 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1921 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1922 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001923 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001924 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001925 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001926
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001927 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001928 vim9script
1929 def Func(...l: list<string>)
1930 echo l
1931 enddef
1932 Func('a', 'b', 'c')
1933 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001934 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001935
1936 lines =<< trim END
1937 vim9script
1938 def Func(...l: list<string>)
1939 echo l
1940 enddef
1941 Func()
1942 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001943 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001944
1945 lines =<< trim END
1946 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001947 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001948 echo l
1949 enddef
1950 Func(0)
1951 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001952 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001953
1954 lines =<< trim END
1955 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001956 def Func(...l: any)
1957 echo l
1958 enddef
1959 Func(0)
1960 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001961 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001962
1963 lines =<< trim END
1964 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001965 def Func(..._l: list<string>)
1966 echo _l
1967 enddef
1968 Func('a', 'b', 'c')
1969 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001970 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001971
1972 lines =<< trim END
1973 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001974 def Func(...l: list<string>)
1975 echo l
1976 enddef
1977 Func(1, 2, 3)
1978 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001979 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001980
1981 lines =<< trim END
1982 vim9script
1983 def Func(...l: list<string>)
1984 echo l
1985 enddef
1986 Func('a', 9)
1987 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001988 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001989
1990 lines =<< trim END
1991 vim9script
1992 def Func(...l: list<string>)
1993 echo l
1994 enddef
1995 Func(1, 'a')
1996 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001997 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001998
1999 lines =<< trim END
2000 vim9script
2001 def Func( # some comment
2002 ...l = []
2003 )
2004 echo l
2005 enddef
2006 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002007 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02002008
2009 lines =<< trim END
2010 vim9script
2011 def DoIt()
2012 g:Later('')
2013 enddef
2014 defcompile
2015 def g:Later(...l: list<number>)
2016 enddef
2017 DoIt()
2018 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002019 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002020enddef
2021
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002022let s:value = ''
2023
2024def FuncOneDefArg(opt = 'text')
2025 s:value = opt
2026enddef
2027
2028def FuncTwoDefArg(nr = 123, opt = 'text'): string
2029 return nr .. opt
2030enddef
2031
2032def FuncVarargs(...arg: list<string>): string
2033 return join(arg, ',')
2034enddef
2035
2036def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002037 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002038 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002039 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002040 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002041 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002042 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002043
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002044 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002045 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002046 RefDef2Arg()->assert_equal('123text')
2047 RefDef2Arg(99)->assert_equal('99text')
2048 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002049
Bram Moolenaar62aec932022-01-29 21:45:34 +00002050 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
2051 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002052
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002053 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002054 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002055 RefVarargs()->assert_equal('')
2056 RefVarargs('one')->assert_equal('one')
2057 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002058
Bram Moolenaar62aec932022-01-29 21:45:34 +00002059 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
2060 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002061enddef
2062
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002063" Only varargs
2064def MyVarargsOnly(...args: list<string>): string
2065 return join(args, ',')
2066enddef
2067
2068def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002069 g:MyVarargsOnly()->assert_equal('')
2070 g:MyVarargsOnly('one')->assert_equal('one')
2071 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
2072 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
2073 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002074enddef
2075
Bram Moolenaar36818a92023-01-03 12:33:26 +00002076def Test_varargs_mismatch()
2077 var lines =<< trim END
2078 vim9script
2079
2080 def Map(Fn: func(...any): number): number
2081 return Fn('12')
2082 enddef
2083
2084 var res = Map((v) => str2nr(v))
2085 assert_equal(12, res)
2086 END
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002087 v9.CheckScriptFailure(lines, 'E1180: Variable arguments type must be a list: any')
Bram Moolenaar36818a92023-01-03 12:33:26 +00002088enddef
2089
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002090def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00002091 var lines =<< trim END
2092 def Func(x: number)
2093 var x = 234
2094 enddef
2095 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002096 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002097
2098 lines =<< trim END
2099 def Func(Ref: number)
2100 def Ref()
2101 enddef
2102 enddef
2103 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002104 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002105enddef
2106
Bram Moolenaar62aec932022-01-29 21:45:34 +00002107def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002108 arg['key'] = 'value'
2109enddef
2110
Bram Moolenaar62aec932022-01-29 21:45:34 +00002111def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002112 arg[0] = 'value'
2113enddef
2114
2115def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002116 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002117 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002118 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002119 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002120 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002121 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002122 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002123
Bram Moolenaar62aec932022-01-29 21:45:34 +00002124 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002125 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002126enddef
2127
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002128" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002129def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002130 return firstline .. lastline
2131enddef
2132
2133def Test_argument_names()
2134 assert_equal('OK', WithReservedNames('O', 'K'))
2135enddef
2136
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002137def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002138 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002139 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002140enddef
2141
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002142func DefinedLater(arg)
2143 return a:arg
2144endfunc
2145
2146def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002147 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002148 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002149 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002150
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002151 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002152 vim9script
2153 def RetNumber(): number
2154 return 123
2155 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002156 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002157 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002158 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002159 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002160
2161 lines =<< trim END
2162 vim9script
2163 def RetNumber(): number
2164 return 123
2165 enddef
2166 def Bar(F: func: number): number
2167 return F()
2168 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002169 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002170 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002171 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002172 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002173
2174 lines =<< trim END
2175 vim9script
2176 def UseNumber(nr: number)
2177 echo nr
2178 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002179 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002180 Funcref(123)
2181 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002182 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002183
2184 lines =<< trim END
2185 vim9script
2186 def UseNumber(nr: number)
2187 echo nr
2188 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002189 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002190 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002191 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002192
2193 lines =<< trim END
2194 vim9script
2195 def EchoNr(nr = 34)
2196 g:echo = nr
2197 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002198 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002199 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002200 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002201 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002202 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002203 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002204 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002205
2206 lines =<< trim END
2207 vim9script
2208 def EchoList(...l: list<number>)
2209 g:echo = l
2210 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002211 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002212 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002213 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002214 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002215 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002216 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002217 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002218
2219 lines =<< trim END
2220 vim9script
2221 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2222 g:optarg = opt
2223 g:listarg = l
2224 return nr
2225 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002226 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002227 Funcref(10)->assert_equal(10)
2228 g:optarg->assert_equal(12)
2229 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002230
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002231 Funcref(11, 22)->assert_equal(11)
2232 g:optarg->assert_equal(22)
2233 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002234
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002235 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2236 g:optarg->assert_equal(18)
2237 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002238 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002239 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002240
2241 lines =<< trim END
2242 function s:func(num)
2243 return a:num * 2
2244 endfunction
2245
2246 def s:CallFuncref()
2247 var Funcref = function('s:func')
2248 Funcref(3)->assert_equal(6)
2249 enddef
2250 call s:CallFuncref()
2251 END
2252 v9.CheckScriptSuccess(lines)
2253
2254 lines =<< trim END
2255 function s:func(num)
2256 return a:num * 2
2257 endfunction
2258
2259 def s:CallFuncref()
2260 var Funcref = function(s:func)
2261 Funcref(3)->assert_equal(6)
2262 enddef
2263 call s:CallFuncref()
2264 END
2265 v9.CheckScriptSuccess(lines)
2266
2267 lines =<< trim END
2268 function s:func(num)
2269 return a:num * 2
2270 endfunction
2271
2272 def s:CallFuncref()
2273 var Funcref = s:func
2274 Funcref(3)->assert_equal(6)
2275 enddef
2276 call s:CallFuncref()
2277 END
2278 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002279enddef
2280
2281let SomeFunc = function('len')
2282let NotAFunc = 'text'
2283
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002284def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002285 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002286 var Ref1: func(bool): string
2287 var Ref2: func(bool): number
2288 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002289 Ref3 = g:cond ? Ref1 : Ref2
2290
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002291 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002292 var Refa1: func(bool): number
2293 var Refa2: func(bool, number): number
2294 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002295 Refa3 = g:cond ? Refa1 : Refa2
2296
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002297 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002298 var Refb1: func(bool, string): number
2299 var Refb2: func(string, number): number
2300 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002301 Refb3 = g:cond ? Refb1 : Refb2
2302enddef
2303
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002304def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002305 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002306enddef
2307
2308def DefinedEvenLater(arg: string): string
2309 return arg
2310enddef
2311
2312def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002313 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002314 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002315enddef
2316
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002317def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002318 var lines =<< trim END
2319 vim9script
2320 # Define an outer function
2321 def FirstFunction()
2322 # Define an inner function
2323 def SecondFunction()
2324 # the function has a body, a double free is detected.
2325 AAAAA
2326
2327 # enddef followed by | or } followed by # one or more characters
2328 enddef|BBBB
2329 enddef
2330
2331 # Compile all functions
2332 defcompile
2333 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002334 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002335enddef
2336
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002337def Test_nested_function_with_args_split()
2338 var lines =<< trim END
2339 vim9script
2340 def FirstFunction()
2341 def SecondFunction(
2342 )
2343 # had a double free if the right parenthesis of the nested function is
2344 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002345
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002346 enddef|BBBB
2347 enddef
2348 # Compile all functions
2349 defcompile
2350 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002351 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002352
2353 lines =<< trim END
2354 vim9script
2355 def FirstFunction()
2356 func SecondFunction()
2357 endfunc|BBBB
2358 enddef
2359 defcompile
2360 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002361 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002362enddef
2363
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002364def Test_error_in_function_args()
2365 var lines =<< trim END
2366 def FirstFunction()
2367 def SecondFunction(J =
2368 # Nois
2369 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002370
2371 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002372 enddef
2373 # Compile all functions
2374 defcompile
2375 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002376 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002377enddef
2378
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002379def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002380 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002381 'def Func(): number',
2382 'return "a"',
2383 'enddef',
2384 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002385 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002386 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002387 'def Func(): string',
2388 'return 1',
2389 'enddef',
2390 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002391 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002392 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002393 'def Func(): void',
2394 'return "a"',
2395 'enddef',
2396 'defcompile'],
2397 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002398 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002399 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002400 'def Func()',
2401 'return "a"',
2402 'enddef',
2403 'defcompile'],
2404 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002405 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002406
Bram Moolenaar62aec932022-01-29 21:45:34 +00002407 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002408 'def Func(): number',
2409 'return',
2410 'enddef',
2411 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002412 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002413
Bram Moolenaar62aec932022-01-29 21:45:34 +00002414 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002415 'def Func():number',
2416 'return 123',
2417 'enddef',
2418 'defcompile'], 'E1069:')
2419 delfunc! g:Func
2420
Bram Moolenaar62aec932022-01-29 21:45:34 +00002421 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002422 'def Func() :number',
2423 'return 123',
2424 'enddef',
2425 'defcompile'], 'E1059:')
2426 delfunc! g:Func
2427
Bram Moolenaar62aec932022-01-29 21:45:34 +00002428 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002429 'def Func() : number',
2430 'return 123',
2431 'enddef',
2432 'defcompile'], 'E1059:')
2433 delfunc! g:Func
2434
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002435 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002436 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002437 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002438 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002439 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002440 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002441
Bram Moolenaar62aec932022-01-29 21:45:34 +00002442 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002443 'vim9script',
2444 'def FuncB()',
2445 ' return 123',
2446 'enddef',
2447 'def FuncA()',
2448 ' FuncB()',
2449 'enddef',
2450 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002451enddef
2452
2453def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002454 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002455 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2456 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2457 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2458 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2459 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002460enddef
2461
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002462def Test_white_space_before_comma()
2463 var lines =<< trim END
2464 vim9script
2465 def Func(a: number , b: number)
2466 enddef
2467 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002468 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002469 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002470enddef
2471
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002472def Test_white_space_after_comma()
2473 var lines =<< trim END
2474 vim9script
2475 def Func(a: number,b: number)
2476 enddef
2477 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002478 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002479
2480 # OK in legacy function
2481 lines =<< trim END
2482 vim9script
2483 func Func(a,b)
2484 endfunc
2485 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002486 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002487enddef
2488
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002489def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002490 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002491 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002492 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002493 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002494 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002495 enddef
2496 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002497 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002498
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002499 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002500 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002501 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002502
Bram Moolenaar67979662020-06-20 22:50:47 +02002503 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002504 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002505 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002506
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002507 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002508 def ListFunc(arg: list<number>)
2509 listvar = arg
2510 enddef
2511 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002512 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002513
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002514 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002515 def DictFunc(arg: dict<number>)
2516 dictvar = arg
2517 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002518 {a: 1, b: 2}->DictFunc()
2519 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002520 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002521 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002522 enddef
2523 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002524 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002525
Bram Moolenaare0de1712020-12-02 17:36:54 +01002526 {a: 3, b: 4}->DictFunc()
2527 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002528
2529 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002530 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002531 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002532 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002533
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002534 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002535 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002536 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002537 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002538 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002539 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002540
2541 def UseString()
2542 'xyork'->MyFunc()
2543 enddef
2544 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002545 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002546
Bram Moolenaar10409562020-07-29 20:00:38 +02002547 def UseString2()
2548 "knife"->MyFunc()
2549 enddef
2550 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002551 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002552
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002553 # prepending a colon makes it a mark
2554 new
2555 setline(1, ['aaa', 'bbb', 'ccc'])
2556 normal! 3Gmt1G
2557 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002558 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002559 bwipe!
2560
Bram Moolenaare6b53242020-07-01 17:28:33 +02002561 MyFunc(
2562 'continued'
2563 )
2564 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002565 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002566 )
2567
2568 call MyFunc(
2569 'more'
2570 ..
2571 'lines'
2572 )
2573 assert_equal(
2574 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002575 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002576 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002577 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002578 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002579enddef
2580
2581def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002582 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002583 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002584 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002585 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002586 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002587 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002588 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002589 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002590 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002591enddef
2592
Bram Moolenaar65b95452020-07-19 14:03:09 +02002593def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002594 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002595 vim9script
2596 def MyFunc(arg: string)
2597 echo arg
2598 enddef
2599 MyFunc(1234)
2600 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002601 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002602enddef
2603
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002604def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002605 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002606 vim9script
2607 const var = ''
2608 def MyFunc(arg: string)
2609 var = 'asdf'
2610 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002611 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002612 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002613 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002614 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002615
2616 lines =<< trim END
2617 const g:Aconst = 77
2618 def Change()
2619 # comment
2620 g:Aconst = 99
2621 enddef
2622 call Change()
2623 unlet g:Aconst
2624 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002625 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002626enddef
2627
2628" Test that inside :function a Python function can be defined, :def is not
2629" recognized.
2630func Test_function_python()
2631 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002632 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002633 execute py "<< EOF"
2634def do_something():
2635 return 1
2636EOF
2637endfunc
2638
2639def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002640 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002641 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002642 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002643 echo 'hello'
2644 enddef
2645
2646 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002647 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002648 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002649 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002650
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002651 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002652 CallGoneSoon()
2653 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002654 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002655 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2656 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002657enddef
2658
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002659func Test_free_dict_while_in_funcstack()
2660 " relies on the sleep command
2661 CheckUnix
2662 call Run_Test_free_dict_while_in_funcstack()
2663endfunc
2664
2665def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002666 # this was freeing the TermRun() default argument dictionary while it was
2667 # still referenced in a funcstack_T
2668 var lines =<< trim END
2669 vim9script
2670
2671 &updatetime = 400
2672 def TermRun(_ = {})
2673 def Post()
2674 enddef
2675 def Exec()
2676 term_start('sleep 1', {
2677 term_finish: 'close',
2678 exit_cb: (_, _) => Post(),
2679 })
2680 enddef
2681 Exec()
2682 enddef
2683 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2684 timer_start(100, (_) => feedkeys("\<F4>"))
2685 timer_start(1000, (_) => feedkeys("\<F4>"))
2686 sleep 1500m
2687 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002688 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002689 nunmap <F4>
2690 set updatetime&
2691enddef
2692
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002693def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002694 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002695 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002696 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002697 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002698 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002699 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002700 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002701 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002702 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002703
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002704 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002705 g:Func1()->assert_equal('Func1')
2706 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002707
2708 delfunc! Func0
2709 delfunc! Func1
2710 delfunc! Func2
2711enddef
2712
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002713def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002714 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002715 vim9script
2716 func Func(arg)
2717 echo a:arg
2718 endfunc
2719 Func('text')
2720 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002721 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002722 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002723enddef
2724
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002725let s:funcResult = 0
2726
2727def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002728 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002729enddef
2730
2731def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002732 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002733 return 1234
2734enddef
2735
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002736def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002737 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002738 return 'text'
2739enddef
2740
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002741def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002742 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002743enddef
2744
2745def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002746 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002747 return arg
2748enddef
2749
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002750def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002751 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002752enddef
2753
Bram Moolenaar62aec932022-01-29 21:45:34 +00002754def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002755 return arg
2756enddef
2757
Bram Moolenaar62aec932022-01-29 21:45:34 +00002758def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002759 return arg
2760enddef
2761
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002762def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002763 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002764 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002765 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002766 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002767 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002768
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002769 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002770 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002771 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002772 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002773 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002774
Bram Moolenaar53900992020-08-22 19:02:02 +02002775 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002776 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002777 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002778 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002779
Bram Moolenaar53900992020-08-22 19:02:02 +02002780 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002781 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002782 Ref2()->assert_equal(1234)
2783 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002784
Bram Moolenaar53900992020-08-22 19:02:02 +02002785 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002786 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002787 Ref2(13)->assert_equal(13)
2788 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002789enddef
2790
Bram Moolenaar9978d472020-07-05 16:01:56 +02002791def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002792 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002793 for n in repeat([1], 3)
2794 res += n
2795 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002796 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002797
2798 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002799 for n in repeat(0z01, 3)->blob2list()
2800 res += n
2801 endfor
2802 res->assert_equal(3)
2803
2804 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002805 for n in add([1, 2], 3)
2806 res += n
2807 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002808 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002809enddef
2810
Bram Moolenaar846178a2020-07-05 17:04:13 +02002811def Test_argv_return_type()
2812 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002813 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002814 for name in argv()
2815 res ..= name
2816 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002817 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002818enddef
2819
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002820def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002821 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002822 RefVoid = g:FuncNoArgNoRet
2823 RefVoid = g:FuncOneArgNoRet
2824 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 +00002825 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 +02002826
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002827 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002828 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002829 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002830 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2831 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 +02002832
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002833 var RefAnyNoArgs: func: any = RefAny
2834
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002835 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002836 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002837 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002838 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 +00002839 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 +02002840
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002841 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002842 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002843 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002844 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2845 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 +02002846enddef
2847
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002848def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002849 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002850
Bram Moolenaar62aec932022-01-29 21:45:34 +00002851 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2852 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002853 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 +00002854 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2855 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 +02002856 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 +02002857
Bram Moolenaar62aec932022-01-29 21:45:34 +00002858 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2859 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2860 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:')
2861 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002862enddef
2863
Bram Moolenaar89228602020-04-05 22:14:54 +02002864def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002865 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002866 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002867 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002868
2869 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002870 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002871
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002872 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002873 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002874 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002875
Bram Moolenaar62aec932022-01-29 21:45:34 +00002876 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002877enddef
2878
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002879def Test_func_common_type()
2880 def FuncOne(n: number): number
2881 return n
2882 enddef
2883 def FuncTwo(s: string): number
2884 return len(s)
2885 enddef
2886 def FuncThree(n: number, s: string): number
2887 return n + len(s)
2888 enddef
2889 var list = [FuncOne, FuncTwo, FuncThree]
2890 assert_equal(8, list[0](8))
2891 assert_equal(4, list[1]('word'))
2892 assert_equal(7, list[2](3, 'word'))
2893enddef
2894
Bram Moolenaar62aec932022-01-29 21:45:34 +00002895def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002896 arg1: string,
2897 arg2 = 1234,
2898 ...rest: list<string>
2899 ): string
2900 return arg1 .. arg2 .. join(rest, '-')
2901enddef
2902
Bram Moolenaar2c330432020-04-13 14:41:35 +02002903def MultiLineComment(
2904 arg1: string, # comment
2905 arg2 = 1234, # comment
2906 ...rest: list<string> # comment
2907 ): string # comment
2908 return arg1 .. arg2 .. join(rest, '-')
2909enddef
2910
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002911def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002912 MultiLine('text')->assert_equal('text1234')
2913 MultiLine('text', 777)->assert_equal('text777')
2914 MultiLine('text', 777, 'one')->assert_equal('text777one')
2915 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002916enddef
2917
Bram Moolenaar23e03252020-04-12 22:22:31 +02002918func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002919 call s:MultiLine('text')->assert_equal('text1234')
2920 call s:MultiLine('text', 777)->assert_equal('text777')
2921 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2922 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002923endfunc
2924
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002925
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002926" When using CheckScriptFailure() for the below test, E1010 is generated instead
2927" of E1056.
2928func Test_E1056_1059()
2929 let caught_1056 = 0
2930 try
2931 def F():
2932 return 1
2933 enddef
2934 catch /E1056:/
2935 let caught_1056 = 1
2936 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002937 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002938
2939 let caught_1059 = 0
2940 try
2941 def F5(items : list)
2942 echo 'a'
2943 enddef
2944 catch /E1059:/
2945 let caught_1059 = 1
2946 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002947 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002948endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002949
Bram Moolenaar015f4262020-05-05 21:25:22 +02002950func DelMe()
2951 echo 'DelMe'
2952endfunc
2953
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002954def Test_error_reporting()
2955 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002956 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002957 " comment
2958 def Func()
2959 # comment
2960 # comment
2961 invalid
2962 enddef
2963 defcompile
2964 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002965 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002966 try
2967 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002968 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002969 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002970 v:exception->assert_match('Invalid command: invalid')
2971 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002972 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002973 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002974
2975 # comment lines after the start of the function
2976 lines =<< trim END
2977 " comment
2978 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002979 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002980 # comment
2981 # comment
2982 invalid
2983 enddef
2984 defcompile
2985 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002986 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002987 try
2988 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002989 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002990 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002991 v:exception->assert_match('Invalid command: invalid')
2992 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002993 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002994 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002995
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002996 lines =<< trim END
2997 vim9script
2998 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002999 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02003000 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003001 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02003002 enddef
3003 defcompile
3004 Func()
3005 END
Bram Moolenaar08052222020-09-14 17:04:31 +02003006 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02003007 try
3008 source Xdef
3009 assert_report('should have failed')
3010 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003011 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02003012 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003013 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02003014enddef
3015
Bram Moolenaar015f4262020-05-05 21:25:22 +02003016def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003017 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003018 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02003019 'delfunc g:DelMe',
3020 'echo RefMe()'], 'E117:')
3021enddef
3022
3023def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003024 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003025 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003026 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02003027enddef
3028
Bram Moolenaar62aec932022-01-29 21:45:34 +00003029def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02003030 return Ref('more')
3031enddef
3032
3033def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003034 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003035 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02003036enddef
3037
Bram Moolenaar62aec932022-01-29 21:45:34 +00003038def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003039 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003040 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003041enddef
3042
3043def Test_closure_ref_after_return()
3044 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003045 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003046 unlet g:Ref
3047enddef
3048
Bram Moolenaar62aec932022-01-29 21:45:34 +00003049def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003050 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003051 g:Extend = (s) => local->add(s)
3052 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003053enddef
3054
3055def Test_closure_two_refs()
3056 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003057 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003058 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003059 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003060 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003061 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003062
3063 unlet g:Extend
3064 unlet g:Read
3065enddef
3066
Bram Moolenaar62aec932022-01-29 21:45:34 +00003067def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003068 return join(Ref(), ' ')
3069enddef
3070
Bram Moolenaar62aec932022-01-29 21:45:34 +00003071def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003072 Ref(add)
3073enddef
3074
3075def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02003076 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003077 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003078 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003079 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003080 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003081 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003082
3083 unlet g:Extend
3084 unlet g:Read
3085enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003086
Bram Moolenaar62aec932022-01-29 21:45:34 +00003087def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003088 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003089 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003090enddef
3091
Bram Moolenaar62aec932022-01-29 21:45:34 +00003092def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003093 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003094 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003095enddef
3096
3097def Test_closure_using_argument()
3098 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003099 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003100
3101 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003102 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003103
3104 unlet g:UseArg
3105 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003106
3107 var lines =<< trim END
3108 vim9script
3109 def Test(Fun: func(number): number): list<number>
3110 return map([1, 2, 3], (_, i) => Fun(i))
3111 enddef
3112 def Inc(nr: number): number
3113 return nr + 2
3114 enddef
3115 assert_equal([3, 4, 5], Test(Inc))
3116 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003117 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003118enddef
3119
Bram Moolenaar62aec932022-01-29 21:45:34 +00003120def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003121 var local = 'a'
3122
3123 def Append(arg: string)
3124 local ..= arg
3125 enddef
3126 g:Append = Append
3127
3128 def Get(): string
3129 return local
3130 enddef
3131 g:Get = Get
3132enddef
3133
3134def Test_closure_append_get()
3135 MakeGetAndAppendRefs()
3136 g:Get()->assert_equal('a')
3137 g:Append('-b')
3138 g:Get()->assert_equal('a-b')
3139 g:Append('-c')
3140 g:Get()->assert_equal('a-b-c')
3141
3142 unlet g:Append
3143 unlet g:Get
3144enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003145
Bram Moolenaar04b12692020-05-04 23:24:44 +02003146def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003147 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003148 def Closure(arg: string): string
3149 return local .. arg
3150 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003151 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003152enddef
3153
Bram Moolenaar62aec932022-01-29 21:45:34 +00003154func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003155 return a:Ref('some')
3156endfunc
3157
3158def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003159 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003160 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003161 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003162enddef
3163
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003164def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003165 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003166 vim9script
3167 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003168 var name = 0
3169 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003170 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003171 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003172 enddef
3173 Func()
3174 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003175 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003176enddef
3177
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003178def Test_nested_closure_used()
3179 var lines =<< trim END
3180 vim9script
3181 def Func()
3182 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003183 var Closure = () => x
3184 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003185 enddef
3186 Func()
3187 assert_equal('hello', g:Myclosure())
3188 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003189 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003190enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003191
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003192def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003193 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003194 vim9script
3195 def FuncA()
3196 FuncB(0)
3197 enddef
3198 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003199 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003200 enddef
3201 FuncA()
3202 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003203 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003204enddef
3205
Bram Moolenaar6de22962022-09-09 21:35:36 +01003206def Run_Test_closure_in_for_loop_fails()
Drew Vogelea67ba72025-05-07 22:05:17 +02003207 CheckScreendump
Bram Moolenaar6de22962022-09-09 21:35:36 +01003208 var lines =<< trim END
3209 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003210 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003211 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003212 # time should be enough for startup to finish
3213 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003214 echo n
3215 })
3216 endfor
3217 END
3218 writefile(lines, 'XTest_closure_fails', 'D')
3219
3220 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003221 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003222 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003223
3224 # clean up
3225 g:StopVimInTerminal(buf)
3226enddef
3227
3228func Test_closure_in_for_loop_fails()
3229 CheckScreendump
3230 call Run_Test_closure_in_for_loop_fails()
3231endfunc
3232
Bram Moolenaarf112f302020-12-20 17:47:52 +01003233def Test_global_closure()
3234 var lines =<< trim END
3235 vim9script
3236 def ReverseEveryNLines(n: number, line1: number, line2: number)
3237 var mods = 'sil keepj keepp lockm '
3238 var range = ':' .. line1 .. ',' .. line2
3239 def g:Offset(): number
3240 var offset = (line('.') - line1 + 1) % n
3241 return offset != 0 ? offset : n
3242 enddef
3243 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3244 enddef
3245
3246 new
3247 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3248 ReverseEveryNLines(3, 1, 9)
3249 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003250 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003251 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3252 assert_equal(expected, getline(1, 9))
3253 bwipe!
3254enddef
3255
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003256def Test_global_closure_called_directly()
3257 var lines =<< trim END
3258 vim9script
3259 def Outer()
3260 var x = 1
3261 def g:Inner()
3262 var y = x
3263 x += 1
3264 assert_equal(1, y)
3265 enddef
3266 g:Inner()
3267 assert_equal(2, x)
3268 enddef
3269 Outer()
3270 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003271 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003272 delfunc g:Inner
3273enddef
3274
Bram Moolenaar69c76172021-12-02 16:38:52 +00003275def Test_closure_called_from_legacy()
3276 var lines =<< trim END
3277 vim9script
3278 def Func()
3279 var outer = 'foo'
3280 var F = () => {
3281 outer = 'bar'
3282 }
3283 execute printf('call %s()', string(F))
3284 enddef
3285 Func()
3286 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003287 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003288enddef
3289
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003290def Test_failure_in_called_function()
3291 # this was using the frame index as the return value
3292 var lines =<< trim END
3293 vim9script
3294 au TerminalWinOpen * eval [][0]
3295 def PopupTerm(a: any)
3296 # make sure typvals on stack are string
3297 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3298 FireEvent()
3299 enddef
3300 def FireEvent()
3301 do TerminalWinOpen
3302 enddef
3303 # use try/catch to make eval fail
3304 try
3305 call PopupTerm(0)
3306 catch
3307 endtry
3308 au! TerminalWinOpen
3309 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003310 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003311enddef
3312
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003313def Test_nested_lambda()
3314 var lines =<< trim END
3315 vim9script
3316 def Func()
3317 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003318 var Lambda1 = () => 7
3319 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003320 var res = Lambda2()
3321 assert_equal([7, 4], res)
3322 enddef
3323 Func()
3324 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003325 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003326enddef
3327
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003328def Test_double_nested_lambda()
3329 var lines =<< trim END
3330 vim9script
3331 def F(head: string): func(string): func(string): string
3332 return (sep: string): func(string): string => ((tail: string): string => {
3333 return head .. sep .. tail
3334 })
3335 enddef
3336 assert_equal('hello-there', F('hello')('-')('there'))
3337 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003338 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003339enddef
3340
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003341def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003342 var lines =<< trim END
3343 vim9script
3344 def F(text: string): func(string): func(string): string
3345 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003346 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003347 })
3348 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003349 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003350 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003351 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003352
3353 lines =<< trim END
3354 vim9script
3355 echo range(4)->mapnew((_, v) => {
3356 return range(v) ->mapnew((_, s) => {
3357 return string(s)
3358 })
3359 })
3360 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003361 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003362
3363 lines =<< trim END
3364 vim9script
3365
Bram Moolenaara749a422022-02-12 19:52:25 +00003366 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003367 range(10)
3368 ->mapnew((_, _) => ({
3369 key: range(10)->mapnew((_, _) => {
3370 return ' '
3371 }),
3372 }))
3373 enddef
3374
3375 defcomp
3376 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003377 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003378enddef
3379
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003380def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003381 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003382 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003383enddef
3384
3385def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003386 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003387enddef
3388
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003389def Test_compiling_referenced_func_no_shadow()
3390 var lines =<< trim END
3391 vim9script
3392
3393 def InitializeReply(lspserver: dict<any>)
3394 enddef
3395
3396 def ProcessReply(lspserver: dict<any>)
3397 var lsp_reply_handlers: dict<func> =
3398 { 'initialize': InitializeReply }
3399 lsp_reply_handlers['initialize'](lspserver)
3400 enddef
3401
3402 call ProcessReply({})
3403 END
3404 v9.CheckScriptSuccess(lines)
3405enddef
3406
Bram Moolenaar62aec932022-01-29 21:45:34 +00003407def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003408 var path: string = empty(dir)
3409 \ ? 'empty'
3410 \ : 'full'
3411 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003412enddef
3413
3414def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003415 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003416enddef
3417
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003418def Test_script_var_in_lambda()
3419 var lines =<< trim END
3420 vim9script
3421 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003422 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003423 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003424 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003425enddef
3426
Bram Moolenaar62aec932022-01-29 21:45:34 +00003427def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003428 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003429 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003430 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003431 ->reverse()
3432 return x
3433enddef
3434
3435def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003436 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003437
3438 var lines =<< trim END
3439 vim9script
3440 var res = [{n: 1, m: 2, s: 'xxx'}]
3441 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3442 v.n,
3443 v.m,
3444 substitute(v.s, '.*', 'yyy', '')
3445 ))
3446 assert_equal(['1:2:yyy'], res)
3447 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003448 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003449enddef
3450
Bram Moolenaarb6571982021-01-08 22:24:19 +01003451def Test_list_lambda()
3452 timer_start(1000, (_) => 0)
3453 var body = execute(timer_info()[0].callback
3454 ->string()
3455 ->substitute("('", ' ', '')
3456 ->substitute("')", '', '')
3457 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003458 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003459enddef
3460
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003461def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003462 var lines =<< trim END
3463 vim9script
3464 var flist: list<func>
3465 for i in range(10)
3466 var inloop = i
3467 flist[i] = () => inloop
3468 endfor
3469 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003470 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003471
3472 lines =<< trim END
3473 vim9script
3474 if true
3475 var outloop = 5
3476 var flist: list<func>
3477 for i in range(10)
3478 flist[i] = () => outloop
3479 endfor
3480 endif
3481 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003482 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003483
3484 lines =<< trim END
3485 vim9script
3486 if true
3487 var outloop = 5
3488 endif
3489 var flist: list<func>
3490 for i in range(10)
3491 flist[i] = () => outloop
3492 endfor
3493 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003494 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003495
3496 lines =<< trim END
3497 vim9script
3498 for i in range(10)
3499 var Ref = () => 0
3500 endfor
3501 assert_equal(0, ((i) => 0)(0))
3502 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003503 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003504enddef
3505
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003506def Test_legacy_lambda()
3507 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003508
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003509 var lines =<< trim END
3510 echo {x -> 'hello ' .. x}('foo')
3511 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003512 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003513
3514 lines =<< trim END
3515 vim9script
3516 def Func()
3517 echo (() => 'no error')()
3518 enddef
3519 legacy call s:Func()
3520 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003521 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003522enddef
3523
Bram Moolenaarce024c32021-06-26 13:00:49 +02003524def Test_legacy()
3525 var lines =<< trim END
3526 vim9script
3527 func g:LegacyFunction()
3528 let g:legacyvar = 1
3529 endfunc
3530 def Testit()
3531 legacy call g:LegacyFunction()
3532 enddef
3533 Testit()
3534 assert_equal(1, g:legacyvar)
3535 unlet g:legacyvar
3536 delfunc g:LegacyFunction
3537 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003538 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003539enddef
3540
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003541def Test_legacy_errors()
3542 for cmd in ['if', 'elseif', 'else', 'endif',
3543 'for', 'endfor', 'continue', 'break',
3544 'while', 'endwhile',
3545 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003546 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003547 endfor
3548enddef
3549
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003550def Test_call_legacy_with_dict()
3551 var lines =<< trim END
3552 vim9script
3553 func Legacy() dict
3554 let g:result = self.value
3555 endfunc
3556 def TestDirect()
3557 var d = {value: 'yes', func: Legacy}
3558 d.func()
3559 enddef
3560 TestDirect()
3561 assert_equal('yes', g:result)
3562 unlet g:result
3563
3564 def TestIndirect()
3565 var d = {value: 'foo', func: Legacy}
3566 var Fi = d.func
3567 Fi()
3568 enddef
3569 TestIndirect()
3570 assert_equal('foo', g:result)
3571 unlet g:result
3572
3573 var d = {value: 'bar', func: Legacy}
3574 d.func()
3575 assert_equal('bar', g:result)
3576 unlet g:result
3577 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003578 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003579enddef
3580
Bram Moolenaar62aec932022-01-29 21:45:34 +00003581def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003582 # closure nested inside another closure using argument
3583 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3584 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3585enddef
3586
3587def Test_nested_closure_using_argument()
3588 assert_equal(['x', 'x2'], DoFilterThis('x'))
3589enddef
3590
Bram Moolenaar0186e582021-01-10 18:33:11 +01003591def Test_triple_nested_closure()
3592 var what = 'x'
3593 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3594 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3595 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3596enddef
3597
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003598func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003599 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003600 call Run_Test_silent_echo()
3601endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003602
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003603def Run_Test_silent_echo()
Drew Vogelea67ba72025-05-07 22:05:17 +02003604 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003605 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003606 vim9script
3607 def EchoNothing()
3608 silent echo ''
3609 enddef
3610 defcompile
3611 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003612 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003613
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003614 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003615 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003616 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003617 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003618
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003619 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003620 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003621enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003622
Bram Moolenaar171fb922020-10-28 16:54:47 +01003623def SilentlyError()
3624 execute('silent! invalid')
3625 g:did_it = 'yes'
3626enddef
3627
Bram Moolenaar62aec932022-01-29 21:45:34 +00003628func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003629 silent! invalid
3630endfunc
3631
3632def SilentlyUserError()
3633 UserError()
3634 g:did_it = 'yes'
3635enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003636
3637" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003638func Test_ignore_silent_error()
3639 let g:did_it = 'no'
3640 call SilentlyError()
3641 call assert_equal('yes', g:did_it)
3642
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003643 let g:did_it = 'no'
3644 call SilentlyUserError()
3645 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003646
3647 unlet g:did_it
3648endfunc
3649
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003650def Test_ignore_silent_error_in_filter()
3651 var lines =<< trim END
3652 vim9script
3653 def Filter(winid: number, key: string): bool
3654 if key == 'o'
3655 silent! eval [][0]
3656 return true
3657 endif
3658 return popup_filter_menu(winid, key)
3659 enddef
3660
Bram Moolenaare0de1712020-12-02 17:36:54 +01003661 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003662 feedkeys("o\r", 'xnt')
3663 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003664 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003665enddef
3666
Bram Moolenaar62aec932022-01-29 21:45:34 +00003667def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003668 if n < 2
3669 return n
3670 else
3671 return Fibonacci(n - 1) + Fibonacci(n - 2)
3672 endif
3673enddef
3674
Bram Moolenaar985116a2020-07-12 17:31:09 +02003675def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003676 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003677enddef
3678
Bram Moolenaar62aec932022-01-29 21:45:34 +00003679def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003680 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003681 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003682 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003683 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003684 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003685enddef
3686
3687def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003688 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003689 writefile(['111'], 'XclosureDir/file1')
3690 writefile(['222'], 'XclosureDir/file2')
3691 writefile(['333'], 'XclosureDir/tdir/file3')
3692
Bram Moolenaare0de1712020-12-02 17:36:54 +01003693 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003694enddef
3695
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003696def Test_invalid_function_name()
3697 var lines =<< trim END
3698 vim9script
3699 def s: list<string>
3700 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003701 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003702
3703 lines =<< trim END
3704 vim9script
3705 def g: list<string>
3706 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003707 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003708
3709 lines =<< trim END
3710 vim9script
3711 def <SID>: list<string>
3712 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003713 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003714
3715 lines =<< trim END
3716 vim9script
3717 def F list<string>
3718 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003719 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003720enddef
3721
Bram Moolenaara90afb92020-07-15 22:38:56 +02003722def Test_partial_call()
John Marriott45377e22025-03-27 18:12:32 +01003723 CheckFeature quickfix
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003724 var lines =<< trim END
3725 var Xsetlist: func
3726 Xsetlist = function('setloclist', [0])
3727 Xsetlist([], ' ', {title: 'test'})
3728 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003729
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003730 Xsetlist = function('setloclist', [0, [], ' '])
3731 Xsetlist({title: 'test'})
3732 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003733
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003734 Xsetlist = function('setqflist')
3735 Xsetlist([], ' ', {title: 'test'})
3736 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003737
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003738 Xsetlist = function('setqflist', [[], ' '])
3739 Xsetlist({title: 'test'})
3740 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003741
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003742 var Len: func: number = function('len', ['word'])
3743 assert_equal(4, Len())
3744
3745 var RepeatFunc = function('repeat', ['o'])
3746 assert_equal('ooooo', RepeatFunc(5))
3747 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003748 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003749
3750 lines =<< trim END
3751 vim9script
3752 def Foo(Parser: any)
3753 enddef
3754 var Expr: func(dict<any>): dict<any>
3755 const Call = Foo(Expr)
3756 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003757 v9.CheckScriptFailure(lines, 'E1031:')
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02003758
3759 # Test for calling a partial that takes a single argument.
3760 # This used to produce a "E340: Internal error" message.
3761 lines =<< trim END
3762 def Foo(n: number): number
3763 return n * 2
3764 enddef
3765 var Fn = function(Foo, [10])
3766 assert_equal(20, Fn())
3767 END
3768 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara90afb92020-07-15 22:38:56 +02003769enddef
3770
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003771def Test_partial_double_nested()
3772 var idx = 123
3773 var Get = () => idx
3774 var Ref = function(Get, [])
3775 var RefRef = function(Ref, [])
3776 assert_equal(123, RefRef())
3777enddef
3778
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003779def Test_partial_null_function()
3780 var lines =<< trim END
3781 var d: dict<func> = {f: null_function}
3782 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003783 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003784 END
3785 v9.CheckDefAndScriptSuccess(lines)
3786enddef
3787
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003788def Test_cmd_modifier()
3789 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003790 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003791enddef
3792
3793def Test_restore_modifiers()
3794 # check that when compiling a :def function command modifiers are not messed
3795 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003796 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003797 vim9script
3798 set eventignore=
3799 autocmd QuickFixCmdPost * copen
3800 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003801 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003802 enddef
3803 func Func()
3804 noautocmd call s:AutocmdsDisabled()
3805 let g:ei_after = &eventignore
3806 endfunc
3807 Func()
3808 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003809 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003810 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003811enddef
3812
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003813def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003814 eval 1 + 2
3815 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003816 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003817 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003818enddef
3819
3820def StackBot()
3821 # throw an error
3822 eval [][0]
3823enddef
3824
3825def Test_callstack_def()
3826 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003827 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003828 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003829 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003830 endtry
3831enddef
3832
Bram Moolenaare8211a32020-10-09 22:04:29 +02003833" Re-using spot for variable used in block
3834def Test_block_scoped_var()
3835 var lines =<< trim END
3836 vim9script
3837 def Func()
3838 var x = ['a', 'b', 'c']
3839 if 1
3840 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003841 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003842 endif
3843 var z = x
3844 assert_equal(['x', 'x', 'x'], z)
3845 enddef
3846 Func()
3847 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003848 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003849enddef
3850
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003851def Test_reset_did_emsg()
3852 var lines =<< trim END
3853 @s = 'blah'
3854 au BufWinLeave * #
3855 def Func()
3856 var winid = popup_create('popup', {})
3857 exe '*s'
3858 popup_close(winid)
3859 enddef
3860 Func()
3861 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003862 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003863 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003864enddef
3865
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003866def Test_did_emsg_reset()
3867 # executing an autocommand resets did_emsg, this should not result in a
3868 # builtin function considered failing
3869 var lines =<< trim END
3870 vim9script
3871 au BufWinLeave * #
3872 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003873 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003874 eval [][0]
3875 enddef
3876 nno <F3> <cmd>call <sid>Func()<cr>
3877 feedkeys("\<F3>\e", 'xt')
3878 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003879 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003880 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003881
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003882 nunmap <F3>
3883 au! BufWinLeave
3884enddef
3885
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003886def Test_abort_with_silent_call()
3887 var lines =<< trim END
3888 vim9script
3889 g:result = 'none'
3890 def Func()
3891 g:result += 3
3892 g:result = 'yes'
3893 enddef
3894 # error is silenced, but function aborts on error
3895 silent! Func()
3896 assert_equal('none', g:result)
3897 unlet g:result
3898 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003899 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003900enddef
3901
Bram Moolenaarf665e972020-12-05 19:17:16 +01003902def Test_continues_with_silent_error()
3903 var lines =<< trim END
3904 vim9script
3905 g:result = 'none'
3906 def Func()
3907 silent! g:result += 3
3908 g:result = 'yes'
3909 enddef
3910 # error is silenced, function does not abort
3911 Func()
3912 assert_equal('yes', g:result)
3913 unlet g:result
3914 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003915 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003916enddef
3917
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003918def Test_abort_even_with_silent()
3919 var lines =<< trim END
3920 vim9script
3921 g:result = 'none'
3922 def Func()
3923 eval {-> ''}() .. '' .. {}['X']
3924 g:result = 'yes'
3925 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003926 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003927 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003928 unlet g:result
3929 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003930 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003931enddef
3932
Bram Moolenaarf665e972020-12-05 19:17:16 +01003933def Test_cmdmod_silent_restored()
3934 var lines =<< trim END
3935 vim9script
3936 def Func()
3937 g:result = 'none'
3938 silent! g:result += 3
3939 g:result = 'none'
3940 g:result += 3
3941 enddef
3942 Func()
3943 END
3944 # can't use CheckScriptFailure, it ignores the :silent!
3945 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003946 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003947 var caught = 'no'
3948 try
3949 exe 'source ' .. fname
3950 catch /E1030:/
3951 caught = 'yes'
3952 assert_match('Func, line 4', v:throwpoint)
3953 endtry
3954 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003955enddef
3956
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003957def Test_cmdmod_silent_nested()
3958 var lines =<< trim END
3959 vim9script
3960 var result = ''
3961
3962 def Error()
3963 result ..= 'Eb'
3964 eval [][0]
3965 result ..= 'Ea'
3966 enddef
3967
3968 def Crash()
3969 result ..= 'Cb'
3970 sil! Error()
3971 result ..= 'Ca'
3972 enddef
3973
3974 Crash()
3975 assert_equal('CbEbEaCa', result)
3976 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003977 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003978enddef
3979
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003980def Test_dict_member_with_silent()
3981 var lines =<< trim END
3982 vim9script
3983 g:result = 'none'
3984 var d: dict<any>
3985 def Func()
3986 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003987 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003988 catch
3989 endtry
3990 enddef
3991 silent! Func()
3992 assert_equal('0', g:result)
3993 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003994 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003995 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003996enddef
3997
Bram Moolenaarf9041332021-01-21 19:41:16 +01003998def Test_skip_cmds_with_silent()
3999 var lines =<< trim END
4000 vim9script
4001
4002 def Func(b: bool)
4003 Crash()
4004 enddef
4005
4006 def Crash()
4007 sil! :/not found/d _
4008 sil! :/not found/put _
4009 enddef
4010
4011 Func(true)
4012 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004013 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01004014enddef
4015
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01004016def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00004017 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01004018 def g:Opfunc(_: any): string
4019 setline(1, 'ASDF')
4020 return ''
4021 enddef
4022 new
4023 setline(1, 'asdf')
4024 feedkeys("\<F3>$", 'x')
4025 assert_equal('ASDF', getline(1))
4026
4027 bwipe!
4028 nunmap <F3>
4029enddef
4030
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004031func Test_opfunc_error()
4032 CheckScreendump
4033 call Run_Test_opfunc_error()
4034endfunc
4035
4036def Run_Test_opfunc_error()
4037 # test that the error from Opfunc() is displayed right away
4038 var lines =<< trim END
4039 vim9script
4040
4041 def Opfunc(type: string)
4042 try
4043 eval [][0]
4044 catch /nothing/ # error not caught
4045 endtry
4046 enddef
4047 &operatorfunc = Opfunc
4048 nnoremap <expr> l <SID>L()
4049 def L(): string
4050 return 'l'
4051 enddef
4052 'x'->repeat(10)->setline(1)
4053 feedkeys('g@l', 'n')
4054 feedkeys('llll')
4055 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004056 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004057
Bram Moolenaar62aec932022-01-29 21:45:34 +00004058 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
4059 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01004060 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004061
4062 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00004063 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004064enddef
4065
Bram Moolenaar077a4232020-12-22 18:33:27 +01004066" this was crashing on exit
4067def Test_nested_lambda_in_closure()
4068 var lines =<< trim END
4069 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004070 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004071 def Outer()
4072 def g:Inner()
4073 echo map([1, 2, 3], {_, v -> v + 1})
4074 enddef
4075 g:Inner()
4076 enddef
4077 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004078 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01004079 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004080 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004081 return
4082 endif
4083 assert_equal(['Done'], readfile('XnestedDone'))
4084 delete('XnestedDone')
4085enddef
4086
Bram Moolenaar92368aa2022-02-07 17:50:39 +00004087def Test_nested_closure_funcref()
4088 var lines =<< trim END
4089 vim9script
4090 def Func()
4091 var n: number
4092 def Nested()
4093 ++n
4094 enddef
4095 Nested()
4096 g:result_one = n
4097 var Ref = function(Nested)
4098 Ref()
4099 g:result_two = n
4100 enddef
4101 Func()
4102 END
4103 v9.CheckScriptSuccess(lines)
4104 assert_equal(1, g:result_one)
4105 assert_equal(2, g:result_two)
4106 unlet g:result_one g:result_two
4107enddef
4108
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004109def Test_nested_closure_in_dict()
4110 var lines =<< trim END
4111 vim9script
4112 def Func(): dict<any>
4113 var n: number
4114 def Inc(): number
4115 ++n
4116 return n
4117 enddef
4118 return {inc: function(Inc)}
4119 enddef
4120 disas Func
4121 var d = Func()
4122 assert_equal(1, d.inc())
4123 assert_equal(2, d.inc())
4124 END
4125 v9.CheckScriptSuccess(lines)
4126enddef
4127
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004128def Test_script_local_other_script()
4129 var lines =<< trim END
4130 function LegacyJob()
4131 let FuncRef = function('s:close_cb')
4132 endfunction
4133 function s:close_cb(...)
4134 endfunction
4135 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004136 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004137 source Xlegacy.vim
4138 g:LegacyJob()
4139 g:LegacyJob()
4140 g:LegacyJob()
4141
4142 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004143enddef
4144
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004145def Test_check_func_arg_types()
4146 var lines =<< trim END
4147 vim9script
4148 def F1(x: string): string
4149 return x
4150 enddef
4151
4152 def F2(x: number): number
4153 return x + 1
4154 enddef
4155
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004156 def G(Fg: func): dict<func>
4157 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004158 enddef
4159
4160 def H(d: dict<func>): string
4161 return d.f('a')
4162 enddef
4163 END
4164
Bram Moolenaar62aec932022-01-29 21:45:34 +00004165 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4166 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004167
4168 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004169enddef
4170
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004171def Test_call_func_with_null()
4172 var lines =<< trim END
4173 def Fstring(v: string)
4174 assert_equal(null_string, v)
4175 enddef
4176 Fstring(null_string)
4177 def Fblob(v: blob)
4178 assert_equal(null_blob, v)
4179 enddef
4180 Fblob(null_blob)
4181 def Flist(v: list<number>)
4182 assert_equal(null_list, v)
4183 enddef
4184 Flist(null_list)
4185 def Fdict(v: dict<number>)
4186 assert_equal(null_dict, v)
4187 enddef
4188 Fdict(null_dict)
4189 def Ffunc(Fv: func(number): number)
4190 assert_equal(null_function, Fv)
4191 enddef
4192 Ffunc(null_function)
4193 if has('channel')
4194 def Fchannel(v: channel)
4195 assert_equal(null_channel, v)
4196 enddef
4197 Fchannel(null_channel)
4198 def Fjob(v: job)
4199 assert_equal(null_job, v)
4200 enddef
4201 Fjob(null_job)
4202 endif
4203 END
4204 v9.CheckDefAndScriptSuccess(lines)
4205enddef
4206
4207def Test_null_default_argument()
4208 var lines =<< trim END
4209 def Fstring(v: string = null_string)
4210 assert_equal(null_string, v)
4211 enddef
4212 Fstring()
4213 def Fblob(v: blob = null_blob)
4214 assert_equal(null_blob, v)
4215 enddef
4216 Fblob()
4217 def Flist(v: list<number> = null_list)
4218 assert_equal(null_list, v)
4219 enddef
4220 Flist()
4221 def Fdict(v: dict<number> = null_dict)
4222 assert_equal(null_dict, v)
4223 enddef
4224 Fdict()
4225 def Ffunc(Fv: func(number): number = null_function)
4226 assert_equal(null_function, Fv)
4227 enddef
4228 Ffunc()
4229 if has('channel')
4230 def Fchannel(v: channel = null_channel)
4231 assert_equal(null_channel, v)
4232 enddef
4233 Fchannel()
4234 def Fjob(v: job = null_job)
4235 assert_equal(null_job, v)
4236 enddef
4237 Fjob()
4238 endif
4239 END
4240 v9.CheckDefAndScriptSuccess(lines)
4241enddef
4242
4243def Test_null_return()
4244 var lines =<< trim END
4245 def Fstring(): string
4246 return null_string
4247 enddef
4248 assert_equal(null_string, Fstring())
4249 def Fblob(): blob
4250 return null_blob
4251 enddef
4252 assert_equal(null_blob, Fblob())
4253 def Flist(): list<number>
4254 return null_list
4255 enddef
4256 assert_equal(null_list, Flist())
4257 def Fdict(): dict<number>
4258 return null_dict
4259 enddef
4260 assert_equal(null_dict, Fdict())
4261 def Ffunc(): func(number): number
4262 return null_function
4263 enddef
4264 assert_equal(null_function, Ffunc())
4265 if has('channel')
4266 def Fchannel(): channel
4267 return null_channel
4268 enddef
4269 assert_equal(null_channel, Fchannel())
4270 def Fjob(): job
4271 return null_job
4272 enddef
4273 assert_equal(null_job, Fjob())
4274 endif
4275 END
4276 v9.CheckDefAndScriptSuccess(lines)
4277enddef
4278
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004279def Test_list_any_type_checked()
4280 var lines =<< trim END
4281 vim9script
4282 def Foo()
4283 --decl--
4284 Bar(l)
4285 enddef
4286 def Bar(ll: list<dict<any>>)
4287 enddef
4288 Foo()
4289 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004290 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004291 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004292 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004293 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004294 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004295
4296 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004297 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004298enddef
4299
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004300def Test_compile_error()
4301 var lines =<< trim END
4302 def g:Broken()
4303 echo 'a' + {}
4304 enddef
4305 call g:Broken()
4306 END
4307 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004308 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004309
4310 # Second call won't try compiling again
4311 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004312 delfunc g:Broken
4313
4314 # No error when compiling with :silent!
4315 lines =<< trim END
4316 def g:Broken()
4317 echo 'a' + []
4318 enddef
4319 silent! defcompile
4320 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004321 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004322
4323 # Calling the function won't try compiling again
4324 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4325 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004326enddef
4327
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004328def Test_ignored_argument()
4329 var lines =<< trim END
4330 vim9script
4331 def Ignore(_, _): string
4332 return 'yes'
4333 enddef
4334 assert_equal('yes', Ignore(1, 2))
4335
4336 func Ok(_)
4337 return a:_
4338 endfunc
4339 assert_equal('ok', Ok('ok'))
4340
4341 func Oktoo()
4342 let _ = 'too'
4343 return _
4344 endfunc
4345 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004346
4347 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004348 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004349 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004350
4351 lines =<< trim END
4352 def Ignore(_: string): string
4353 return _
4354 enddef
4355 defcompile
4356 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004357 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004358
4359 lines =<< trim END
4360 var _ = 1
4361 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004362 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004363
4364 lines =<< trim END
4365 var x = _
4366 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004367 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004368enddef
4369
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004370def Test_too_many_arguments()
4371 var lines =<< trim END
4372 echo [0, 1, 2]->map(() => 123)
4373 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004374 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004375
4376 lines =<< trim END
4377 echo [0, 1, 2]->map((_) => 123)
4378 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004379 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004380
4381 lines =<< trim END
4382 vim9script
4383 def OneArgument(arg: string)
4384 echo arg
4385 enddef
4386 var Ref = OneArgument
4387 Ref('a', 'b')
4388 END
4389 v9.CheckScriptFailure(lines, 'E118:')
4390enddef
4391
4392def Test_funcref_with_base()
4393 var lines =<< trim END
4394 vim9script
4395 def TwoArguments(str: string, nr: number)
4396 echo str nr
4397 enddef
4398 var Ref = TwoArguments
4399 Ref('a', 12)
4400 'b'->Ref(34)
4401 END
4402 v9.CheckScriptSuccess(lines)
4403
4404 lines =<< trim END
4405 vim9script
4406 def TwoArguments(str: string, nr: number)
4407 echo str nr
4408 enddef
4409 var Ref = TwoArguments
4410 'a'->Ref('b')
4411 END
4412 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4413
4414 lines =<< trim END
4415 vim9script
4416 def TwoArguments(str: string, nr: number)
4417 echo str nr
4418 enddef
4419 var Ref = TwoArguments
4420 123->Ref(456)
4421 END
4422 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4423
4424 lines =<< trim END
4425 vim9script
4426 def TwoArguments(nr: number, str: string)
4427 echo str nr
4428 enddef
4429 var Ref = TwoArguments
4430 123->Ref('b')
4431 def AndNowCompiled()
4432 456->Ref('x')
4433 enddef
4434 AndNowCompiled()
4435 END
4436 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004437enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004438
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004439def Test_closing_brace_at_start_of_line()
4440 var lines =<< trim END
4441 def Func()
4442 enddef
4443 Func(
4444 )
4445 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004446 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004447enddef
4448
Bram Moolenaar62aec932022-01-29 21:45:34 +00004449func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004450 let g:mydict = {}
4451 func g:mydict.afunc()
4452 let g:result = self.key
4453 endfunc
4454endfunc
4455
4456def Test_numbered_function_reference()
4457 CreateMydict()
4458 var output = execute('legacy func g:mydict.afunc')
4459 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4460 execute 'function(' .. funcName .. ', [], {key: 42})()'
4461 # check that the function still exists
4462 assert_equal(output, execute('legacy func g:mydict.afunc'))
4463 unlet g:mydict
4464enddef
4465
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004466def Test_numbered_function_call()
4467 var lines =<< trim END
4468 let s:legacyscript = {}
4469 func s:legacyscript.Helper() abort
4470 return "Success"
4471 endfunc
4472 let g:legacyscript = deepcopy(s:legacyscript)
4473
4474 let g:legacy_result = eval("g:legacyscript.Helper()")
4475 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4476 END
4477 v9.CheckScriptSuccess(lines)
4478 assert_equal('Success', g:legacy_result)
4479 assert_equal('Success', g:vim9_result)
4480
4481 unlet g:legacy_result
4482 unlet g:vim9_result
4483enddef
4484
Bram Moolenaard3a11782022-01-05 16:50:40 +00004485def Test_go_beyond_end_of_cmd()
4486 # this was reading the byte after the end of the line
4487 var lines =<< trim END
4488 def F()
4489 cal
4490 enddef
4491 defcompile
4492 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004493 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004494enddef
4495
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004496" Test for memory allocation failure when defining a new lambda
4497func Test_lambda_allocation_failure()
4498 new
4499 let lines =<< trim END
4500 vim9script
4501 g:Xlambda = (x): number => {
4502 return x + 1
4503 }
4504 END
4505 call setline(1, lines)
4506 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4507 call assert_fails('source', 'E342:')
4508 call assert_false(exists('g:Xlambda'))
4509 bw!
4510endfunc
4511
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004512def Test_lambda_argument_type_check()
4513 var lines =<< trim END
4514 vim9script
4515
4516 def Scan(ll: list<any>): func(func(any))
4517 return (Emit: func(any)) => {
4518 for e in ll
4519 Emit(e)
4520 endfor
4521 }
4522 enddef
4523
4524 def Sum(Cont: func(func(any))): any
4525 var sum = 0.0
4526 Cont((v: float) => { # <== NOTE: the lambda expects a float
4527 sum += v
4528 })
4529 return sum
4530 enddef
4531
Bram Moolenaar47bba532023-01-20 18:49:46 +00004532 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004533 echo Scan(ml)->Sum()
4534 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004535 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004536enddef
4537
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004538def Test_multiple_funcref()
4539 # This was using a NULL pointer
4540 var lines =<< trim END
4541 vim9script
4542 def A(F: func, ...args: list<any>): func
4543 return funcref(F, args)
4544 enddef
4545
4546 def B(F: func): func
4547 return funcref(A, [F])
4548 enddef
4549
4550 def Test(n: number)
4551 enddef
4552
4553 const X = B(Test)
4554 X(1)
4555 END
4556 v9.CheckScriptSuccess(lines)
4557
4558 # slightly different case
4559 lines =<< trim END
4560 vim9script
4561
4562 def A(F: func, ...args: list<any>): any
4563 return call(F, args)
4564 enddef
4565
4566 def B(F: func): func
4567 return funcref(A, [F])
4568 enddef
4569
4570 def Test(n: number)
4571 enddef
4572
4573 const X = B(Test)
4574 X(1)
4575 END
4576 v9.CheckScriptSuccess(lines)
4577enddef
4578
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004579def Test_cexpr_errmsg_line_number()
John Marriott45377e22025-03-27 18:12:32 +01004580 CheckFeature quickfix
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004581 var lines =<< trim END
4582 vim9script
4583 def Func()
4584 var qfl = {}
4585 cexpr qfl
4586 enddef
4587 Func()
4588 END
4589 v9.CheckScriptFailure(lines, 'E777', 2)
4590enddef
4591
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004592def AddDefer(s: string)
4593 g:deferred->extend([s])
4594enddef
4595
4596def DeferTwo()
4597 g:deferred->extend(['in Two'])
4598 for n in range(3)
4599 defer g:AddDefer('two' .. n)
4600 endfor
4601 g:deferred->extend(['end Two'])
4602enddef
4603
4604def DeferOne()
4605 g:deferred->extend(['in One'])
4606 defer g:AddDefer('one')
4607 g:DeferTwo()
4608 g:deferred->extend(['end One'])
4609
4610 writefile(['text'], 'XdeferFile')
4611 defer delete('XdeferFile')
4612enddef
4613
4614def Test_defer()
4615 g:deferred = []
4616 g:DeferOne()
4617 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4618 unlet g:deferred
4619 assert_equal('', glob('XdeferFile'))
4620enddef
4621
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004622def Test_invalid_redir()
4623 var lines =<< trim END
4624 def Tone()
4625 if 1
4626 redi =>@�0
4627 redi END
4628 endif
4629 enddef
4630 defcompile
4631 END
4632 v9.CheckScriptFailure(lines, 'E354:')
4633 delfunc g:Tone
4634
4635 # this was reading past the end of the line
4636 lines =<< trim END
4637 def Ttwo()
4638 if 0
4639 redi =>@�0
4640 redi END
4641 endif
4642 enddef
4643 defcompile
4644 END
4645 v9.CheckScriptFailure(lines, 'E354:')
4646 delfunc g:Ttwo
4647enddef
4648
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004649func Test_keytyped_in_nested_function()
Drew Vogelea67ba72025-05-07 22:05:17 +02004650 CheckScreendump
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004651 CheckRunVimInTerminal
4652
4653 call Run_Test_keytyped_in_nested_function()
4654endfunc
4655
4656def Run_Test_keytyped_in_nested_function()
4657 var lines =<< trim END
4658 vim9script
4659 autocmd CmdlineEnter * sample#Init()
4660
4661 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4662 END
4663 writefile(lines, 'Xkeytyped', 'D')
4664
4665 var dir = 'Xrtpdir/autoload'
4666 mkdir(dir, 'pR')
4667
4668 lines =<< trim END
4669 vim9script
4670 export def Init(): void
4671 cnoremap <expr>" <SID>Quote('"')
4672 enddef
4673 def Quote(str: string): string
4674 def InPair(): number
4675 return 0
4676 enddef
4677 return str
4678 enddef
4679 END
4680 writefile(lines, dir .. '/sample.vim')
4681
4682 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4683
4684 term_sendkeys(buf, ':"')
4685 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4686
4687 # clean up
4688 term_sendkeys(buf, "\<Esc>")
4689 g:StopVimInTerminal(buf)
4690enddef
4691
Yegappan Lakshmanan5715a722024-05-03 18:24:07 +02004692" Test for test_override('defcompile')
4693def Test_test_override_defcompile()
4694 var lines =<< trim END
4695 vim9script
4696 def Foo()
4697 xxx
4698 enddef
4699 END
4700 test_override('defcompile', 1)
4701 v9.CheckScriptFailure(lines, 'E476: Invalid command: xxx')
4702 test_override('defcompile', 0)
4703enddef
4704
Yegappan Lakshmanan0072cee2025-01-07 20:22:32 +01004705" Test for using a comment after the opening curly brace of an inner block.
4706def Test_comment_after_inner_block()
4707 var lines =<< trim END
4708 vim9script
4709
4710 def F(G: func)
4711 enddef
4712
4713 F(() => { # comment1
4714 F(() => { # comment2
4715 echo 'ok' # comment3
4716 }) # comment4
4717 }) # comment5
4718 END
4719 v9.CheckScriptSuccess(lines)
4720enddef
4721
Yegappan Lakshmanan6289f912025-01-14 17:13:36 +01004722" Test for calling an imported funcref which is modified in the current script
4723def Test_call_modified_import_func()
4724 var lines =<< trim END
4725 vim9script
4726
4727 export var done = 0
4728
4729 def Noop()
4730 enddef
4731
4732 export var Setup = Noop
4733
4734 export def Run()
4735 done = 0
4736 Setup()
Yegappan Lakshmanan9904cbc2025-01-15 18:25:19 +01004737 call(Setup, [])
4738 call("Setup", [])
4739 call(() => Setup(), [])
Yegappan Lakshmanan6289f912025-01-14 17:13:36 +01004740 done += 1
4741 enddef
4742 END
4743 writefile(lines, 'XcallModifiedImportFunc.vim', 'D')
4744
4745 lines =<< trim END
4746 vim9script
4747
4748 import './XcallModifiedImportFunc.vim' as imp
4749
4750 var setup = 0
4751
4752 imp.Run()
4753
4754 imp.Setup = () => {
4755 ++setup
4756 }
4757
4758 imp.Run()
4759
Yegappan Lakshmanan9904cbc2025-01-15 18:25:19 +01004760 assert_equal(4, setup)
Yegappan Lakshmanan6289f912025-01-14 17:13:36 +01004761 assert_equal(1, imp.done)
4762 END
4763 v9.CheckScriptSuccess(lines)
4764enddef
4765
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004766" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004767if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004768 def Test_python3_command()
4769 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004770 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004771 assert_equal('yes', g:done)
4772 unlet g:done
4773 enddef
4774
Bram Moolenaar20677332021-06-06 17:02:53 +02004775 def Test_python3_heredoc()
4776 py3 << trim EOF
4777 import vim
4778 vim.vars['didit'] = 'yes'
4779 EOF
4780 assert_equal('yes', g:didit)
4781
4782 python3 << trim EOF
4783 import vim
4784 vim.vars['didit'] = 'again'
4785 EOF
4786 assert_equal('again', g:didit)
4787 enddef
4788endif
4789
Bram Moolenaar20677332021-06-06 17:02:53 +02004790if has('lua')
4791 def Test_lua_heredoc()
4792 g:d = {}
4793 lua << trim EOF
4794 x = vim.eval('g:d')
4795 x['key'] = 'val'
4796 EOF
4797 assert_equal('val', g:d.key)
4798 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004799
4800 def Test_lua_heredoc_fails()
4801 var lines = [
4802 'vim9script',
4803 'def ExeLua()',
4804 'lua << trim EOLUA',
4805 "x = vim.eval('g:nodict')",
4806 'EOLUA',
4807 'enddef',
4808 'ExeLua()',
4809 ]
4810 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4811 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004812endif
4813
Bram Moolenaard881d152022-05-13 13:50:36 +01004814if has('perl')
4815 def Test_perl_heredoc_nested()
4816 var lines =<< trim END
4817 vim9script
4818 def F(): string
4819 def G(): string
4820 perl << EOF
4821 EOF
4822 return 'done'
4823 enddef
4824 return G()
4825 enddef
4826 assert_equal('done', F())
4827 END
4828 v9.CheckScriptSuccess(lines)
4829 enddef
4830endif
4831
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004832
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004833" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker