blob: 030ff833ef40c1a3f3a5507d280c2e8797cff60a [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
Bram Moolenaar403dc312020-10-17 19:29:51 +0200553def Test_return_bool()
554 var lines =<< trim END
555 vim9script
556 def MenuFilter(id: number, key: string): bool
557 return popup_filter_menu(id, key)
558 enddef
559 def YesnoFilter(id: number, key: string): bool
560 return popup_filter_yesno(id, key)
561 enddef
562 defcompile
563 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000564 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200565enddef
566
mityu500c4442022-12-02 18:12:05 +0000567def Test_return_void_comment_follows()
568 var lines =<< trim END
569 vim9script
570 def ReturnCommentFollows(): void
571 return # Some comment
572 enddef
573 defcompile
574 END
575 v9.CheckScriptSuccess(lines)
576enddef
577
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200578let s:nothing = 0
579def ReturnNothing()
580 s:nothing = 1
581 if true
582 return
583 endif
584 s:nothing = 2
585enddef
586
587def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000588 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200589 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200590enddef
591
Bram Moolenaar648ea762021-01-15 19:04:32 +0100592def Test_return_invalid()
593 var lines =<< trim END
594 vim9script
595 def Func(): invalid
596 return xxx
597 enddef
598 defcompile
599 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000600 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100601
602 lines =<< trim END
603 vim9script
604 def Test(Fun: func(number): number): list<number>
605 return map([1, 2, 3], (_, i) => Fun(i))
606 enddef
607 defcompile
608 def Inc(nr: number): nr
609 return nr + 2
610 enddef
611 echo Test(Inc)
612 END
613 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000614 v9.CheckScriptFailure(lines, 'E1010:')
615 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100616enddef
617
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200618def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000619 # This used to fail but now the actual list type is checked, and since it has
620 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200621 var lines =<< trim END
622 vim9script
623 def Func(): list<string>
624 var l: list<any>
625 l->add('string')
626 return l
627 enddef
628 echo Func()
629 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000630 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000631
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200632 lines =<< trim END
633 vim9script
634 def Func(): list<string>
635 var l: list<any>
636 l += ['string']
637 return l
638 enddef
639 echo Func()
640 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000641 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200642enddef
643
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000644def Test_return_any_two_types()
645 var lines =<< trim END
646 vim9script
647
648 def G(Fn: func(string): any)
649 g:result = Fn("hello")
650 enddef
651
652 def F(a: number, b: string): any
653 echo b
654 if a > 0
655 return 1
656 else
657 return []
658 endif
659 enddef
660
661 G(function(F, [1]))
662 END
663 v9.CheckScriptSuccess(lines)
664 assert_equal(1, g:result)
665 unlet g:result
666enddef
667
Bram Moolenaar62aec932022-01-29 21:45:34 +0000668func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200669 let g:counter += 1
670endfunc
671
672def Test_call_ufunc_count()
673 g:counter = 1
674 Increment()
675 Increment()
676 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200677 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200678 g:counter->assert_equal(4)
679 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200680 unlet g:counter
681enddef
682
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000683def Test_call_ufunc_failure()
684 var lines =<< trim END
685 vim9script
686 def Tryit()
687 g:Global(1, 2, 3)
688 enddef
689
690 func g:Global(a, b, c)
691 echo a:a a:b a:c
692 endfunc
693
694 defcompile
695
696 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000697 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000698 endfunc
699 Tryit()
700 END
701 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
702 delfunc g:Global
703
704 lines =<< trim END
705 vim9script
706
707 g:Ref = function('len')
708 def Tryit()
709 g:Ref('x')
710 enddef
711
712 defcompile
713
714 g:Ref = function('add')
715 Tryit()
716 END
717 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
718 unlet g:Ref
719enddef
720
Bram Moolenaar62aec932022-01-29 21:45:34 +0000721def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200722 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200723 for s in rest
724 res ..= ',' .. s
725 endfor
726 return res
727enddef
728
729def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200730 MyVarargs('one')->assert_equal('one')
731 MyVarargs('one', 'two')->assert_equal('one,two')
732 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200733enddef
734
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200735def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000736 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200737enddef
738
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200739def MyDefaultArgs(name = 'string'): string
740 return name
741enddef
742
Bram Moolenaar62aec932022-01-29 21:45:34 +0000743def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200744 return second ? name : 'none'
745enddef
746
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200747
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200748def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000749 g:MyDefaultArgs()->assert_equal('string')
750 g:MyDefaultArgs(v:none)->assert_equal('string')
751 g:MyDefaultArgs('one')->assert_equal('one')
752 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200754 MyDefaultSecond('test')->assert_equal('test')
755 MyDefaultSecond('test', true)->assert_equal('test')
756 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200757
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200758 var lines =<< trim END
759 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
760 return name .. aa .. bb
761 enddef
762
763 MyDefaultThird('->')->assert_equal('->aabb')
764 MyDefaultThird('->', v:none)->assert_equal('->aabb')
765 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
766 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
767 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
768 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
769 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200770
771 def DefArg(mandatory: any, optional = mandatory): string
772 return mandatory .. optional
773 enddef
774 DefArg(1234)->assert_equal('12341234')
775 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200776 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000777 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200778
Bram Moolenaar62aec932022-01-29 21:45:34 +0000779 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100780 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000781 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 +0100782 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000783 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100784
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200785 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100786 vim9script
787 def Func(a = b == 0 ? 1 : 2, b = 0)
788 enddef
789 defcompile
790 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000791 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000792
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000793 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000794 lines =<< trim END
795 vim9script
796 var a: any
797 def Func(arg: string = a)
798 echo arg
799 enddef
800 defcompile
801 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000802 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
803 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000804
805 # using global variable does not require type cast
806 lines =<< trim END
807 vim9script
808 def Func(arg: string = g:str)
809 echo arg
810 enddef
811 g:str = 'works'
812 Func()
813 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000814 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200815enddef
816
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100817def Test_using_vnone_default()
818 var lines =<< trim END
819 vim9script
820
821 def F(a: string = v:none)
822 if a isnot v:none
823 var b = a
824 endif
825 enddef
826 F()
827 END
828 v9.CheckScriptSuccess(lines)
829
Bram Moolenaar2ba51232023-05-15 16:22:38 +0100830 lines =<< trim END
831 vim9script
832
833 export def Floats(x: float, y = 2.0, z = 5.0)
834 g:result = printf("%.2f %.2f %.2f", x, y, z)
835 enddef
836 END
837 writefile(lines, 'Xlib.vim', 'D')
838
839 # test using a function reference in script-local variable
840 lines =<< trim END
841 vim9script
842
843 import './Xlib.vim'
844 const Floatfunc = Xlib.Floats
845 Floatfunc(1.0, v:none, 3.0)
846 END
847 v9.CheckScriptSuccess(lines)
848 assert_equal('1.00 2.00 3.00', g:result)
849 unlet g:result
850
851 # test calling the imported function
852 lines =<< trim END
853 vim9script
854
855 import './Xlib.vim'
856 Xlib.Floats(1.0, v:none, 3.0)
857 END
858 v9.CheckScriptSuccess(lines)
859 assert_equal('1.00 2.00 3.00', g:result)
860 unlet g:result
861
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100862 # TODO: this should give an error for using a missing argument
863 # lines =<< trim END
864 # vim9script
865
866 # def F(a: string = v:none)
867 # var b = a
868 # enddef
869 # F()
870 # END
871 # v9.CheckScriptFailure(lines, 'E99:')
872enddef
873
Bram Moolenaar47bba532023-01-20 18:49:46 +0000874def Test_convert_number_to_float()
875 var lines =<< trim END
876 vim9script
877 def Foo(a: float, b: float): float
878 return a + b
879 enddef
880
881 assert_equal(5.3, Foo(3.3, 2))
882 END
883 v9.CheckScriptSuccess(lines)
884enddef
885
Bram Moolenaar62aec932022-01-29 21:45:34 +0000886def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100887 a: number, #comment
888 b: bool, # comment
889 c: string) #comment
890 assert_equal(4, a)
891 assert_equal(true, b)
892 assert_equal('yes', c)
893enddef
894
895def Test_func_with_comments()
896 FuncWithComment(4, true, 'yes')
897
898 var lines =<< trim END
899 def Func(# comment
900 arg: string)
901 enddef
902 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000903 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100904
905 lines =<< trim END
Christian Brabandte4a450a2023-12-08 20:57:38 +0100906 def Func(f=
907 )
908 enddef
909 END
910 v9.CheckScriptFailure(lines, 'E125:', 2)
911
912 lines =<< trim END
Bram Moolenaarcef12702021-01-04 14:09:43 +0100913 def Func(
914 arg: string# comment
915 )
916 enddef
917 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000918 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100919
920 lines =<< trim END
921 def Func(
922 arg: string
923 )# comment
924 enddef
925 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000926 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100927enddef
928
Bram Moolenaar04b12692020-05-04 23:24:44 +0200929def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000930 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200931 return 'nested ' .. arg
932 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000933 NestedDef(':def')->assert_equal('nested :def')
934
935 func NestedFunc(arg)
936 return 'nested ' .. a:arg
937 endfunc
938 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200939
Bram Moolenaar62aec932022-01-29 21:45:34 +0000940 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
941 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200942
Bram Moolenaar62aec932022-01-29 21:45:34 +0000943 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
944 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200945
Bram Moolenaar54021752020-12-06 18:50:36 +0100946 var lines =<< trim END
947 def Outer()
948 def Inner()
949 # comment
950 enddef
951 def Inner()
952 enddef
953 enddef
954 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000955 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100956
957 lines =<< trim END
958 def Outer()
959 def Inner()
960 # comment
961 enddef
962 def! Inner()
963 enddef
964 enddef
965 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000966 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100967
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000968 lines =<< trim END
969 vim9script
970 def Outer()
971 def Inner()
972 g:result = 'ok'
973 enddef
974 Inner()
975 enddef
976 Outer()
977 Inner()
978 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000979 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000980 assert_equal('ok', g:result)
981 unlet g:result
982
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000983 lines =<< trim END
984 vim9script
985 def Outer()
986 def _Inner()
987 echo 'bad'
988 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000989 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000990 enddef
991 defcompile
992 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000993 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000994
995 lines =<< trim END
996 vim9script
997 def Outer()
998 def g:inner()
999 echo 'bad'
1000 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +00001001 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001002 enddef
1003 defcompile
1004 END
Bram Moolenaar3787f262022-02-07 21:54:01 +00001005 v9.CheckScriptFailure(lines, 'E1267:')
1006
1007 lines =<< trim END
1008 vim9script
1009 def g:_Func()
1010 echo 'bad'
1011 enddef
1012 END
1013 v9.CheckScriptFailure(lines, 'E1267:')
1014
1015 lines =<< trim END
1016 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001017 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +00001018 echo 'bad'
1019 enddef
1020 END
1021 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001022
Bram Moolenaar54021752020-12-06 18:50:36 +01001023 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +01001024 lines =<< trim END
1025 vim9script
1026 var thecount = 0
1027 if true
1028 def Test(): number
1029 def TheFunc(): number
1030 thecount += 1
1031 return thecount
1032 enddef
1033 return TheFunc()
1034 enddef
1035 endif
1036 defcompile
1037 assert_equal(1, Test())
1038 assert_equal(2, Test())
1039 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001040 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001041
1042 # also works when "thecount" is inside the "if" block
1043 lines =<< trim END
1044 vim9script
1045 if true
1046 var thecount = 0
1047 def Test(): number
1048 def TheFunc(): number
1049 thecount += 1
1050 return thecount
1051 enddef
1052 return TheFunc()
1053 enddef
1054 endif
1055 defcompile
1056 assert_equal(1, Test())
1057 assert_equal(2, Test())
1058 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001059 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001060
Bram Moolenaara915fa02022-03-23 11:29:15 +00001061 # nested function with recursive call
1062 lines =<< trim END
1063 vim9script
1064
1065 def MyFunc(): number
1066 def Fib(n: number): number
1067 if n < 2
1068 return 1
1069 endif
1070 return Fib(n - 2) + Fib(n - 1)
1071 enddef
1072
1073 return Fib(5)
1074 enddef
1075
1076 assert_equal(8, MyFunc())
1077 END
1078 v9.CheckScriptSuccess(lines)
1079
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001080 lines =<< trim END
1081 vim9script
1082 def Outer()
1083 def Inner()
1084 echo 'hello'
1085 enddef burp
1086 enddef
1087 defcompile
1088 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001089 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001090enddef
1091
Bram Moolenaar1889f492022-08-16 19:34:44 +01001092def Test_nested_function_fails()
1093 var lines =<< trim END
1094 def T()
1095 def Func(g: string):string
1096 enddef
1097 Func()
1098 enddef
1099 silent! defcompile
1100 END
1101 v9.CheckScriptFailure(lines, 'E1069:')
1102enddef
1103
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001104def Test_not_nested_function()
1105 echo printf('%d',
1106 function('len')('xxx'))
1107enddef
1108
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001109func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001110 call MyDefaultArgs()->assert_equal('string')
1111 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001112 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001113endfunc
1114
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001115def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001116 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001117 vim9script
1118 def Outer()
1119 def g:Inner(): string
1120 return 'inner'
1121 enddef
1122 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001123 defcompile
1124 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001125 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001126 delfunc g:Inner
1127 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001128 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001129 delfunc g:Inner
1130 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001131 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001132 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001133 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001134 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001135
1136 lines =<< trim END
1137 vim9script
1138 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001139 func g:Inner()
1140 return 'inner'
1141 endfunc
1142 enddef
1143 defcompile
1144 Outer()
1145 g:Inner()->assert_equal('inner')
1146 delfunc g:Inner
1147 Outer()
1148 g:Inner()->assert_equal('inner')
1149 delfunc g:Inner
1150 Outer()
1151 g:Inner()->assert_equal('inner')
1152 delfunc g:Inner
1153 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001154 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001155
1156 lines =<< trim END
1157 vim9script
1158 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001159 def g:Inner(): string
1160 return 'inner'
1161 enddef
1162 enddef
1163 defcompile
1164 Outer()
1165 Outer()
1166 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001167 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001168 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001169
1170 lines =<< trim END
1171 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001172 def Outer()
1173 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001174 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001175 enddef
1176 g:Inner()
1177 enddef
1178 Outer()
1179 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001180 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001181 delfunc g:Inner
1182
1183 lines =<< trim END
1184 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001185 def Func()
1186 echo 'script'
1187 enddef
1188 def Outer()
1189 def Func()
1190 echo 'inner'
1191 enddef
1192 enddef
1193 defcompile
1194 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001195 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001196
1197 lines =<< trim END
1198 vim9script
1199 def Func()
1200 echo 'script'
1201 enddef
1202 def Func()
1203 echo 'script'
1204 enddef
1205 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001206 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001207enddef
1208
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001209def DefListAll()
1210 def
1211enddef
1212
1213def DefListOne()
1214 def DefListOne
1215enddef
1216
1217def DefListMatches()
1218 def /DefList
1219enddef
1220
1221def Test_nested_def_list()
1222 var funcs = split(execute('call DefListAll()'), "\n")
1223 assert_true(len(funcs) > 10)
1224 assert_true(funcs->index('def DefListAll()') >= 0)
1225
1226 funcs = split(execute('call DefListOne()'), "\n")
1227 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1228
1229 funcs = split(execute('call DefListMatches()'), "\n")
1230 assert_true(len(funcs) >= 3)
1231 assert_true(funcs->index('def DefListAll()') >= 0)
1232 assert_true(funcs->index('def DefListOne()') >= 0)
1233 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001234
1235 var lines =<< trim END
1236 vim9script
1237 def Func()
1238 def +Func+
1239 enddef
1240 defcompile
1241 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001242 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001243enddef
1244
Bram Moolenaare08be092022-02-17 13:08:26 +00001245def Test_global_function_not_found()
1246 var lines =<< trim END
1247 g:Ref = 123
1248 call g:Ref()
1249 END
1250 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1251enddef
1252
Bram Moolenaar333894b2020-08-01 18:53:07 +02001253def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001254 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001255 vim9script
1256 def g:Func(): string
1257 return 'global'
1258 enddef
1259 def Func(): string
1260 return 'local'
1261 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001262 g:Func()->assert_equal('global')
1263 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001264 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001265 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001266 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001267
1268 lines =<< trim END
1269 vim9script
1270 def g:Funcy()
1271 echo 'funcy'
1272 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001273 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001274 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001275 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001276enddef
1277
Bram Moolenaar0f769812020-09-12 18:32:34 +02001278def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001279 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001280 vim9script
1281 def g:Gfunc(): string
1282 return 'global'
1283 enddef
1284 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001285 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001286 return Gfunc('testing')
1287 enddef
1288 g:Gfunc()->assert_equal('global')
1289 AnotherFunc()->assert_equal(7)
1290 delfunc g:Gfunc
1291 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001292 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001293
1294 lines =<< trim END
1295 vim9script
1296 def g:Func(): string
1297 return 'global'
1298 enddef
1299 def AnotherFunc()
1300 g:Func = function('len')
1301 enddef
1302 AnotherFunc()
1303 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001304 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001305 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001306
Bram Moolenaar62aec932022-01-29 21:45:34 +00001307 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001308 lines =<< trim END
1309 vim9script
1310 def g:Func(): string
1311 return 'global'
1312 enddef
1313 def AnotherFunc(): string
1314 return Func()
1315 enddef
1316 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001317 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001318 v9.CheckScriptFailure(lines, 'E117:')
1319 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001320
1321 lines =<< trim END
1322 vim9script
1323 def g:Func(): string
1324 return 'global'
1325 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001326 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001327 delfunc g:Func
1328 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001329 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001330
1331 # This does not shadow "i" which is visible only inside the for loop
1332 lines =<< trim END
1333 vim9script
1334
1335 def Foo(i: number)
1336 echo i
1337 enddef
1338
1339 for i in range(3)
1340 # Foo() is compiled here
1341 Foo(i)
1342 endfor
1343 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001344 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001345enddef
1346
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001347func TakesOneArg(arg)
1348 echo a:arg
1349endfunc
1350
1351def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001352 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1353 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1354 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1355 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001356
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001357 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001358 vim9script
1359 def Func(s: string)
1360 echo s
1361 enddef
1362 Func([])
1363 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01001364 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<any>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001365
Bram Moolenaar9a015112021-12-31 14:06:45 +00001366 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001367 lines =<< trim END
1368 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001369 var name = 'piet'
1370 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001371 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001372 enddef
1373 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001374 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001375
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001376 # same, inside the same block
1377 lines =<< trim END
1378 vim9script
1379 if true
1380 var name = 'piet'
1381 def FuncOne(name: string)
1382 echo name
1383 enddef
1384 endif
1385 END
1386 v9.CheckScriptFailure(lines, 'E1168:')
1387
1388 # variable in other block is OK
1389 lines =<< trim END
1390 vim9script
1391 if true
1392 var name = 'piet'
1393 endif
1394 def FuncOne(name: string)
1395 echo name
1396 enddef
1397 END
1398 v9.CheckScriptSuccess(lines)
1399
Bram Moolenaardce24412022-02-08 20:35:30 +00001400 # with another variable in another block
1401 lines =<< trim END
1402 vim9script
1403 if true
1404 var name = 'piet'
1405 # define a function so that the variable isn't cleared
1406 def GetItem(): string
1407 return item
1408 enddef
1409 endif
1410 if true
1411 var name = 'peter'
1412 def FuncOne(name: string)
1413 echo name
1414 enddef
1415 endif
1416 END
1417 v9.CheckScriptFailure(lines, 'E1168:')
1418
1419 # only variable in another block is OK
1420 lines =<< trim END
1421 vim9script
1422 if true
1423 var name = 'piet'
1424 # define a function so that the variable isn't cleared
1425 def GetItem(): string
1426 return item
1427 enddef
1428 endif
1429 if true
1430 def FuncOne(name: string)
1431 echo name
1432 enddef
1433 endif
1434 END
1435 v9.CheckScriptSuccess(lines)
1436
Bram Moolenaar9a015112021-12-31 14:06:45 +00001437 # argument name declared later is only found when compiling
1438 lines =<< trim END
1439 vim9script
1440 def FuncOne(name: string)
1441 echo nr
1442 enddef
1443 var name = 'piet'
1444 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001445 v9.CheckScriptSuccess(lines)
1446 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001447
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001448 lines =<< trim END
1449 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001450 def FuncOne(nr: number)
1451 echo nr
1452 enddef
1453 def FuncTwo()
1454 FuncOne()
1455 enddef
1456 defcompile
1457 END
1458 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001459 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001460 try
1461 source Xscript
1462 catch
1463 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1464 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1465 didCatch = true
1466 endtry
1467 assert_true(didCatch)
1468
1469 lines =<< trim END
1470 vim9script
1471 def FuncOne(nr: number)
1472 echo nr
1473 enddef
1474 def FuncTwo()
1475 FuncOne(1, 2)
1476 enddef
1477 defcompile
1478 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001479 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001480 didCatch = false
1481 try
1482 source Xscript
1483 catch
1484 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1485 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1486 didCatch = true
1487 endtry
1488 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001489enddef
1490
Bram Moolenaar50824712020-12-20 21:10:17 +01001491def Test_call_funcref_wrong_args()
1492 var head =<< trim END
1493 vim9script
1494 def Func3(a1: string, a2: number, a3: list<number>)
1495 echo a1 .. a2 .. a3[0]
1496 enddef
1497 def Testme()
1498 var funcMap: dict<func> = {func: Func3}
1499 END
1500 var tail =<< trim END
1501 enddef
1502 Testme()
1503 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001504 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001505
Bram Moolenaar62aec932022-01-29 21:45:34 +00001506 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1507 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001508
1509 var lines =<< trim END
1510 vim9script
1511 var Ref: func(number): any
1512 Ref = (j) => !j
1513 echo Ref(false)
1514 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001515 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001516
1517 lines =<< trim END
1518 vim9script
1519 var Ref: func(number): any
1520 Ref = (j) => !j
1521 call Ref(false)
1522 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001523 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001524enddef
1525
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001526def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001527 var lines =<< trim END
1528 var Callback = (..._) => 'anything'
1529 assert_equal('anything', Callback())
1530 assert_equal('anything', Callback(1))
1531 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001532
1533 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001534 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001535 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001536
Bram Moolenaar62aec932022-01-29 21:45:34 +00001537 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001538 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001539
Bram Moolenaar2a389082021-04-09 20:24:31 +02001540 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001541 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001542 echo Ref(1, 'x')
1543 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001544 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001545
1546 lines =<< trim END
1547 var Ref: func(job, string, number)
1548 Ref = (x, y) => 0
1549 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001550 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001551
1552 lines =<< trim END
1553 var Ref: func(job, string)
1554 Ref = (x, y, z) => 0
1555 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001556 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001557
1558 lines =<< trim END
1559 var one = 1
1560 var l = [1, 2, 3]
1561 echo map(l, (one) => one)
1562 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001563 v9.CheckDefFailure(lines, 'E1167:')
1564 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001565
1566 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001567 var Ref: func(any, ?any): bool
1568 Ref = (_, y = 1) => false
1569 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001570 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001571
1572 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001573 var a = 0
1574 var b = (a == 0 ? 1 : 2)
1575 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001576 var txt = 'a'
1577 b = (txt =~ 'x' ? 1 : 2)
1578 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001579 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001580 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001581
1582 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001583 def ShadowLocal()
1584 var one = 1
1585 var l = [1, 2, 3]
1586 echo map(l, (one) => one)
1587 enddef
1588 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001589 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001590
1591 lines =<< trim END
1592 def Shadowarg(one: number)
1593 var l = [1, 2, 3]
1594 echo map(l, (one) => one)
1595 enddef
1596 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001597 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001598
1599 lines =<< trim END
1600 echo ((a) => a)('aa', 'bb')
1601 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001602 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001603
1604 lines =<< trim END
1605 echo 'aa'->((a) => a)('bb')
1606 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001607 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1608 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001609enddef
1610
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001611def Test_lambda_line_nr()
1612 var lines =<< trim END
1613 vim9script
1614 # comment
1615 # comment
1616 var id = timer_start(1'000, (_) => 0)
1617 var out = execute('verbose ' .. timer_info(id)[0].callback
1618 ->string()
1619 ->substitute("('\\|')", ' ', 'g'))
1620 assert_match('Last set from .* line 4', out)
1621 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001622 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001623enddef
1624
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001625def FilterWithCond(x: string, Cond: func(string): bool): bool
1626 return Cond(x)
1627enddef
1628
Bram Moolenaar0346b792021-01-31 22:18:29 +01001629def Test_lambda_return_type()
1630 var lines =<< trim END
1631 var Ref = (): => 123
1632 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001633 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001634
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001635 # no space before the return type
1636 lines =<< trim END
1637 var Ref = (x):number => x + 1
1638 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001639 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001640
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001641 # this works
1642 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001643 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001644 endfor
1645
1646 # this fails
1647 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001648 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001649 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001650 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 +02001651
1652 lines =<< trim END
1653 var Lambda1 = (x) => {
1654 return x
1655 }
1656 assert_equal('asdf', Lambda1('asdf'))
1657 var Lambda2 = (x): string => {
1658 return x
1659 }
1660 assert_equal('foo', Lambda2('foo'))
1661 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001662 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001663
1664 lines =<< trim END
1665 var Lambda = (x): string => {
1666 return x
1667 }
1668 echo Lambda(['foo'])
1669 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001670 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001671enddef
1672
Bram Moolenaar709664c2020-12-12 14:33:41 +01001673def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001674 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001675 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001676 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001677enddef
1678
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001679def Test_lambda_invalid_block()
1680 var lines =<< trim END
1681 timer_start(0, (_) => { # echo
1682 echo 'yes'
1683 })
1684 END
1685 v9.CheckDefAndScriptSuccess(lines)
1686
1687 lines =<< trim END
1688 timer_start(0, (_) => { " echo
1689 echo 'yes'
1690 })
1691 END
1692 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1693
1694 lines =<< trim END
1695 timer_start(0, (_) => { | echo
1696 echo 'yes'
1697 })
1698 END
1699 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1700enddef
1701
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001702def Test_lambda_with_following_cmd()
1703 var lines =<< trim END
1704 set ts=2
1705 var Lambda = () => {
1706 set ts=4
1707 } | set ts=3
1708 assert_equal(3, &ts)
1709 Lambda()
1710 assert_equal(4, &ts)
1711 END
1712 v9.CheckDefAndScriptSuccess(lines)
1713 set ts=8
1714enddef
1715
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001716def Test_pass_legacy_lambda_to_def_func()
1717 var lines =<< trim END
1718 vim9script
1719 func Foo()
1720 eval s:Bar({x -> 0})
1721 endfunc
1722 def Bar(y: any)
1723 enddef
1724 Foo()
1725 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001726 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001727
1728 lines =<< trim END
1729 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001730 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001731 enddef
1732 legacy call g:TestFunc({-> 0})
1733 delfunc g:TestFunc
1734
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001735 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001736 enddef
1737 legacy call g:TestFunc({nr -> 0})
1738 delfunc g:TestFunc
1739 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001740 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001741enddef
1742
Bram Moolenaar844fb642021-10-23 13:32:30 +01001743def Test_lambda_in_reduce_line_break()
1744 # this was using freed memory
1745 var lines =<< trim END
1746 vim9script
1747 const result: dict<number> =
1748 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1749 ->reduce((acc, val) => {
1750 if has_key(acc, val)
1751 acc[val] += 1
1752 return acc
1753 else
1754 acc[val] = 1
1755 return acc
1756 endif
1757 }, {})
1758 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1759 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001760 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001761enddef
1762
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001763def Test_set_opfunc_to_lambda()
1764 var lines =<< trim END
1765 vim9script
1766 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1767 def CountSpaces(type = ''): string
1768 if type == ''
1769 &operatorfunc = (t) => CountSpaces(t)
1770 return 'g@'
1771 endif
1772 normal! '[V']y
1773 g:result = getreg('"')->count(' ')
1774 return ''
1775 enddef
1776 new
1777 'a b c d e'->setline(1)
1778 feedkeys("\<F4>", 'x')
1779 assert_equal(4, g:result)
1780 bwipe!
1781 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001782 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001783enddef
1784
Bram Moolenaaref082e12021-12-12 21:02:03 +00001785def Test_set_opfunc_to_global_function()
1786 var lines =<< trim END
1787 vim9script
1788 def g:CountSpaces(type = ''): string
1789 normal! '[V']y
1790 g:result = getreg('"')->count(' ')
1791 return ''
1792 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001793 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001794 &operatorfunc = g:CountSpaces
1795 new
1796 'a b c d e'->setline(1)
1797 feedkeys("g@_", 'x')
1798 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001799
1800 &operatorfunc = ''
1801 g:result = 0
1802 # global function works in :def function
1803 def Func()
1804 &operatorfunc = g:CountSpaces
1805 enddef
1806 Func()
1807 feedkeys("g@_", 'x')
1808 assert_equal(4, g:result)
1809
Bram Moolenaaref082e12021-12-12 21:02:03 +00001810 bwipe!
1811 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001812 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001813 &operatorfunc = ''
1814enddef
1815
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001816def Test_use_script_func_name_with_prefix()
1817 var lines =<< trim END
1818 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001819 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001820 return 'it'
1821 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001822 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001823 assert_equal('it', Fn())
1824 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001825 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001826enddef
1827
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001828def Test_lambda_type_allocated()
1829 # Check that unreferencing a partial using a lambda can use the variable type
1830 # after the lambda has been freed and does not leak memory.
1831 var lines =<< trim END
1832 vim9script
1833
1834 func MyomniFunc1(val, findstart, base)
1835 return a:findstart ? 0 : []
1836 endfunc
1837
1838 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1839 &omnifunc = Lambda
1840 Lambda = (a, b) => MyomniFunc1(20, a, b)
1841 &omnifunc = string(Lambda)
1842 Lambda = (a, b) => strlen(a)
1843 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001844 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001845enddef
1846
Bram Moolenaara7583c42022-05-07 21:14:05 +01001847def Test_define_lambda_in_execute()
1848 var lines =<< trim [CODE]
1849 vim9script
1850
1851 def BuildFuncMultiLine(): func
1852 var x =<< trim END
1853 g:SomeRandomFunc = (d: dict<any>) => {
1854 return d.k1 + d.k2
1855 }
1856 END
1857 execute(x)
1858 return g:SomeRandomFunc
1859 enddef
1860 var ResultPlus = BuildFuncMultiLine()
1861 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1862 [CODE]
1863 v9.CheckScriptSuccess(lines)
1864 unlet g:SomeRandomFunc
1865enddef
1866
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001867" Default arg and varargs
1868def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001869 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001870 for s in rest
1871 res ..= ',' .. s
1872 endfor
1873 return res
1874enddef
1875
1876def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001877 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1878 g:MyDefVarargs('one')->assert_equal('one,foo')
1879 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1880 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1881 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001882 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001883 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001884 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001885
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001886 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001887 vim9script
1888 def Func(...l: list<string>)
1889 echo l
1890 enddef
1891 Func('a', 'b', 'c')
1892 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001893 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001894
1895 lines =<< trim END
1896 vim9script
1897 def Func(...l: list<string>)
1898 echo l
1899 enddef
1900 Func()
1901 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001902 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001903
1904 lines =<< trim END
1905 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001906 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001907 echo l
1908 enddef
1909 Func(0)
1910 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001911 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001912
1913 lines =<< trim END
1914 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001915 def Func(...l: any)
1916 echo l
1917 enddef
1918 Func(0)
1919 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001920 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001921
1922 lines =<< trim END
1923 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001924 def Func(..._l: list<string>)
1925 echo _l
1926 enddef
1927 Func('a', 'b', 'c')
1928 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001929 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001930
1931 lines =<< trim END
1932 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001933 def Func(...l: list<string>)
1934 echo l
1935 enddef
1936 Func(1, 2, 3)
1937 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001938 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001939
1940 lines =<< trim END
1941 vim9script
1942 def Func(...l: list<string>)
1943 echo l
1944 enddef
1945 Func('a', 9)
1946 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001947 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001948
1949 lines =<< trim END
1950 vim9script
1951 def Func(...l: list<string>)
1952 echo l
1953 enddef
1954 Func(1, 'a')
1955 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001956 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001957
1958 lines =<< trim END
1959 vim9script
1960 def Func( # some comment
1961 ...l = []
1962 )
1963 echo l
1964 enddef
1965 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001966 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001967
1968 lines =<< trim END
1969 vim9script
1970 def DoIt()
1971 g:Later('')
1972 enddef
1973 defcompile
1974 def g:Later(...l: list<number>)
1975 enddef
1976 DoIt()
1977 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001978 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001979enddef
1980
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001981let s:value = ''
1982
1983def FuncOneDefArg(opt = 'text')
1984 s:value = opt
1985enddef
1986
1987def FuncTwoDefArg(nr = 123, opt = 'text'): string
1988 return nr .. opt
1989enddef
1990
1991def FuncVarargs(...arg: list<string>): string
1992 return join(arg, ',')
1993enddef
1994
1995def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001996 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001997 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001998 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001999 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002000 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002001 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002002
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002003 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002004 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002005 RefDef2Arg()->assert_equal('123text')
2006 RefDef2Arg(99)->assert_equal('99text')
2007 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002008
Bram Moolenaar62aec932022-01-29 21:45:34 +00002009 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
2010 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002011
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002012 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002013 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002014 RefVarargs()->assert_equal('')
2015 RefVarargs('one')->assert_equal('one')
2016 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002017
Bram Moolenaar62aec932022-01-29 21:45:34 +00002018 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
2019 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002020enddef
2021
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002022" Only varargs
2023def MyVarargsOnly(...args: list<string>): string
2024 return join(args, ',')
2025enddef
2026
2027def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002028 g:MyVarargsOnly()->assert_equal('')
2029 g:MyVarargsOnly('one')->assert_equal('one')
2030 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
2031 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
2032 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002033enddef
2034
Bram Moolenaar36818a92023-01-03 12:33:26 +00002035def Test_varargs_mismatch()
2036 var lines =<< trim END
2037 vim9script
2038
2039 def Map(Fn: func(...any): number): number
2040 return Fn('12')
2041 enddef
2042
2043 var res = Map((v) => str2nr(v))
2044 assert_equal(12, res)
2045 END
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002046 v9.CheckScriptFailure(lines, 'E1180: Variable arguments type must be a list: any')
Bram Moolenaar36818a92023-01-03 12:33:26 +00002047enddef
2048
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002049def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00002050 var lines =<< trim END
2051 def Func(x: number)
2052 var x = 234
2053 enddef
2054 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002055 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002056
2057 lines =<< trim END
2058 def Func(Ref: number)
2059 def Ref()
2060 enddef
2061 enddef
2062 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002063 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002064enddef
2065
Bram Moolenaar62aec932022-01-29 21:45:34 +00002066def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002067 arg['key'] = 'value'
2068enddef
2069
Bram Moolenaar62aec932022-01-29 21:45:34 +00002070def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002071 arg[0] = 'value'
2072enddef
2073
2074def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002075 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002076 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002077 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002078 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002079 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002080 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002081 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002082
Bram Moolenaar62aec932022-01-29 21:45:34 +00002083 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002084 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002085enddef
2086
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002087" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002088def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002089 return firstline .. lastline
2090enddef
2091
2092def Test_argument_names()
2093 assert_equal('OK', WithReservedNames('O', 'K'))
2094enddef
2095
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002096def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002097 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002098 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002099enddef
2100
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002101func DefinedLater(arg)
2102 return a:arg
2103endfunc
2104
2105def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002106 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002107 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002108 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002109
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002110 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002111 vim9script
2112 def RetNumber(): number
2113 return 123
2114 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002115 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002116 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002117 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002118 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002119
2120 lines =<< trim END
2121 vim9script
2122 def RetNumber(): number
2123 return 123
2124 enddef
2125 def Bar(F: func: number): number
2126 return F()
2127 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002128 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002129 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002130 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002131 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002132
2133 lines =<< trim END
2134 vim9script
2135 def UseNumber(nr: number)
2136 echo nr
2137 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002138 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002139 Funcref(123)
2140 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002141 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002142
2143 lines =<< trim END
2144 vim9script
2145 def UseNumber(nr: number)
2146 echo nr
2147 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002148 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002149 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002150 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002151
2152 lines =<< trim END
2153 vim9script
2154 def EchoNr(nr = 34)
2155 g:echo = nr
2156 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002157 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002158 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002159 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002160 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002161 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002162 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002163 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002164
2165 lines =<< trim END
2166 vim9script
2167 def EchoList(...l: list<number>)
2168 g:echo = l
2169 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002170 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002171 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002172 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002173 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002174 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002175 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002176 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002177
2178 lines =<< trim END
2179 vim9script
2180 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2181 g:optarg = opt
2182 g:listarg = l
2183 return nr
2184 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002185 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002186 Funcref(10)->assert_equal(10)
2187 g:optarg->assert_equal(12)
2188 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002189
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002190 Funcref(11, 22)->assert_equal(11)
2191 g:optarg->assert_equal(22)
2192 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002193
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002194 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2195 g:optarg->assert_equal(18)
2196 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002197 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002198 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002199
2200 lines =<< trim END
2201 function s:func(num)
2202 return a:num * 2
2203 endfunction
2204
2205 def s:CallFuncref()
2206 var Funcref = function('s:func')
2207 Funcref(3)->assert_equal(6)
2208 enddef
2209 call s:CallFuncref()
2210 END
2211 v9.CheckScriptSuccess(lines)
2212
2213 lines =<< trim END
2214 function s:func(num)
2215 return a:num * 2
2216 endfunction
2217
2218 def s:CallFuncref()
2219 var Funcref = function(s:func)
2220 Funcref(3)->assert_equal(6)
2221 enddef
2222 call s:CallFuncref()
2223 END
2224 v9.CheckScriptSuccess(lines)
2225
2226 lines =<< trim END
2227 function s:func(num)
2228 return a:num * 2
2229 endfunction
2230
2231 def s:CallFuncref()
2232 var Funcref = s:func
2233 Funcref(3)->assert_equal(6)
2234 enddef
2235 call s:CallFuncref()
2236 END
2237 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002238enddef
2239
2240let SomeFunc = function('len')
2241let NotAFunc = 'text'
2242
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002243def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002244 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002245 var Ref1: func(bool): string
2246 var Ref2: func(bool): number
2247 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002248 Ref3 = g:cond ? Ref1 : Ref2
2249
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002250 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002251 var Refa1: func(bool): number
2252 var Refa2: func(bool, number): number
2253 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002254 Refa3 = g:cond ? Refa1 : Refa2
2255
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002256 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002257 var Refb1: func(bool, string): number
2258 var Refb2: func(string, number): number
2259 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002260 Refb3 = g:cond ? Refb1 : Refb2
2261enddef
2262
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002263def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002264 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002265enddef
2266
2267def DefinedEvenLater(arg: string): string
2268 return arg
2269enddef
2270
2271def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002272 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002273 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002274enddef
2275
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002276def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002277 var lines =<< trim END
2278 vim9script
2279 # Define an outer function
2280 def FirstFunction()
2281 # Define an inner function
2282 def SecondFunction()
2283 # the function has a body, a double free is detected.
2284 AAAAA
2285
2286 # enddef followed by | or } followed by # one or more characters
2287 enddef|BBBB
2288 enddef
2289
2290 # Compile all functions
2291 defcompile
2292 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002293 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002294enddef
2295
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002296def Test_nested_function_with_args_split()
2297 var lines =<< trim END
2298 vim9script
2299 def FirstFunction()
2300 def SecondFunction(
2301 )
2302 # had a double free if the right parenthesis of the nested function is
2303 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002304
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002305 enddef|BBBB
2306 enddef
2307 # Compile all functions
2308 defcompile
2309 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002310 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002311
2312 lines =<< trim END
2313 vim9script
2314 def FirstFunction()
2315 func SecondFunction()
2316 endfunc|BBBB
2317 enddef
2318 defcompile
2319 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002320 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002321enddef
2322
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002323def Test_error_in_function_args()
2324 var lines =<< trim END
2325 def FirstFunction()
2326 def SecondFunction(J =
2327 # Nois
2328 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002329
2330 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002331 enddef
2332 # Compile all functions
2333 defcompile
2334 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002335 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002336enddef
2337
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002338def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002339 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002340 'def Func(): number',
2341 'return "a"',
2342 'enddef',
2343 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002344 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002345 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002346 'def Func(): string',
2347 'return 1',
2348 'enddef',
2349 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002350 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002351 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002352 'def Func(): void',
2353 'return "a"',
2354 'enddef',
2355 'defcompile'],
2356 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002357 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002358 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002359 'def Func()',
2360 'return "a"',
2361 'enddef',
2362 'defcompile'],
2363 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002364 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002365
Bram Moolenaar62aec932022-01-29 21:45:34 +00002366 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002367 'def Func(): number',
2368 'return',
2369 'enddef',
2370 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002371 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002372
Bram Moolenaar62aec932022-01-29 21:45:34 +00002373 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002374 'def Func():number',
2375 'return 123',
2376 'enddef',
2377 'defcompile'], 'E1069:')
2378 delfunc! g:Func
2379
Bram Moolenaar62aec932022-01-29 21:45:34 +00002380 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002381 'def Func() :number',
2382 'return 123',
2383 'enddef',
2384 'defcompile'], 'E1059:')
2385 delfunc! g:Func
2386
Bram Moolenaar62aec932022-01-29 21:45:34 +00002387 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002388 'def Func() : number',
2389 'return 123',
2390 'enddef',
2391 'defcompile'], 'E1059:')
2392 delfunc! g:Func
2393
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002394 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002395 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002396 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002397 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002398 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002399 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002400
Bram Moolenaar62aec932022-01-29 21:45:34 +00002401 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002402 'vim9script',
2403 'def FuncB()',
2404 ' return 123',
2405 'enddef',
2406 'def FuncA()',
2407 ' FuncB()',
2408 'enddef',
2409 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002410enddef
2411
2412def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002413 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002414 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2415 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2416 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2417 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2418 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002419enddef
2420
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002421def Test_white_space_before_comma()
2422 var lines =<< trim END
2423 vim9script
2424 def Func(a: number , b: number)
2425 enddef
2426 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002427 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002428 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002429enddef
2430
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002431def Test_white_space_after_comma()
2432 var lines =<< trim END
2433 vim9script
2434 def Func(a: number,b: number)
2435 enddef
2436 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002437 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002438
2439 # OK in legacy function
2440 lines =<< trim END
2441 vim9script
2442 func Func(a,b)
2443 endfunc
2444 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002445 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002446enddef
2447
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002448def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002449 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002450 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002451 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002452 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002453 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002454 enddef
2455 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002456 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002457
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002458 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002459 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002460 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002461
Bram Moolenaar67979662020-06-20 22:50:47 +02002462 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002463 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002464 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002465
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002466 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002467 def ListFunc(arg: list<number>)
2468 listvar = arg
2469 enddef
2470 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002471 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002472
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002473 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002474 def DictFunc(arg: dict<number>)
2475 dictvar = arg
2476 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002477 {a: 1, b: 2}->DictFunc()
2478 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002479 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002480 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002481 enddef
2482 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002483 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002484
Bram Moolenaare0de1712020-12-02 17:36:54 +01002485 {a: 3, b: 4}->DictFunc()
2486 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002487
2488 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002489 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002490 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002491 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002492
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002493 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002494 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002495 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002496 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002497 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002498 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002499
2500 def UseString()
2501 'xyork'->MyFunc()
2502 enddef
2503 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002504 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002505
Bram Moolenaar10409562020-07-29 20:00:38 +02002506 def UseString2()
2507 "knife"->MyFunc()
2508 enddef
2509 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002510 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002511
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002512 # prepending a colon makes it a mark
2513 new
2514 setline(1, ['aaa', 'bbb', 'ccc'])
2515 normal! 3Gmt1G
2516 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002517 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002518 bwipe!
2519
Bram Moolenaare6b53242020-07-01 17:28:33 +02002520 MyFunc(
2521 'continued'
2522 )
2523 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002524 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002525 )
2526
2527 call MyFunc(
2528 'more'
2529 ..
2530 'lines'
2531 )
2532 assert_equal(
2533 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002534 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002535 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002536 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002537 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002538enddef
2539
2540def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002541 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002542 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002543 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002544 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002545 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002546 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002547 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002548 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002549 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002550enddef
2551
Bram Moolenaar65b95452020-07-19 14:03:09 +02002552def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002553 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002554 vim9script
2555 def MyFunc(arg: string)
2556 echo arg
2557 enddef
2558 MyFunc(1234)
2559 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002560 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002561enddef
2562
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002563def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002564 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002565 vim9script
2566 const var = ''
2567 def MyFunc(arg: string)
2568 var = 'asdf'
2569 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002570 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002571 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002572 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002573 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002574
2575 lines =<< trim END
2576 const g:Aconst = 77
2577 def Change()
2578 # comment
2579 g:Aconst = 99
2580 enddef
2581 call Change()
2582 unlet g:Aconst
2583 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002584 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002585enddef
2586
2587" Test that inside :function a Python function can be defined, :def is not
2588" recognized.
2589func Test_function_python()
2590 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002591 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002592 execute py "<< EOF"
2593def do_something():
2594 return 1
2595EOF
2596endfunc
2597
2598def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002599 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002600 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002601 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002602 echo 'hello'
2603 enddef
2604
2605 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002606 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002607 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002608 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002609
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002610 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002611 CallGoneSoon()
2612 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002613 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002614 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2615 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002616enddef
2617
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002618func Test_free_dict_while_in_funcstack()
2619 " relies on the sleep command
2620 CheckUnix
2621 call Run_Test_free_dict_while_in_funcstack()
2622endfunc
2623
2624def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002625 # this was freeing the TermRun() default argument dictionary while it was
2626 # still referenced in a funcstack_T
2627 var lines =<< trim END
2628 vim9script
2629
2630 &updatetime = 400
2631 def TermRun(_ = {})
2632 def Post()
2633 enddef
2634 def Exec()
2635 term_start('sleep 1', {
2636 term_finish: 'close',
2637 exit_cb: (_, _) => Post(),
2638 })
2639 enddef
2640 Exec()
2641 enddef
2642 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2643 timer_start(100, (_) => feedkeys("\<F4>"))
2644 timer_start(1000, (_) => feedkeys("\<F4>"))
2645 sleep 1500m
2646 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002647 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002648 nunmap <F4>
2649 set updatetime&
2650enddef
2651
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002652def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002653 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002654 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002655 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002656 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002657 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002658 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002659 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002660 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002661 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002662
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002663 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002664 g:Func1()->assert_equal('Func1')
2665 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002666
2667 delfunc! Func0
2668 delfunc! Func1
2669 delfunc! Func2
2670enddef
2671
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002672def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002673 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002674 vim9script
2675 func Func(arg)
2676 echo a:arg
2677 endfunc
2678 Func('text')
2679 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002680 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002681 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002682enddef
2683
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002684let s:funcResult = 0
2685
2686def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002687 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002688enddef
2689
2690def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002691 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002692 return 1234
2693enddef
2694
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002695def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002696 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002697 return 'text'
2698enddef
2699
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002700def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002701 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002702enddef
2703
2704def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002705 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002706 return arg
2707enddef
2708
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002709def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002710 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002711enddef
2712
Bram Moolenaar62aec932022-01-29 21:45:34 +00002713def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002714 return arg
2715enddef
2716
Bram Moolenaar62aec932022-01-29 21:45:34 +00002717def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002718 return arg
2719enddef
2720
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002721def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002722 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002723 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002724 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002725 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002726 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002727
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002728 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002729 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002730 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002731 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002732 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002733
Bram Moolenaar53900992020-08-22 19:02:02 +02002734 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002735 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002736 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002737 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002738
Bram Moolenaar53900992020-08-22 19:02:02 +02002739 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002740 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002741 Ref2()->assert_equal(1234)
2742 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002743
Bram Moolenaar53900992020-08-22 19:02:02 +02002744 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002745 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002746 Ref2(13)->assert_equal(13)
2747 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002748enddef
2749
Bram Moolenaar9978d472020-07-05 16:01:56 +02002750def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002751 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002752 for n in repeat([1], 3)
2753 res += n
2754 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002755 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002756
2757 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002758 for n in repeat(0z01, 3)->blob2list()
2759 res += n
2760 endfor
2761 res->assert_equal(3)
2762
2763 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002764 for n in add([1, 2], 3)
2765 res += n
2766 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002767 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002768enddef
2769
Bram Moolenaar846178a2020-07-05 17:04:13 +02002770def Test_argv_return_type()
2771 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002772 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002773 for name in argv()
2774 res ..= name
2775 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002776 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002777enddef
2778
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002779def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002780 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002781 RefVoid = g:FuncNoArgNoRet
2782 RefVoid = g:FuncOneArgNoRet
2783 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 +00002784 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 +02002785
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002786 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002787 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002788 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002789 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2790 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 +02002791
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002792 var RefAnyNoArgs: func: any = RefAny
2793
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002794 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002795 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002796 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002797 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 +00002798 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 +02002799
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002800 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002801 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002802 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002803 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2804 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 +02002805enddef
2806
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002807def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002808 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002809
Bram Moolenaar62aec932022-01-29 21:45:34 +00002810 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2811 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002812 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 +00002813 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2814 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 +02002815 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 +02002816
Bram Moolenaar62aec932022-01-29 21:45:34 +00002817 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2818 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2819 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:')
2820 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002821enddef
2822
Bram Moolenaar89228602020-04-05 22:14:54 +02002823def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002824 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002825 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002826 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002827
2828 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002829 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002830
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002831 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002832 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002833 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002834
Bram Moolenaar62aec932022-01-29 21:45:34 +00002835 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002836enddef
2837
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002838def Test_func_common_type()
2839 def FuncOne(n: number): number
2840 return n
2841 enddef
2842 def FuncTwo(s: string): number
2843 return len(s)
2844 enddef
2845 def FuncThree(n: number, s: string): number
2846 return n + len(s)
2847 enddef
2848 var list = [FuncOne, FuncTwo, FuncThree]
2849 assert_equal(8, list[0](8))
2850 assert_equal(4, list[1]('word'))
2851 assert_equal(7, list[2](3, 'word'))
2852enddef
2853
Bram Moolenaar62aec932022-01-29 21:45:34 +00002854def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002855 arg1: string,
2856 arg2 = 1234,
2857 ...rest: list<string>
2858 ): string
2859 return arg1 .. arg2 .. join(rest, '-')
2860enddef
2861
Bram Moolenaar2c330432020-04-13 14:41:35 +02002862def MultiLineComment(
2863 arg1: string, # comment
2864 arg2 = 1234, # comment
2865 ...rest: list<string> # comment
2866 ): string # comment
2867 return arg1 .. arg2 .. join(rest, '-')
2868enddef
2869
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002870def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002871 MultiLine('text')->assert_equal('text1234')
2872 MultiLine('text', 777)->assert_equal('text777')
2873 MultiLine('text', 777, 'one')->assert_equal('text777one')
2874 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002875enddef
2876
Bram Moolenaar23e03252020-04-12 22:22:31 +02002877func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002878 call s:MultiLine('text')->assert_equal('text1234')
2879 call s:MultiLine('text', 777)->assert_equal('text777')
2880 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2881 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002882endfunc
2883
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002884
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002885" When using CheckScriptFailure() for the below test, E1010 is generated instead
2886" of E1056.
2887func Test_E1056_1059()
2888 let caught_1056 = 0
2889 try
2890 def F():
2891 return 1
2892 enddef
2893 catch /E1056:/
2894 let caught_1056 = 1
2895 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002896 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002897
2898 let caught_1059 = 0
2899 try
2900 def F5(items : list)
2901 echo 'a'
2902 enddef
2903 catch /E1059:/
2904 let caught_1059 = 1
2905 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002906 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002907endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002908
Bram Moolenaar015f4262020-05-05 21:25:22 +02002909func DelMe()
2910 echo 'DelMe'
2911endfunc
2912
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002913def Test_error_reporting()
2914 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002915 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002916 " comment
2917 def Func()
2918 # comment
2919 # comment
2920 invalid
2921 enddef
2922 defcompile
2923 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002924 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002925 try
2926 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002927 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002928 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002929 v:exception->assert_match('Invalid command: invalid')
2930 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002931 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002932 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002933
2934 # comment lines after the start of the function
2935 lines =<< trim END
2936 " comment
2937 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002938 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002939 # comment
2940 # comment
2941 invalid
2942 enddef
2943 defcompile
2944 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002945 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002946 try
2947 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002948 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002949 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002950 v:exception->assert_match('Invalid command: invalid')
2951 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002952 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002953 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002954
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002955 lines =<< trim END
2956 vim9script
2957 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002958 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002959 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002960 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002961 enddef
2962 defcompile
2963 Func()
2964 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002965 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002966 try
2967 source Xdef
2968 assert_report('should have failed')
2969 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002970 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002971 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002972 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002973enddef
2974
Bram Moolenaar015f4262020-05-05 21:25:22 +02002975def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002976 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002977 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002978 'delfunc g:DelMe',
2979 'echo RefMe()'], 'E117:')
2980enddef
2981
2982def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002983 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002984 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002985 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002986enddef
2987
Bram Moolenaar62aec932022-01-29 21:45:34 +00002988def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002989 return Ref('more')
2990enddef
2991
2992def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002993 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002994 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002995enddef
2996
Bram Moolenaar62aec932022-01-29 21:45:34 +00002997def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002998 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002999 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003000enddef
3001
3002def Test_closure_ref_after_return()
3003 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003004 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003005 unlet g:Ref
3006enddef
3007
Bram Moolenaar62aec932022-01-29 21:45:34 +00003008def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003009 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003010 g:Extend = (s) => local->add(s)
3011 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003012enddef
3013
3014def Test_closure_two_refs()
3015 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003016 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003017 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003018 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003019 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003020 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003021
3022 unlet g:Extend
3023 unlet g:Read
3024enddef
3025
Bram Moolenaar62aec932022-01-29 21:45:34 +00003026def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003027 return join(Ref(), ' ')
3028enddef
3029
Bram Moolenaar62aec932022-01-29 21:45:34 +00003030def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003031 Ref(add)
3032enddef
3033
3034def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02003035 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003036 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003037 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003038 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003039 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003040 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003041
3042 unlet g:Extend
3043 unlet g:Read
3044enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003045
Bram Moolenaar62aec932022-01-29 21:45:34 +00003046def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003047 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003048 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003049enddef
3050
Bram Moolenaar62aec932022-01-29 21:45:34 +00003051def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003052 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003053 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003054enddef
3055
3056def Test_closure_using_argument()
3057 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003058 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003059
3060 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003061 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003062
3063 unlet g:UseArg
3064 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003065
3066 var lines =<< trim END
3067 vim9script
3068 def Test(Fun: func(number): number): list<number>
3069 return map([1, 2, 3], (_, i) => Fun(i))
3070 enddef
3071 def Inc(nr: number): number
3072 return nr + 2
3073 enddef
3074 assert_equal([3, 4, 5], Test(Inc))
3075 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003076 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003077enddef
3078
Bram Moolenaar62aec932022-01-29 21:45:34 +00003079def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003080 var local = 'a'
3081
3082 def Append(arg: string)
3083 local ..= arg
3084 enddef
3085 g:Append = Append
3086
3087 def Get(): string
3088 return local
3089 enddef
3090 g:Get = Get
3091enddef
3092
3093def Test_closure_append_get()
3094 MakeGetAndAppendRefs()
3095 g:Get()->assert_equal('a')
3096 g:Append('-b')
3097 g:Get()->assert_equal('a-b')
3098 g:Append('-c')
3099 g:Get()->assert_equal('a-b-c')
3100
3101 unlet g:Append
3102 unlet g:Get
3103enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003104
Bram Moolenaar04b12692020-05-04 23:24:44 +02003105def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003106 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003107 def Closure(arg: string): string
3108 return local .. arg
3109 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003110 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003111enddef
3112
Bram Moolenaar62aec932022-01-29 21:45:34 +00003113func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003114 return a:Ref('some')
3115endfunc
3116
3117def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003118 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003119 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003120 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003121enddef
3122
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003123def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003124 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003125 vim9script
3126 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003127 var name = 0
3128 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003129 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003130 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003131 enddef
3132 Func()
3133 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003134 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003135enddef
3136
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003137def Test_nested_closure_used()
3138 var lines =<< trim END
3139 vim9script
3140 def Func()
3141 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003142 var Closure = () => x
3143 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003144 enddef
3145 Func()
3146 assert_equal('hello', g:Myclosure())
3147 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003148 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003149enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003150
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003151def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003152 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003153 vim9script
3154 def FuncA()
3155 FuncB(0)
3156 enddef
3157 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003158 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003159 enddef
3160 FuncA()
3161 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003162 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003163enddef
3164
Bram Moolenaar6de22962022-09-09 21:35:36 +01003165def Run_Test_closure_in_for_loop_fails()
3166 var lines =<< trim END
3167 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003168 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003169 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003170 # time should be enough for startup to finish
3171 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003172 echo n
3173 })
3174 endfor
3175 END
3176 writefile(lines, 'XTest_closure_fails', 'D')
3177
3178 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003179 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003180 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003181
3182 # clean up
3183 g:StopVimInTerminal(buf)
3184enddef
3185
3186func Test_closure_in_for_loop_fails()
3187 CheckScreendump
3188 call Run_Test_closure_in_for_loop_fails()
3189endfunc
3190
Bram Moolenaarf112f302020-12-20 17:47:52 +01003191def Test_global_closure()
3192 var lines =<< trim END
3193 vim9script
3194 def ReverseEveryNLines(n: number, line1: number, line2: number)
3195 var mods = 'sil keepj keepp lockm '
3196 var range = ':' .. line1 .. ',' .. line2
3197 def g:Offset(): number
3198 var offset = (line('.') - line1 + 1) % n
3199 return offset != 0 ? offset : n
3200 enddef
3201 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3202 enddef
3203
3204 new
3205 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3206 ReverseEveryNLines(3, 1, 9)
3207 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003208 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003209 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3210 assert_equal(expected, getline(1, 9))
3211 bwipe!
3212enddef
3213
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003214def Test_global_closure_called_directly()
3215 var lines =<< trim END
3216 vim9script
3217 def Outer()
3218 var x = 1
3219 def g:Inner()
3220 var y = x
3221 x += 1
3222 assert_equal(1, y)
3223 enddef
3224 g:Inner()
3225 assert_equal(2, x)
3226 enddef
3227 Outer()
3228 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003229 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003230 delfunc g:Inner
3231enddef
3232
Bram Moolenaar69c76172021-12-02 16:38:52 +00003233def Test_closure_called_from_legacy()
3234 var lines =<< trim END
3235 vim9script
3236 def Func()
3237 var outer = 'foo'
3238 var F = () => {
3239 outer = 'bar'
3240 }
3241 execute printf('call %s()', string(F))
3242 enddef
3243 Func()
3244 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003245 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003246enddef
3247
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003248def Test_failure_in_called_function()
3249 # this was using the frame index as the return value
3250 var lines =<< trim END
3251 vim9script
3252 au TerminalWinOpen * eval [][0]
3253 def PopupTerm(a: any)
3254 # make sure typvals on stack are string
3255 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3256 FireEvent()
3257 enddef
3258 def FireEvent()
3259 do TerminalWinOpen
3260 enddef
3261 # use try/catch to make eval fail
3262 try
3263 call PopupTerm(0)
3264 catch
3265 endtry
3266 au! TerminalWinOpen
3267 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003268 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003269enddef
3270
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003271def Test_nested_lambda()
3272 var lines =<< trim END
3273 vim9script
3274 def Func()
3275 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003276 var Lambda1 = () => 7
3277 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003278 var res = Lambda2()
3279 assert_equal([7, 4], res)
3280 enddef
3281 Func()
3282 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003283 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003284enddef
3285
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003286def Test_double_nested_lambda()
3287 var lines =<< trim END
3288 vim9script
3289 def F(head: string): func(string): func(string): string
3290 return (sep: string): func(string): string => ((tail: string): string => {
3291 return head .. sep .. tail
3292 })
3293 enddef
3294 assert_equal('hello-there', F('hello')('-')('there'))
3295 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003296 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003297enddef
3298
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003299def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003300 var lines =<< trim END
3301 vim9script
3302 def F(text: string): func(string): func(string): string
3303 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003304 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003305 })
3306 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003307 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003308 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003309 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003310
3311 lines =<< trim END
3312 vim9script
3313 echo range(4)->mapnew((_, v) => {
3314 return range(v) ->mapnew((_, s) => {
3315 return string(s)
3316 })
3317 })
3318 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003319 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003320
3321 lines =<< trim END
3322 vim9script
3323
Bram Moolenaara749a422022-02-12 19:52:25 +00003324 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003325 range(10)
3326 ->mapnew((_, _) => ({
3327 key: range(10)->mapnew((_, _) => {
3328 return ' '
3329 }),
3330 }))
3331 enddef
3332
3333 defcomp
3334 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003335 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003336enddef
3337
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003338def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003339 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003340 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003341enddef
3342
3343def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003344 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003345enddef
3346
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003347def Test_compiling_referenced_func_no_shadow()
3348 var lines =<< trim END
3349 vim9script
3350
3351 def InitializeReply(lspserver: dict<any>)
3352 enddef
3353
3354 def ProcessReply(lspserver: dict<any>)
3355 var lsp_reply_handlers: dict<func> =
3356 { 'initialize': InitializeReply }
3357 lsp_reply_handlers['initialize'](lspserver)
3358 enddef
3359
3360 call ProcessReply({})
3361 END
3362 v9.CheckScriptSuccess(lines)
3363enddef
3364
Bram Moolenaar62aec932022-01-29 21:45:34 +00003365def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003366 var path: string = empty(dir)
3367 \ ? 'empty'
3368 \ : 'full'
3369 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003370enddef
3371
3372def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003373 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003374enddef
3375
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003376def Test_script_var_in_lambda()
3377 var lines =<< trim END
3378 vim9script
3379 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003380 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003381 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003382 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003383enddef
3384
Bram Moolenaar62aec932022-01-29 21:45:34 +00003385def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003386 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003387 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003388 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003389 ->reverse()
3390 return x
3391enddef
3392
3393def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003394 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003395
3396 var lines =<< trim END
3397 vim9script
3398 var res = [{n: 1, m: 2, s: 'xxx'}]
3399 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3400 v.n,
3401 v.m,
3402 substitute(v.s, '.*', 'yyy', '')
3403 ))
3404 assert_equal(['1:2:yyy'], res)
3405 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003406 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003407enddef
3408
Bram Moolenaarb6571982021-01-08 22:24:19 +01003409def Test_list_lambda()
3410 timer_start(1000, (_) => 0)
3411 var body = execute(timer_info()[0].callback
3412 ->string()
3413 ->substitute("('", ' ', '')
3414 ->substitute("')", '', '')
3415 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003416 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003417enddef
3418
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003419def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003420 var lines =<< trim END
3421 vim9script
3422 var flist: list<func>
3423 for i in range(10)
3424 var inloop = i
3425 flist[i] = () => inloop
3426 endfor
3427 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003428 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003429
3430 lines =<< trim END
3431 vim9script
3432 if true
3433 var outloop = 5
3434 var flist: list<func>
3435 for i in range(10)
3436 flist[i] = () => outloop
3437 endfor
3438 endif
3439 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003440 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003441
3442 lines =<< trim END
3443 vim9script
3444 if true
3445 var outloop = 5
3446 endif
3447 var flist: list<func>
3448 for i in range(10)
3449 flist[i] = () => outloop
3450 endfor
3451 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003452 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003453
3454 lines =<< trim END
3455 vim9script
3456 for i in range(10)
3457 var Ref = () => 0
3458 endfor
3459 assert_equal(0, ((i) => 0)(0))
3460 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003461 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003462enddef
3463
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003464def Test_legacy_lambda()
3465 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003466
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003467 var lines =<< trim END
3468 echo {x -> 'hello ' .. x}('foo')
3469 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003470 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003471
3472 lines =<< trim END
3473 vim9script
3474 def Func()
3475 echo (() => 'no error')()
3476 enddef
3477 legacy call s:Func()
3478 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003479 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003480enddef
3481
Bram Moolenaarce024c32021-06-26 13:00:49 +02003482def Test_legacy()
3483 var lines =<< trim END
3484 vim9script
3485 func g:LegacyFunction()
3486 let g:legacyvar = 1
3487 endfunc
3488 def Testit()
3489 legacy call g:LegacyFunction()
3490 enddef
3491 Testit()
3492 assert_equal(1, g:legacyvar)
3493 unlet g:legacyvar
3494 delfunc g:LegacyFunction
3495 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003496 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003497enddef
3498
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003499def Test_legacy_errors()
3500 for cmd in ['if', 'elseif', 'else', 'endif',
3501 'for', 'endfor', 'continue', 'break',
3502 'while', 'endwhile',
3503 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003504 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003505 endfor
3506enddef
3507
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003508def Test_call_legacy_with_dict()
3509 var lines =<< trim END
3510 vim9script
3511 func Legacy() dict
3512 let g:result = self.value
3513 endfunc
3514 def TestDirect()
3515 var d = {value: 'yes', func: Legacy}
3516 d.func()
3517 enddef
3518 TestDirect()
3519 assert_equal('yes', g:result)
3520 unlet g:result
3521
3522 def TestIndirect()
3523 var d = {value: 'foo', func: Legacy}
3524 var Fi = d.func
3525 Fi()
3526 enddef
3527 TestIndirect()
3528 assert_equal('foo', g:result)
3529 unlet g:result
3530
3531 var d = {value: 'bar', func: Legacy}
3532 d.func()
3533 assert_equal('bar', g:result)
3534 unlet g:result
3535 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003536 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003537enddef
3538
Bram Moolenaar62aec932022-01-29 21:45:34 +00003539def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003540 # closure nested inside another closure using argument
3541 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3542 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3543enddef
3544
3545def Test_nested_closure_using_argument()
3546 assert_equal(['x', 'x2'], DoFilterThis('x'))
3547enddef
3548
Bram Moolenaar0186e582021-01-10 18:33:11 +01003549def Test_triple_nested_closure()
3550 var what = 'x'
3551 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3552 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3553 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3554enddef
3555
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003556func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003557 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003558 call Run_Test_silent_echo()
3559endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003560
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003561def Run_Test_silent_echo()
3562 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003563 vim9script
3564 def EchoNothing()
3565 silent echo ''
3566 enddef
3567 defcompile
3568 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003569 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003570
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003571 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003572 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003573 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003574 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003575
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003576 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003577 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003578enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003579
Bram Moolenaar171fb922020-10-28 16:54:47 +01003580def SilentlyError()
3581 execute('silent! invalid')
3582 g:did_it = 'yes'
3583enddef
3584
Bram Moolenaar62aec932022-01-29 21:45:34 +00003585func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003586 silent! invalid
3587endfunc
3588
3589def SilentlyUserError()
3590 UserError()
3591 g:did_it = 'yes'
3592enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003593
3594" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003595func Test_ignore_silent_error()
3596 let g:did_it = 'no'
3597 call SilentlyError()
3598 call assert_equal('yes', g:did_it)
3599
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003600 let g:did_it = 'no'
3601 call SilentlyUserError()
3602 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003603
3604 unlet g:did_it
3605endfunc
3606
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003607def Test_ignore_silent_error_in_filter()
3608 var lines =<< trim END
3609 vim9script
3610 def Filter(winid: number, key: string): bool
3611 if key == 'o'
3612 silent! eval [][0]
3613 return true
3614 endif
3615 return popup_filter_menu(winid, key)
3616 enddef
3617
Bram Moolenaare0de1712020-12-02 17:36:54 +01003618 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003619 feedkeys("o\r", 'xnt')
3620 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003621 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003622enddef
3623
Bram Moolenaar62aec932022-01-29 21:45:34 +00003624def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003625 if n < 2
3626 return n
3627 else
3628 return Fibonacci(n - 1) + Fibonacci(n - 2)
3629 endif
3630enddef
3631
Bram Moolenaar985116a2020-07-12 17:31:09 +02003632def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003633 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003634enddef
3635
Bram Moolenaar62aec932022-01-29 21:45:34 +00003636def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003637 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003638 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003639 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003640 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003641 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003642enddef
3643
3644def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003645 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003646 writefile(['111'], 'XclosureDir/file1')
3647 writefile(['222'], 'XclosureDir/file2')
3648 writefile(['333'], 'XclosureDir/tdir/file3')
3649
Bram Moolenaare0de1712020-12-02 17:36:54 +01003650 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003651enddef
3652
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003653def Test_invalid_function_name()
3654 var lines =<< trim END
3655 vim9script
3656 def s: list<string>
3657 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003658 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003659
3660 lines =<< trim END
3661 vim9script
3662 def g: list<string>
3663 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003664 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003665
3666 lines =<< trim END
3667 vim9script
3668 def <SID>: list<string>
3669 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003670 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003671
3672 lines =<< trim END
3673 vim9script
3674 def F list<string>
3675 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003676 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003677enddef
3678
Bram Moolenaara90afb92020-07-15 22:38:56 +02003679def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003680 var lines =<< trim END
3681 var Xsetlist: func
3682 Xsetlist = function('setloclist', [0])
3683 Xsetlist([], ' ', {title: 'test'})
3684 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003685
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003686 Xsetlist = function('setloclist', [0, [], ' '])
3687 Xsetlist({title: 'test'})
3688 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003689
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003690 Xsetlist = function('setqflist')
3691 Xsetlist([], ' ', {title: 'test'})
3692 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003693
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003694 Xsetlist = function('setqflist', [[], ' '])
3695 Xsetlist({title: 'test'})
3696 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003697
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003698 var Len: func: number = function('len', ['word'])
3699 assert_equal(4, Len())
3700
3701 var RepeatFunc = function('repeat', ['o'])
3702 assert_equal('ooooo', RepeatFunc(5))
3703 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003704 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003705
3706 lines =<< trim END
3707 vim9script
3708 def Foo(Parser: any)
3709 enddef
3710 var Expr: func(dict<any>): dict<any>
3711 const Call = Foo(Expr)
3712 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003713 v9.CheckScriptFailure(lines, 'E1031:')
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02003714
3715 # Test for calling a partial that takes a single argument.
3716 # This used to produce a "E340: Internal error" message.
3717 lines =<< trim END
3718 def Foo(n: number): number
3719 return n * 2
3720 enddef
3721 var Fn = function(Foo, [10])
3722 assert_equal(20, Fn())
3723 END
3724 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara90afb92020-07-15 22:38:56 +02003725enddef
3726
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003727def Test_partial_double_nested()
3728 var idx = 123
3729 var Get = () => idx
3730 var Ref = function(Get, [])
3731 var RefRef = function(Ref, [])
3732 assert_equal(123, RefRef())
3733enddef
3734
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003735def Test_partial_null_function()
3736 var lines =<< trim END
3737 var d: dict<func> = {f: null_function}
3738 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003739 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003740 END
3741 v9.CheckDefAndScriptSuccess(lines)
3742enddef
3743
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003744def Test_cmd_modifier()
3745 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003746 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003747enddef
3748
3749def Test_restore_modifiers()
3750 # check that when compiling a :def function command modifiers are not messed
3751 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003752 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003753 vim9script
3754 set eventignore=
3755 autocmd QuickFixCmdPost * copen
3756 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003757 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003758 enddef
3759 func Func()
3760 noautocmd call s:AutocmdsDisabled()
3761 let g:ei_after = &eventignore
3762 endfunc
3763 Func()
3764 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003765 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003766 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003767enddef
3768
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003769def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003770 eval 1 + 2
3771 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003772 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003773 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003774enddef
3775
3776def StackBot()
3777 # throw an error
3778 eval [][0]
3779enddef
3780
3781def Test_callstack_def()
3782 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003783 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003784 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003785 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003786 endtry
3787enddef
3788
Bram Moolenaare8211a32020-10-09 22:04:29 +02003789" Re-using spot for variable used in block
3790def Test_block_scoped_var()
3791 var lines =<< trim END
3792 vim9script
3793 def Func()
3794 var x = ['a', 'b', 'c']
3795 if 1
3796 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003797 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003798 endif
3799 var z = x
3800 assert_equal(['x', 'x', 'x'], z)
3801 enddef
3802 Func()
3803 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003804 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003805enddef
3806
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003807def Test_reset_did_emsg()
3808 var lines =<< trim END
3809 @s = 'blah'
3810 au BufWinLeave * #
3811 def Func()
3812 var winid = popup_create('popup', {})
3813 exe '*s'
3814 popup_close(winid)
3815 enddef
3816 Func()
3817 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003818 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003819 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003820enddef
3821
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003822def Test_did_emsg_reset()
3823 # executing an autocommand resets did_emsg, this should not result in a
3824 # builtin function considered failing
3825 var lines =<< trim END
3826 vim9script
3827 au BufWinLeave * #
3828 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003829 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003830 eval [][0]
3831 enddef
3832 nno <F3> <cmd>call <sid>Func()<cr>
3833 feedkeys("\<F3>\e", 'xt')
3834 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003835 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003836 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003837
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003838 nunmap <F3>
3839 au! BufWinLeave
3840enddef
3841
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003842def Test_abort_with_silent_call()
3843 var lines =<< trim END
3844 vim9script
3845 g:result = 'none'
3846 def Func()
3847 g:result += 3
3848 g:result = 'yes'
3849 enddef
3850 # error is silenced, but function aborts on error
3851 silent! Func()
3852 assert_equal('none', g:result)
3853 unlet g:result
3854 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003855 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003856enddef
3857
Bram Moolenaarf665e972020-12-05 19:17:16 +01003858def Test_continues_with_silent_error()
3859 var lines =<< trim END
3860 vim9script
3861 g:result = 'none'
3862 def Func()
3863 silent! g:result += 3
3864 g:result = 'yes'
3865 enddef
3866 # error is silenced, function does not abort
3867 Func()
3868 assert_equal('yes', g:result)
3869 unlet g:result
3870 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003871 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003872enddef
3873
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003874def Test_abort_even_with_silent()
3875 var lines =<< trim END
3876 vim9script
3877 g:result = 'none'
3878 def Func()
3879 eval {-> ''}() .. '' .. {}['X']
3880 g:result = 'yes'
3881 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003882 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003883 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003884 unlet g:result
3885 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003886 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003887enddef
3888
Bram Moolenaarf665e972020-12-05 19:17:16 +01003889def Test_cmdmod_silent_restored()
3890 var lines =<< trim END
3891 vim9script
3892 def Func()
3893 g:result = 'none'
3894 silent! g:result += 3
3895 g:result = 'none'
3896 g:result += 3
3897 enddef
3898 Func()
3899 END
3900 # can't use CheckScriptFailure, it ignores the :silent!
3901 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003902 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003903 var caught = 'no'
3904 try
3905 exe 'source ' .. fname
3906 catch /E1030:/
3907 caught = 'yes'
3908 assert_match('Func, line 4', v:throwpoint)
3909 endtry
3910 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003911enddef
3912
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003913def Test_cmdmod_silent_nested()
3914 var lines =<< trim END
3915 vim9script
3916 var result = ''
3917
3918 def Error()
3919 result ..= 'Eb'
3920 eval [][0]
3921 result ..= 'Ea'
3922 enddef
3923
3924 def Crash()
3925 result ..= 'Cb'
3926 sil! Error()
3927 result ..= 'Ca'
3928 enddef
3929
3930 Crash()
3931 assert_equal('CbEbEaCa', result)
3932 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003933 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003934enddef
3935
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003936def Test_dict_member_with_silent()
3937 var lines =<< trim END
3938 vim9script
3939 g:result = 'none'
3940 var d: dict<any>
3941 def Func()
3942 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003943 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003944 catch
3945 endtry
3946 enddef
3947 silent! Func()
3948 assert_equal('0', g:result)
3949 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003950 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003951 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003952enddef
3953
Bram Moolenaarf9041332021-01-21 19:41:16 +01003954def Test_skip_cmds_with_silent()
3955 var lines =<< trim END
3956 vim9script
3957
3958 def Func(b: bool)
3959 Crash()
3960 enddef
3961
3962 def Crash()
3963 sil! :/not found/d _
3964 sil! :/not found/put _
3965 enddef
3966
3967 Func(true)
3968 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003969 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003970enddef
3971
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003972def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003973 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003974 def g:Opfunc(_: any): string
3975 setline(1, 'ASDF')
3976 return ''
3977 enddef
3978 new
3979 setline(1, 'asdf')
3980 feedkeys("\<F3>$", 'x')
3981 assert_equal('ASDF', getline(1))
3982
3983 bwipe!
3984 nunmap <F3>
3985enddef
3986
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003987func Test_opfunc_error()
3988 CheckScreendump
3989 call Run_Test_opfunc_error()
3990endfunc
3991
3992def Run_Test_opfunc_error()
3993 # test that the error from Opfunc() is displayed right away
3994 var lines =<< trim END
3995 vim9script
3996
3997 def Opfunc(type: string)
3998 try
3999 eval [][0]
4000 catch /nothing/ # error not caught
4001 endtry
4002 enddef
4003 &operatorfunc = Opfunc
4004 nnoremap <expr> l <SID>L()
4005 def L(): string
4006 return 'l'
4007 enddef
4008 'x'->repeat(10)->setline(1)
4009 feedkeys('g@l', 'n')
4010 feedkeys('llll')
4011 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004012 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004013
Bram Moolenaar62aec932022-01-29 21:45:34 +00004014 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
4015 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01004016 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004017
4018 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00004019 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004020enddef
4021
Bram Moolenaar077a4232020-12-22 18:33:27 +01004022" this was crashing on exit
4023def Test_nested_lambda_in_closure()
4024 var lines =<< trim END
4025 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004026 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004027 def Outer()
4028 def g:Inner()
4029 echo map([1, 2, 3], {_, v -> v + 1})
4030 enddef
4031 g:Inner()
4032 enddef
4033 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004034 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01004035 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004036 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004037 return
4038 endif
4039 assert_equal(['Done'], readfile('XnestedDone'))
4040 delete('XnestedDone')
4041enddef
4042
Bram Moolenaar92368aa2022-02-07 17:50:39 +00004043def Test_nested_closure_funcref()
4044 var lines =<< trim END
4045 vim9script
4046 def Func()
4047 var n: number
4048 def Nested()
4049 ++n
4050 enddef
4051 Nested()
4052 g:result_one = n
4053 var Ref = function(Nested)
4054 Ref()
4055 g:result_two = n
4056 enddef
4057 Func()
4058 END
4059 v9.CheckScriptSuccess(lines)
4060 assert_equal(1, g:result_one)
4061 assert_equal(2, g:result_two)
4062 unlet g:result_one g:result_two
4063enddef
4064
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004065def Test_nested_closure_in_dict()
4066 var lines =<< trim END
4067 vim9script
4068 def Func(): dict<any>
4069 var n: number
4070 def Inc(): number
4071 ++n
4072 return n
4073 enddef
4074 return {inc: function(Inc)}
4075 enddef
4076 disas Func
4077 var d = Func()
4078 assert_equal(1, d.inc())
4079 assert_equal(2, d.inc())
4080 END
4081 v9.CheckScriptSuccess(lines)
4082enddef
4083
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004084def Test_script_local_other_script()
4085 var lines =<< trim END
4086 function LegacyJob()
4087 let FuncRef = function('s:close_cb')
4088 endfunction
4089 function s:close_cb(...)
4090 endfunction
4091 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004092 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004093 source Xlegacy.vim
4094 g:LegacyJob()
4095 g:LegacyJob()
4096 g:LegacyJob()
4097
4098 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004099enddef
4100
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004101def Test_check_func_arg_types()
4102 var lines =<< trim END
4103 vim9script
4104 def F1(x: string): string
4105 return x
4106 enddef
4107
4108 def F2(x: number): number
4109 return x + 1
4110 enddef
4111
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004112 def G(Fg: func): dict<func>
4113 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004114 enddef
4115
4116 def H(d: dict<func>): string
4117 return d.f('a')
4118 enddef
4119 END
4120
Bram Moolenaar62aec932022-01-29 21:45:34 +00004121 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4122 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004123
4124 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004125enddef
4126
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004127def Test_call_func_with_null()
4128 var lines =<< trim END
4129 def Fstring(v: string)
4130 assert_equal(null_string, v)
4131 enddef
4132 Fstring(null_string)
4133 def Fblob(v: blob)
4134 assert_equal(null_blob, v)
4135 enddef
4136 Fblob(null_blob)
4137 def Flist(v: list<number>)
4138 assert_equal(null_list, v)
4139 enddef
4140 Flist(null_list)
4141 def Fdict(v: dict<number>)
4142 assert_equal(null_dict, v)
4143 enddef
4144 Fdict(null_dict)
4145 def Ffunc(Fv: func(number): number)
4146 assert_equal(null_function, Fv)
4147 enddef
4148 Ffunc(null_function)
4149 if has('channel')
4150 def Fchannel(v: channel)
4151 assert_equal(null_channel, v)
4152 enddef
4153 Fchannel(null_channel)
4154 def Fjob(v: job)
4155 assert_equal(null_job, v)
4156 enddef
4157 Fjob(null_job)
4158 endif
4159 END
4160 v9.CheckDefAndScriptSuccess(lines)
4161enddef
4162
4163def Test_null_default_argument()
4164 var lines =<< trim END
4165 def Fstring(v: string = null_string)
4166 assert_equal(null_string, v)
4167 enddef
4168 Fstring()
4169 def Fblob(v: blob = null_blob)
4170 assert_equal(null_blob, v)
4171 enddef
4172 Fblob()
4173 def Flist(v: list<number> = null_list)
4174 assert_equal(null_list, v)
4175 enddef
4176 Flist()
4177 def Fdict(v: dict<number> = null_dict)
4178 assert_equal(null_dict, v)
4179 enddef
4180 Fdict()
4181 def Ffunc(Fv: func(number): number = null_function)
4182 assert_equal(null_function, Fv)
4183 enddef
4184 Ffunc()
4185 if has('channel')
4186 def Fchannel(v: channel = null_channel)
4187 assert_equal(null_channel, v)
4188 enddef
4189 Fchannel()
4190 def Fjob(v: job = null_job)
4191 assert_equal(null_job, v)
4192 enddef
4193 Fjob()
4194 endif
4195 END
4196 v9.CheckDefAndScriptSuccess(lines)
4197enddef
4198
4199def Test_null_return()
4200 var lines =<< trim END
4201 def Fstring(): string
4202 return null_string
4203 enddef
4204 assert_equal(null_string, Fstring())
4205 def Fblob(): blob
4206 return null_blob
4207 enddef
4208 assert_equal(null_blob, Fblob())
4209 def Flist(): list<number>
4210 return null_list
4211 enddef
4212 assert_equal(null_list, Flist())
4213 def Fdict(): dict<number>
4214 return null_dict
4215 enddef
4216 assert_equal(null_dict, Fdict())
4217 def Ffunc(): func(number): number
4218 return null_function
4219 enddef
4220 assert_equal(null_function, Ffunc())
4221 if has('channel')
4222 def Fchannel(): channel
4223 return null_channel
4224 enddef
4225 assert_equal(null_channel, Fchannel())
4226 def Fjob(): job
4227 return null_job
4228 enddef
4229 assert_equal(null_job, Fjob())
4230 endif
4231 END
4232 v9.CheckDefAndScriptSuccess(lines)
4233enddef
4234
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004235def Test_list_any_type_checked()
4236 var lines =<< trim END
4237 vim9script
4238 def Foo()
4239 --decl--
4240 Bar(l)
4241 enddef
4242 def Bar(ll: list<dict<any>>)
4243 enddef
4244 Foo()
4245 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004246 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004247 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004248 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004249 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004250 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004251
4252 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004253 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004254enddef
4255
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004256def Test_compile_error()
4257 var lines =<< trim END
4258 def g:Broken()
4259 echo 'a' + {}
4260 enddef
4261 call g:Broken()
4262 END
4263 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004264 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004265
4266 # Second call won't try compiling again
4267 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004268 delfunc g:Broken
4269
4270 # No error when compiling with :silent!
4271 lines =<< trim END
4272 def g:Broken()
4273 echo 'a' + []
4274 enddef
4275 silent! defcompile
4276 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004277 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004278
4279 # Calling the function won't try compiling again
4280 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4281 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004282enddef
4283
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004284def Test_ignored_argument()
4285 var lines =<< trim END
4286 vim9script
4287 def Ignore(_, _): string
4288 return 'yes'
4289 enddef
4290 assert_equal('yes', Ignore(1, 2))
4291
4292 func Ok(_)
4293 return a:_
4294 endfunc
4295 assert_equal('ok', Ok('ok'))
4296
4297 func Oktoo()
4298 let _ = 'too'
4299 return _
4300 endfunc
4301 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004302
4303 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004304 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004305 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004306
4307 lines =<< trim END
4308 def Ignore(_: string): string
4309 return _
4310 enddef
4311 defcompile
4312 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004313 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004314
4315 lines =<< trim END
4316 var _ = 1
4317 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004318 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004319
4320 lines =<< trim END
4321 var x = _
4322 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004323 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004324enddef
4325
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004326def Test_too_many_arguments()
4327 var lines =<< trim END
4328 echo [0, 1, 2]->map(() => 123)
4329 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004330 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004331
4332 lines =<< trim END
4333 echo [0, 1, 2]->map((_) => 123)
4334 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004335 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004336
4337 lines =<< trim END
4338 vim9script
4339 def OneArgument(arg: string)
4340 echo arg
4341 enddef
4342 var Ref = OneArgument
4343 Ref('a', 'b')
4344 END
4345 v9.CheckScriptFailure(lines, 'E118:')
4346enddef
4347
4348def Test_funcref_with_base()
4349 var lines =<< trim END
4350 vim9script
4351 def TwoArguments(str: string, nr: number)
4352 echo str nr
4353 enddef
4354 var Ref = TwoArguments
4355 Ref('a', 12)
4356 'b'->Ref(34)
4357 END
4358 v9.CheckScriptSuccess(lines)
4359
4360 lines =<< trim END
4361 vim9script
4362 def TwoArguments(str: string, nr: number)
4363 echo str nr
4364 enddef
4365 var Ref = TwoArguments
4366 'a'->Ref('b')
4367 END
4368 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4369
4370 lines =<< trim END
4371 vim9script
4372 def TwoArguments(str: string, nr: number)
4373 echo str nr
4374 enddef
4375 var Ref = TwoArguments
4376 123->Ref(456)
4377 END
4378 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4379
4380 lines =<< trim END
4381 vim9script
4382 def TwoArguments(nr: number, str: string)
4383 echo str nr
4384 enddef
4385 var Ref = TwoArguments
4386 123->Ref('b')
4387 def AndNowCompiled()
4388 456->Ref('x')
4389 enddef
4390 AndNowCompiled()
4391 END
4392 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004393enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004394
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004395def Test_closing_brace_at_start_of_line()
4396 var lines =<< trim END
4397 def Func()
4398 enddef
4399 Func(
4400 )
4401 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004402 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004403enddef
4404
Bram Moolenaar62aec932022-01-29 21:45:34 +00004405func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004406 let g:mydict = {}
4407 func g:mydict.afunc()
4408 let g:result = self.key
4409 endfunc
4410endfunc
4411
4412def Test_numbered_function_reference()
4413 CreateMydict()
4414 var output = execute('legacy func g:mydict.afunc')
4415 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4416 execute 'function(' .. funcName .. ', [], {key: 42})()'
4417 # check that the function still exists
4418 assert_equal(output, execute('legacy func g:mydict.afunc'))
4419 unlet g:mydict
4420enddef
4421
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004422def Test_numbered_function_call()
4423 var lines =<< trim END
4424 let s:legacyscript = {}
4425 func s:legacyscript.Helper() abort
4426 return "Success"
4427 endfunc
4428 let g:legacyscript = deepcopy(s:legacyscript)
4429
4430 let g:legacy_result = eval("g:legacyscript.Helper()")
4431 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4432 END
4433 v9.CheckScriptSuccess(lines)
4434 assert_equal('Success', g:legacy_result)
4435 assert_equal('Success', g:vim9_result)
4436
4437 unlet g:legacy_result
4438 unlet g:vim9_result
4439enddef
4440
Bram Moolenaard3a11782022-01-05 16:50:40 +00004441def Test_go_beyond_end_of_cmd()
4442 # this was reading the byte after the end of the line
4443 var lines =<< trim END
4444 def F()
4445 cal
4446 enddef
4447 defcompile
4448 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004449 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004450enddef
4451
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004452" Test for memory allocation failure when defining a new lambda
4453func Test_lambda_allocation_failure()
4454 new
4455 let lines =<< trim END
4456 vim9script
4457 g:Xlambda = (x): number => {
4458 return x + 1
4459 }
4460 END
4461 call setline(1, lines)
4462 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4463 call assert_fails('source', 'E342:')
4464 call assert_false(exists('g:Xlambda'))
4465 bw!
4466endfunc
4467
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004468def Test_lambda_argument_type_check()
4469 var lines =<< trim END
4470 vim9script
4471
4472 def Scan(ll: list<any>): func(func(any))
4473 return (Emit: func(any)) => {
4474 for e in ll
4475 Emit(e)
4476 endfor
4477 }
4478 enddef
4479
4480 def Sum(Cont: func(func(any))): any
4481 var sum = 0.0
4482 Cont((v: float) => { # <== NOTE: the lambda expects a float
4483 sum += v
4484 })
4485 return sum
4486 enddef
4487
Bram Moolenaar47bba532023-01-20 18:49:46 +00004488 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004489 echo Scan(ml)->Sum()
4490 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004491 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004492enddef
4493
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004494def Test_multiple_funcref()
4495 # This was using a NULL pointer
4496 var lines =<< trim END
4497 vim9script
4498 def A(F: func, ...args: list<any>): func
4499 return funcref(F, args)
4500 enddef
4501
4502 def B(F: func): func
4503 return funcref(A, [F])
4504 enddef
4505
4506 def Test(n: number)
4507 enddef
4508
4509 const X = B(Test)
4510 X(1)
4511 END
4512 v9.CheckScriptSuccess(lines)
4513
4514 # slightly different case
4515 lines =<< trim END
4516 vim9script
4517
4518 def A(F: func, ...args: list<any>): any
4519 return call(F, args)
4520 enddef
4521
4522 def B(F: func): func
4523 return funcref(A, [F])
4524 enddef
4525
4526 def Test(n: number)
4527 enddef
4528
4529 const X = B(Test)
4530 X(1)
4531 END
4532 v9.CheckScriptSuccess(lines)
4533enddef
4534
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004535def Test_cexpr_errmsg_line_number()
4536 var lines =<< trim END
4537 vim9script
4538 def Func()
4539 var qfl = {}
4540 cexpr qfl
4541 enddef
4542 Func()
4543 END
4544 v9.CheckScriptFailure(lines, 'E777', 2)
4545enddef
4546
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004547def AddDefer(s: string)
4548 g:deferred->extend([s])
4549enddef
4550
4551def DeferTwo()
4552 g:deferred->extend(['in Two'])
4553 for n in range(3)
4554 defer g:AddDefer('two' .. n)
4555 endfor
4556 g:deferred->extend(['end Two'])
4557enddef
4558
4559def DeferOne()
4560 g:deferred->extend(['in One'])
4561 defer g:AddDefer('one')
4562 g:DeferTwo()
4563 g:deferred->extend(['end One'])
4564
4565 writefile(['text'], 'XdeferFile')
4566 defer delete('XdeferFile')
4567enddef
4568
4569def Test_defer()
4570 g:deferred = []
4571 g:DeferOne()
4572 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4573 unlet g:deferred
4574 assert_equal('', glob('XdeferFile'))
4575enddef
4576
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004577def Test_invalid_redir()
4578 var lines =<< trim END
4579 def Tone()
4580 if 1
4581 redi =>@�0
4582 redi END
4583 endif
4584 enddef
4585 defcompile
4586 END
4587 v9.CheckScriptFailure(lines, 'E354:')
4588 delfunc g:Tone
4589
4590 # this was reading past the end of the line
4591 lines =<< trim END
4592 def Ttwo()
4593 if 0
4594 redi =>@�0
4595 redi END
4596 endif
4597 enddef
4598 defcompile
4599 END
4600 v9.CheckScriptFailure(lines, 'E354:')
4601 delfunc g:Ttwo
4602enddef
4603
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004604func Test_keytyped_in_nested_function()
4605 CheckRunVimInTerminal
4606
4607 call Run_Test_keytyped_in_nested_function()
4608endfunc
4609
4610def Run_Test_keytyped_in_nested_function()
4611 var lines =<< trim END
4612 vim9script
4613 autocmd CmdlineEnter * sample#Init()
4614
4615 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4616 END
4617 writefile(lines, 'Xkeytyped', 'D')
4618
4619 var dir = 'Xrtpdir/autoload'
4620 mkdir(dir, 'pR')
4621
4622 lines =<< trim END
4623 vim9script
4624 export def Init(): void
4625 cnoremap <expr>" <SID>Quote('"')
4626 enddef
4627 def Quote(str: string): string
4628 def InPair(): number
4629 return 0
4630 enddef
4631 return str
4632 enddef
4633 END
4634 writefile(lines, dir .. '/sample.vim')
4635
4636 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4637
4638 term_sendkeys(buf, ':"')
4639 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4640
4641 # clean up
4642 term_sendkeys(buf, "\<Esc>")
4643 g:StopVimInTerminal(buf)
4644enddef
4645
Yegappan Lakshmanan5715a722024-05-03 18:24:07 +02004646" Test for test_override('defcompile')
4647def Test_test_override_defcompile()
4648 var lines =<< trim END
4649 vim9script
4650 def Foo()
4651 xxx
4652 enddef
4653 END
4654 test_override('defcompile', 1)
4655 v9.CheckScriptFailure(lines, 'E476: Invalid command: xxx')
4656 test_override('defcompile', 0)
4657enddef
4658
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004659" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004660if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004661 def Test_python3_command()
4662 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004663 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004664 assert_equal('yes', g:done)
4665 unlet g:done
4666 enddef
4667
Bram Moolenaar20677332021-06-06 17:02:53 +02004668 def Test_python3_heredoc()
4669 py3 << trim EOF
4670 import vim
4671 vim.vars['didit'] = 'yes'
4672 EOF
4673 assert_equal('yes', g:didit)
4674
4675 python3 << trim EOF
4676 import vim
4677 vim.vars['didit'] = 'again'
4678 EOF
4679 assert_equal('again', g:didit)
4680 enddef
4681endif
4682
Bram Moolenaar20677332021-06-06 17:02:53 +02004683if has('lua')
4684 def Test_lua_heredoc()
4685 g:d = {}
4686 lua << trim EOF
4687 x = vim.eval('g:d')
4688 x['key'] = 'val'
4689 EOF
4690 assert_equal('val', g:d.key)
4691 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004692
4693 def Test_lua_heredoc_fails()
4694 var lines = [
4695 'vim9script',
4696 'def ExeLua()',
4697 'lua << trim EOLUA',
4698 "x = vim.eval('g:nodict')",
4699 'EOLUA',
4700 'enddef',
4701 'ExeLua()',
4702 ]
4703 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4704 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004705endif
4706
Bram Moolenaard881d152022-05-13 13:50:36 +01004707if has('perl')
4708 def Test_perl_heredoc_nested()
4709 var lines =<< trim END
4710 vim9script
4711 def F(): string
4712 def G(): string
4713 perl << EOF
4714 EOF
4715 return 'done'
4716 enddef
4717 return G()
4718 enddef
4719 assert_equal('done', F())
4720 END
4721 v9.CheckScriptSuccess(lines)
4722 enddef
4723endif
4724
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004725
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004726" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker