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