blob: e214d9583ba23c87514d9917c234ceed2b4663df [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" Test various aspects of the Vim9 script language.
2
Christian Brabandteb380b92025-07-07 20:53:55 +02003import './util/vim9.vim' as v9
4source util/screendump.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02005
6func Test_def_basic()
7 def SomeFunc(): string
8 return 'yes'
9 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020010 call SomeFunc()->assert_equal('yes')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020011endfunc
12
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020013func Test_compiling_error()
14 " use a terminal to see the whole error message
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020015 CheckRunVimInTerminal
16
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020017 call TestCompilingError()
Bram Moolenaare8c46602021-04-05 22:27:37 +020018 call TestCompilingErrorInTry()
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020019endfunc
20
21def TestCompilingError()
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020022 var lines =<< trim END
23 vim9script
24 def Fails()
25 echo nothing
26 enddef
27 defcompile
28 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +010029 writefile(lines, 'XTest_compile_error', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +000030 var buf = g:RunVimInTerminal('-S XTest_compile_error',
Bram Moolenaare0de1712020-12-02 17:36:54 +010031 {rows: 10, wait_for_ruler: 0})
Bram Moolenaar62aec932022-01-29 21:45:34 +000032 g:WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
33 g:Term_getlines(buf, range(1, 9))))
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020034
35 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +000036 g:StopVimInTerminal(buf)
Bram Moolenaare8c46602021-04-05 22:27:37 +020037enddef
38
39def TestCompilingErrorInTry()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010040 var dir = 'Xcompdir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +010041 mkdir(dir, 'pR')
Bram Moolenaare8c46602021-04-05 22:27:37 +020042
43 var lines =<< trim END
44 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +000045 export def OnlyCompiled()
Bram Moolenaare8c46602021-04-05 22:27:37 +020046 g:runtime = 'yes'
47 invalid
48 enddef
49 END
50 writefile(lines, dir .. '/script.vim')
51
52 lines =<< trim END
53 vim9script
54 todo
55 try
56 script#OnlyCompiled()
57 catch /nothing/
58 endtry
59 END
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010060 lines[1] = 'set rtp=' .. getcwd() .. '/Xcompdir'
Bram Moolenaarf5fec052022-09-11 11:49:22 +010061 writefile(lines, 'XTest_compile_error', 'D')
Bram Moolenaare8c46602021-04-05 22:27:37 +020062
Bram Moolenaar62aec932022-01-29 21:45:34 +000063 var buf = g:RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0})
64 g:WaitForAssert(() => assert_match('Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid',
65 g:Term_getlines(buf, range(1, 9))))
Bram Moolenaare8c46602021-04-05 22:27:37 +020066
67 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +000068 g:StopVimInTerminal(buf)
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020069enddef
70
Bram Moolenaarad6d9cc2022-08-08 21:43:11 +010071def Test_comment_error()
72 v9.CheckDefFailure(['#{ comment'], 'E1170:')
73enddef
74
Bram Moolenaarb55d6182021-06-08 22:01:53 +020075def Test_compile_error_in_called_function()
76 var lines =<< trim END
77 vim9script
78 var n: number
79 def Foo()
80 &hls = n
81 enddef
82 def Bar()
83 Foo()
84 enddef
85 silent! Foo()
86 Bar()
87 END
Bram Moolenaar62aec932022-01-29 21:45:34 +000088 v9.CheckScriptFailureList(lines, ['E1012:', 'E1191:'])
Bram Moolenaarb55d6182021-06-08 22:01:53 +020089enddef
90
Bram Moolenaar22f17a22021-06-21 20:48:58 +020091def Test_wrong_function_name()
92 var lines =<< trim END
93 vim9script
94 func _Foo()
95 echo 'foo'
96 endfunc
97 END
Bram Moolenaar3787f262022-02-07 21:54:01 +000098 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaar22f17a22021-06-21 20:48:58 +020099
100 lines =<< trim END
101 vim9script
102 def _Foo()
103 echo 'foo'
104 enddef
105 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000106 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaardea5ab02022-02-23 22:12:02 +0000107
108 lines =<< trim END
109 vim9script
110 var Object = {}
111 function Object.Method()
112 endfunction
113 END
114 v9.CheckScriptFailure(lines, 'E1182:')
115
116 lines =<< trim END
117 vim9script
118 var Object = {}
119 def Object.Method()
120 enddef
121 END
122 v9.CheckScriptFailure(lines, 'E1182:')
123
124 lines =<< trim END
125 vim9script
126 g:Object = {}
127 function g:Object.Method()
128 endfunction
129 END
130 v9.CheckScriptFailure(lines, 'E1182:')
131
132 lines =<< trim END
133 let s:Object = {}
134 def Define()
135 function s:Object.Method()
136 endfunction
137 enddef
138 defcompile
139 END
140 v9.CheckScriptFailure(lines, 'E1182:')
141 delfunc g:Define
142
143 lines =<< trim END
144 let s:Object = {}
145 def Define()
146 def Object.Method()
147 enddef
148 enddef
149 defcompile
150 END
151 v9.CheckScriptFailure(lines, 'E1182:')
152 delfunc g:Define
153
154 lines =<< trim END
155 let g:Object = {}
156 def Define()
157 function g:Object.Method()
158 endfunction
159 enddef
160 defcompile
161 END
162 v9.CheckScriptFailure(lines, 'E1182:')
163 delfunc g:Define
Ernie Raelcb90ea92024-08-19 21:45:23 +0200164
165 lines =<< trim END
166 vim9script
167 var F1_ref: func
168 def Start()
169 F1_ref()
170 enddef
171 Start()
172 END
173 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar22f17a22021-06-21 20:48:58 +0200174enddef
175
Ernie Rael3f821d62024-04-24 20:07:50 +0200176" Check that in a legacy script a :def accesses the correct script variables.
177" Github issue: #14615.
178def Test_access_var_from_legacy_def()
179 # Access a script variable by name WITH "s:" prefix.
180 var lines =<< trim END
181 let s:foo = 'init'
182 let s:xxfoo = 'init'
183 def! AccessVarFromLegacyDef()
184 s:xxfoo = 'CHANGED'
185 enddef
186 call AccessVarFromLegacyDef()
187 call assert_equal('init', s:foo)
188 call assert_equal('CHANGED', s:xxfoo)
189 END
190 v9.CheckScriptSuccess(lines)
191
192 # Access a script variable by name WITHOUT "s:" prefix;
193 # previously this accessed "foo" and not "xxfoo"
194 lines =<< trim END
195 let s:foo = 'init'
196 let s:xxfoo = 'init'
197 def! AccessVarFromLegacyDef()
198 xxfoo = 'CHANGED'
199 enddef
200 call AccessVarFromLegacyDef()
201 call assert_equal('init', s:foo)
202 call assert_equal('CHANGED', s:xxfoo)
203 END
204 v9.CheckScriptSuccess(lines)
205enddef
206
Bram Moolenaard4a9b7f2023-05-23 14:48:42 +0100207def Test_listing_function_error()
208 var lines =<< trim END
209 var filler = 123
210 func DoesNotExist
211 END
212 v9.CheckDefExecFailure(lines, 'E123:', 2)
213enddef
214
Bram Moolenaar3f45d672023-02-27 22:06:51 +0000215def Test_break_in_skipped_block()
216 var lines =<< trim END
217 vim9script
218
219 def FixStackFrame(): string
220 for _ in [2]
221 var path = 'xxx'
222 if !!path
223 if false
224 break
225 else
226 return 'foo'
227 endif
228 endif
229 endfor
230 return 'xxx'
231 enddef
232
233 disas FixStackFrame
234
235 FixStackFrame()
236 END
237 v9.CheckScriptSuccess(lines)
238enddef
239
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200240def Test_autoload_name_mismatch()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100241 var dir = 'Xnamedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100242 mkdir(dir, 'pR')
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200243
244 var lines =<< trim END
245 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000246 export def NoFunction()
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200247 # comment
248 g:runtime = 'yes'
249 enddef
250 END
251 writefile(lines, dir .. '/script.vim')
252
253 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100254 exe 'set rtp=' .. getcwd() .. '/Xnamedir'
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200255 lines =<< trim END
256 call script#Function()
257 END
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000258 v9.CheckScriptFailure(lines, 'E117:', 1)
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200259
260 &rtp = save_rtp
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200261enddef
262
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200263def Test_autoload_names()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100264 var dir = 'Xandir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100265 mkdir(dir, 'pR')
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200266
267 var lines =<< trim END
268 func foobar#function()
269 return 'yes'
270 endfunc
271 let foobar#var = 'no'
272 END
273 writefile(lines, dir .. '/foobar.vim')
274
275 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100276 exe 'set rtp=' .. getcwd() .. '/Xandir'
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200277
278 lines =<< trim END
279 assert_equal('yes', foobar#function())
280 var Function = foobar#function
281 assert_equal('yes', Function())
282
283 assert_equal('no', foobar#var)
284 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000285 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200286
287 &rtp = save_rtp
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200288enddef
289
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200290def Test_autoload_error_in_script()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100291 var dir = 'Xaedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100292 mkdir(dir, 'pR')
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200293
294 var lines =<< trim END
295 func scripterror#function()
296 let g:called_function = 'yes'
297 endfunc
298 let 0 = 1
299 END
300 writefile(lines, dir .. '/scripterror.vim')
301
302 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100303 exe 'set rtp=' .. getcwd() .. '/Xaedir'
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200304
305 g:called_function = 'no'
306 # The error in the autoload script cannot be checked with assert_fails(), use
307 # CheckDefSuccess() instead of CheckDefFailure()
308 try
Bram Moolenaar62aec932022-01-29 21:45:34 +0000309 v9.CheckDefSuccess(['scripterror#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200310 catch
311 assert_match('E121: Undefined variable: 0', v:exception)
312 endtry
313 assert_equal('no', g:called_function)
314
315 lines =<< trim END
316 func scriptcaught#function()
317 let g:called_function = 'yes'
318 endfunc
319 try
320 let 0 = 1
321 catch
322 let g:caught = v:exception
323 endtry
324 END
325 writefile(lines, dir .. '/scriptcaught.vim')
326
327 g:called_function = 'no'
Bram Moolenaar62aec932022-01-29 21:45:34 +0000328 v9.CheckDefSuccess(['scriptcaught#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200329 assert_match('E121: Undefined variable: 0', g:caught)
330 assert_equal('yes', g:called_function)
331
332 &rtp = save_rtp
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200333enddef
334
Bram Moolenaar62aec932022-01-29 21:45:34 +0000335def s:CallRecursive(n: number): number
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100336 return CallRecursive(n + 1)
337enddef
338
Bram Moolenaar62aec932022-01-29 21:45:34 +0000339def s:CallMapRecursive(l: list<number>): number
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100340 return map(l, (_, v) => CallMapRecursive([v]))[0]
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100341enddef
342
343def Test_funcdepth_error()
344 set maxfuncdepth=10
345
346 var caught = false
347 try
348 CallRecursive(1)
349 catch /E132:/
350 caught = true
351 endtry
352 assert_true(caught)
353
354 caught = false
355 try
356 CallMapRecursive([1])
357 catch /E132:/
358 caught = true
359 endtry
360 assert_true(caught)
361
362 set maxfuncdepth&
363enddef
364
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100365def Test_endfunc_enddef()
366 var lines =<< trim END
367 def Test()
368 echo 'test'
369 endfunc
370 enddef
371 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000372 v9.CheckScriptFailure(lines, 'E1151:', 3)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100373
374 lines =<< trim END
375 def Test()
376 func Nested()
377 echo 'test'
378 enddef
379 enddef
380 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000381 v9.CheckScriptFailure(lines, 'E1152:', 4)
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100382
383 lines =<< trim END
384 def Ok()
385 echo 'hello'
386 enddef | echo 'there'
387 def Bad()
388 echo 'hello'
389 enddef there
390 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000391 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100392enddef
393
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100394def Test_missing_endfunc_enddef()
395 var lines =<< trim END
396 vim9script
397 def Test()
398 echo 'test'
399 endef
400 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000401 v9.CheckScriptFailure(lines, 'E1057:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100402
403 lines =<< trim END
404 vim9script
405 func Some()
406 echo 'test'
407 enfffunc
408 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000409 v9.CheckScriptFailure(lines, 'E126:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100410enddef
411
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100412def Test_white_space_before_paren()
413 var lines =<< trim END
414 vim9script
415 def Test ()
416 echo 'test'
417 enddef
418 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000419 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100420
421 lines =<< trim END
422 vim9script
423 func Test ()
424 echo 'test'
425 endfunc
426 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000427 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100428
429 lines =<< trim END
430 def Test ()
431 echo 'test'
432 enddef
433 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000434 v9.CheckScriptFailure(lines, 'E1068:', 1)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100435
436 lines =<< trim END
437 func Test ()
438 echo 'test'
439 endfunc
440 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000441 v9.CheckScriptSuccess(lines)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100442enddef
443
Bram Moolenaar832ea892021-01-08 21:55:26 +0100444def Test_enddef_dict_key()
445 var d = {
446 enddef: 'x',
447 endfunc: 'y',
448 }
449 assert_equal({enddef: 'x', endfunc: 'y'}, d)
450enddef
451
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200452def ReturnString(): string
453 return 'string'
454enddef
455
456def ReturnNumber(): number
457 return 123
458enddef
459
460let g:notNumber = 'string'
461
462def ReturnGlobal(): number
463 return g:notNumber
464enddef
465
466def Test_return_something()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000467 g:ReturnString()->assert_equal('string')
468 g:ReturnNumber()->assert_equal(123)
Bram Moolenaar848fadd2022-01-30 15:28:30 +0000469 assert_fails('g:ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaaref7aadb2022-01-18 18:46:07 +0000470
471 var lines =<< trim END
472 vim9script
473
474 def Msg()
475 echomsg 'in Msg()...'
476 enddef
477
478 def Func()
479 return Msg()
480 enddef
481 defcompile
482 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000483 v9.CheckScriptFailure(lines, 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200484enddef
485
Bram Moolenaare32e5162021-01-21 20:21:29 +0100486def Test_check_argument_type()
487 var lines =<< trim END
488 vim9script
489 def Val(a: number, b: number): number
490 return 0
491 enddef
492 def Func()
493 var x: any = true
494 Val(0, x)
495 enddef
496 disass Func
497 Func()
498 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000499 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
Bram Moolenaar56310d32022-12-27 17:25:05 +0000500
501 lines =<< trim END
502 vim9script
503
504 def Foobar(Fn: func(any, ?string): any)
505 enddef
506
507 Foobar((t) => 0)
508 END
509 v9.CheckScriptSuccess(lines)
Bram Moolenaare32e5162021-01-21 20:21:29 +0100510enddef
511
Bram Moolenaarefd88552020-06-18 20:50:10 +0200512def Test_missing_return()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000513 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200514 ' if g:cond',
515 ' echo "no return"',
516 ' else',
517 ' return 0',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100518 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200519 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000520 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200521 ' if g:cond',
522 ' return 1',
523 ' else',
524 ' echo "no return"',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100525 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200526 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000527 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200528 ' if g:cond',
529 ' return 1',
530 ' else',
531 ' return 2',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100532 ' endif',
533 ' return 3',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200534 'enddef'], 'E1095:')
535enddef
536
Bram Moolenaarcf2610c2023-05-14 19:59:59 +0100537def Test_not_missing_return()
538 var lines =<< trim END
539 def Funky(): number
540 if false
541 return 0
542 endif
543 throw 'Error'
544 enddef
545 defcompile
546 END
547 v9.CheckScriptSuccess(lines)
548enddef
549
Yegappan Lakshmananab9a8942024-12-30 09:56:34 +0100550" Test for an if-else block ending in a throw statement
551def Test_if_else_with_throw()
552 var lines =<< trim END
553 def Ifelse_Throw1(): number
554 if false
555 return 1
556 else
557 throw 'Error'
558 endif
559 enddef
560 defcompile
561 END
562 v9.CheckScriptSuccess(lines)
563
564 lines =<< trim END
565 def Ifelse_Throw2(): number
566 if true
567 throw 'Error'
568 else
569 return 2
570 endif
571 enddef
572 defcompile
573 END
574 v9.CheckScriptSuccess(lines)
575
576 lines =<< trim END
577 def Ifelse_Throw3(): number
578 if true
579 return 1
580 elseif false
581 throw 'Error'
582 else
583 return 3
584 endif
585 enddef
586 defcompile
587 END
588 v9.CheckScriptSuccess(lines)
589enddef
590
Bram Moolenaar403dc312020-10-17 19:29:51 +0200591def Test_return_bool()
592 var lines =<< trim END
593 vim9script
594 def MenuFilter(id: number, key: string): bool
595 return popup_filter_menu(id, key)
596 enddef
597 def YesnoFilter(id: number, key: string): bool
598 return popup_filter_yesno(id, key)
599 enddef
600 defcompile
601 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000602 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200603enddef
604
mityu500c4442022-12-02 18:12:05 +0000605def Test_return_void_comment_follows()
606 var lines =<< trim END
607 vim9script
608 def ReturnCommentFollows(): void
609 return # Some comment
610 enddef
611 defcompile
612 END
613 v9.CheckScriptSuccess(lines)
614enddef
615
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200616let s:nothing = 0
617def ReturnNothing()
618 s:nothing = 1
619 if true
620 return
621 endif
622 s:nothing = 2
623enddef
624
625def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000626 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200627 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200628enddef
629
Bram Moolenaar648ea762021-01-15 19:04:32 +0100630def Test_return_invalid()
631 var lines =<< trim END
632 vim9script
633 def Func(): invalid
634 return xxx
635 enddef
636 defcompile
637 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000638 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100639
640 lines =<< trim END
641 vim9script
642 def Test(Fun: func(number): number): list<number>
643 return map([1, 2, 3], (_, i) => Fun(i))
644 enddef
645 defcompile
646 def Inc(nr: number): nr
647 return nr + 2
648 enddef
649 echo Test(Inc)
650 END
651 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000652 v9.CheckScriptFailure(lines, 'E1010:')
653 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100654enddef
655
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200656def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000657 # This used to fail but now the actual list type is checked, and since it has
658 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200659 var lines =<< trim END
660 vim9script
661 def Func(): list<string>
662 var l: list<any>
663 l->add('string')
664 return l
665 enddef
666 echo Func()
667 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000668 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000669
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200670 lines =<< trim END
671 vim9script
672 def Func(): list<string>
673 var l: list<any>
674 l += ['string']
675 return l
676 enddef
677 echo Func()
678 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000679 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200680enddef
681
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000682def Test_return_any_two_types()
683 var lines =<< trim END
684 vim9script
685
686 def G(Fn: func(string): any)
687 g:result = Fn("hello")
688 enddef
689
690 def F(a: number, b: string): any
691 echo b
692 if a > 0
693 return 1
694 else
695 return []
696 endif
697 enddef
698
699 G(function(F, [1]))
700 END
701 v9.CheckScriptSuccess(lines)
702 assert_equal(1, g:result)
703 unlet g:result
704enddef
705
Bram Moolenaar62aec932022-01-29 21:45:34 +0000706func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200707 let g:counter += 1
708endfunc
709
710def Test_call_ufunc_count()
711 g:counter = 1
712 Increment()
713 Increment()
714 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200715 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200716 g:counter->assert_equal(4)
717 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200718 unlet g:counter
719enddef
720
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000721def Test_call_ufunc_failure()
722 var lines =<< trim END
723 vim9script
724 def Tryit()
725 g:Global(1, 2, 3)
726 enddef
727
728 func g:Global(a, b, c)
729 echo a:a a:b a:c
730 endfunc
731
732 defcompile
733
734 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000735 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000736 endfunc
737 Tryit()
738 END
739 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
740 delfunc g:Global
741
742 lines =<< trim END
743 vim9script
744
745 g:Ref = function('len')
746 def Tryit()
747 g:Ref('x')
748 enddef
749
750 defcompile
751
752 g:Ref = function('add')
753 Tryit()
754 END
755 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
756 unlet g:Ref
757enddef
758
Bram Moolenaar62aec932022-01-29 21:45:34 +0000759def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200760 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200761 for s in rest
762 res ..= ',' .. s
763 endfor
764 return res
765enddef
766
767def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200768 MyVarargs('one')->assert_equal('one')
769 MyVarargs('one', 'two')->assert_equal('one,two')
770 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200771enddef
772
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200773def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000774 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200775enddef
776
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200777def MyDefaultArgs(name = 'string'): string
778 return name
779enddef
780
Bram Moolenaar62aec932022-01-29 21:45:34 +0000781def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200782 return second ? name : 'none'
783enddef
784
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200785
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200786def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000787 g:MyDefaultArgs()->assert_equal('string')
788 g:MyDefaultArgs(v:none)->assert_equal('string')
789 g:MyDefaultArgs('one')->assert_equal('one')
790 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200791
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200792 MyDefaultSecond('test')->assert_equal('test')
793 MyDefaultSecond('test', true)->assert_equal('test')
794 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200795
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200796 var lines =<< trim END
797 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
798 return name .. aa .. bb
799 enddef
800
801 MyDefaultThird('->')->assert_equal('->aabb')
802 MyDefaultThird('->', v:none)->assert_equal('->aabb')
803 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
804 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
805 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
806 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
807 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200808
809 def DefArg(mandatory: any, optional = mandatory): string
810 return mandatory .. optional
811 enddef
812 DefArg(1234)->assert_equal('12341234')
813 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200814 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000815 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200816
Bram Moolenaar62aec932022-01-29 21:45:34 +0000817 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100818 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000819 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 +0100820 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000821 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100822
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200823 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100824 vim9script
825 def Func(a = b == 0 ? 1 : 2, b = 0)
826 enddef
827 defcompile
828 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000829 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000830
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000831 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000832 lines =<< trim END
833 vim9script
834 var a: any
835 def Func(arg: string = a)
836 echo arg
837 enddef
838 defcompile
839 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000840 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
841 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000842
843 # using global variable does not require type cast
844 lines =<< trim END
845 vim9script
846 def Func(arg: string = g:str)
847 echo arg
848 enddef
849 g:str = 'works'
850 Func()
851 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000852 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200853enddef
854
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100855def Test_using_vnone_default()
856 var lines =<< trim END
857 vim9script
858
859 def F(a: string = v:none)
860 if a isnot v:none
861 var b = a
862 endif
863 enddef
864 F()
865 END
866 v9.CheckScriptSuccess(lines)
867
Bram Moolenaar2ba51232023-05-15 16:22:38 +0100868 lines =<< trim END
869 vim9script
870
871 export def Floats(x: float, y = 2.0, z = 5.0)
872 g:result = printf("%.2f %.2f %.2f", x, y, z)
873 enddef
874 END
875 writefile(lines, 'Xlib.vim', 'D')
876
877 # test using a function reference in script-local variable
878 lines =<< trim END
879 vim9script
880
881 import './Xlib.vim'
882 const Floatfunc = Xlib.Floats
883 Floatfunc(1.0, v:none, 3.0)
884 END
885 v9.CheckScriptSuccess(lines)
886 assert_equal('1.00 2.00 3.00', g:result)
887 unlet g:result
888
889 # test calling the imported function
890 lines =<< trim END
891 vim9script
892
893 import './Xlib.vim'
894 Xlib.Floats(1.0, v:none, 3.0)
895 END
896 v9.CheckScriptSuccess(lines)
897 assert_equal('1.00 2.00 3.00', g:result)
898 unlet g:result
899
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100900 # TODO: this should give an error for using a missing argument
901 # lines =<< trim END
902 # vim9script
903
904 # def F(a: string = v:none)
905 # var b = a
906 # enddef
907 # F()
908 # END
909 # v9.CheckScriptFailure(lines, 'E99:')
910enddef
911
Bram Moolenaar47bba532023-01-20 18:49:46 +0000912def Test_convert_number_to_float()
913 var lines =<< trim END
914 vim9script
915 def Foo(a: float, b: float): float
916 return a + b
917 enddef
918
919 assert_equal(5.3, Foo(3.3, 2))
920 END
921 v9.CheckScriptSuccess(lines)
922enddef
923
Bram Moolenaar62aec932022-01-29 21:45:34 +0000924def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100925 a: number, #comment
926 b: bool, # comment
927 c: string) #comment
928 assert_equal(4, a)
929 assert_equal(true, b)
930 assert_equal('yes', c)
931enddef
932
933def Test_func_with_comments()
934 FuncWithComment(4, true, 'yes')
935
936 var lines =<< trim END
937 def Func(# comment
938 arg: string)
939 enddef
940 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000941 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100942
943 lines =<< trim END
Christian Brabandte4a450a2023-12-08 20:57:38 +0100944 def Func(f=
945 )
946 enddef
947 END
948 v9.CheckScriptFailure(lines, 'E125:', 2)
949
950 lines =<< trim END
Bram Moolenaarcef12702021-01-04 14:09:43 +0100951 def Func(
952 arg: string# comment
953 )
954 enddef
955 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000956 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100957
958 lines =<< trim END
959 def Func(
960 arg: string
961 )# comment
962 enddef
963 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000964 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100965enddef
966
Bram Moolenaar04b12692020-05-04 23:24:44 +0200967def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000968 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200969 return 'nested ' .. arg
970 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000971 NestedDef(':def')->assert_equal('nested :def')
972
973 func NestedFunc(arg)
974 return 'nested ' .. a:arg
975 endfunc
976 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200977
Bram Moolenaar62aec932022-01-29 21:45:34 +0000978 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
979 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200980
Bram Moolenaar62aec932022-01-29 21:45:34 +0000981 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
982 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200983
Bram Moolenaar54021752020-12-06 18:50:36 +0100984 var lines =<< trim END
985 def Outer()
986 def Inner()
987 # comment
988 enddef
989 def Inner()
990 enddef
991 enddef
992 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000993 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100994
995 lines =<< trim END
996 def Outer()
997 def Inner()
998 # comment
999 enddef
1000 def! Inner()
1001 enddef
1002 enddef
1003 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001004 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +01001005
Bram Moolenaardb8e5c22021-12-25 19:58:22 +00001006 lines =<< trim END
1007 vim9script
1008 def Outer()
1009 def Inner()
1010 g:result = 'ok'
1011 enddef
1012 Inner()
1013 enddef
1014 Outer()
1015 Inner()
1016 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001017 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +00001018 assert_equal('ok', g:result)
1019 unlet g:result
1020
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001021 lines =<< trim END
1022 vim9script
1023 def Outer()
1024 def _Inner()
1025 echo 'bad'
1026 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +00001027 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001028 enddef
1029 defcompile
1030 END
Bram Moolenaar3787f262022-02-07 21:54:01 +00001031 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001032
1033 lines =<< trim END
1034 vim9script
1035 def Outer()
1036 def g:inner()
1037 echo 'bad'
1038 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +00001039 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001040 enddef
1041 defcompile
1042 END
Bram Moolenaar3787f262022-02-07 21:54:01 +00001043 v9.CheckScriptFailure(lines, 'E1267:')
1044
1045 lines =<< trim END
1046 vim9script
1047 def g:_Func()
1048 echo 'bad'
1049 enddef
1050 END
1051 v9.CheckScriptFailure(lines, 'E1267:')
1052
1053 lines =<< trim END
1054 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001055 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +00001056 echo 'bad'
1057 enddef
1058 END
1059 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001060
Bram Moolenaar54021752020-12-06 18:50:36 +01001061 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +01001062 lines =<< trim END
1063 vim9script
1064 var thecount = 0
1065 if true
1066 def Test(): number
1067 def TheFunc(): number
1068 thecount += 1
1069 return thecount
1070 enddef
1071 return TheFunc()
1072 enddef
1073 endif
1074 defcompile
1075 assert_equal(1, Test())
1076 assert_equal(2, Test())
1077 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001078 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001079
1080 # also works when "thecount" is inside the "if" block
1081 lines =<< trim END
1082 vim9script
1083 if true
1084 var thecount = 0
1085 def Test(): number
1086 def TheFunc(): number
1087 thecount += 1
1088 return thecount
1089 enddef
1090 return TheFunc()
1091 enddef
1092 endif
1093 defcompile
1094 assert_equal(1, Test())
1095 assert_equal(2, Test())
1096 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001097 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001098
Bram Moolenaara915fa02022-03-23 11:29:15 +00001099 # nested function with recursive call
1100 lines =<< trim END
1101 vim9script
1102
1103 def MyFunc(): number
1104 def Fib(n: number): number
1105 if n < 2
1106 return 1
1107 endif
1108 return Fib(n - 2) + Fib(n - 1)
1109 enddef
1110
1111 return Fib(5)
1112 enddef
1113
1114 assert_equal(8, MyFunc())
1115 END
1116 v9.CheckScriptSuccess(lines)
1117
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001118 lines =<< trim END
1119 vim9script
1120 def Outer()
1121 def Inner()
1122 echo 'hello'
1123 enddef burp
1124 enddef
1125 defcompile
1126 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001127 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001128enddef
1129
Bram Moolenaar1889f492022-08-16 19:34:44 +01001130def Test_nested_function_fails()
1131 var lines =<< trim END
1132 def T()
1133 def Func(g: string):string
1134 enddef
1135 Func()
1136 enddef
1137 silent! defcompile
1138 END
1139 v9.CheckScriptFailure(lines, 'E1069:')
1140enddef
1141
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001142def Test_not_nested_function()
1143 echo printf('%d',
1144 function('len')('xxx'))
1145enddef
1146
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001147func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001148 call MyDefaultArgs()->assert_equal('string')
1149 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001150 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001151endfunc
1152
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001153def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001154 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001155 vim9script
1156 def Outer()
1157 def g:Inner(): string
1158 return 'inner'
1159 enddef
1160 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001161 defcompile
1162 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001163 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001164 delfunc g:Inner
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
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001171 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001172 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001173
1174 lines =<< trim END
1175 vim9script
1176 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001177 func g:Inner()
1178 return 'inner'
1179 endfunc
1180 enddef
1181 defcompile
1182 Outer()
1183 g:Inner()->assert_equal('inner')
1184 delfunc g:Inner
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 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001192 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001193
1194 lines =<< trim END
1195 vim9script
1196 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001197 def g:Inner(): string
1198 return 'inner'
1199 enddef
1200 enddef
1201 defcompile
1202 Outer()
1203 Outer()
1204 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001205 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001206 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001207
1208 lines =<< trim END
1209 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001210 def Outer()
1211 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001212 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001213 enddef
1214 g:Inner()
1215 enddef
1216 Outer()
1217 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001218 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001219 delfunc g:Inner
1220
1221 lines =<< trim END
1222 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001223 def Func()
1224 echo 'script'
1225 enddef
1226 def Outer()
1227 def Func()
1228 echo 'inner'
1229 enddef
1230 enddef
1231 defcompile
1232 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001233 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001234
1235 lines =<< trim END
1236 vim9script
1237 def Func()
1238 echo 'script'
1239 enddef
1240 def Func()
1241 echo 'script'
1242 enddef
1243 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001244 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001245enddef
1246
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001247def DefListAll()
1248 def
1249enddef
1250
1251def DefListOne()
1252 def DefListOne
1253enddef
1254
1255def DefListMatches()
1256 def /DefList
1257enddef
1258
1259def Test_nested_def_list()
1260 var funcs = split(execute('call DefListAll()'), "\n")
1261 assert_true(len(funcs) > 10)
1262 assert_true(funcs->index('def DefListAll()') >= 0)
1263
1264 funcs = split(execute('call DefListOne()'), "\n")
1265 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1266
1267 funcs = split(execute('call DefListMatches()'), "\n")
1268 assert_true(len(funcs) >= 3)
1269 assert_true(funcs->index('def DefListAll()') >= 0)
1270 assert_true(funcs->index('def DefListOne()') >= 0)
1271 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001272
1273 var lines =<< trim END
1274 vim9script
1275 def Func()
1276 def +Func+
1277 enddef
1278 defcompile
1279 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001280 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001281enddef
1282
Bram Moolenaare08be092022-02-17 13:08:26 +00001283def Test_global_function_not_found()
1284 var lines =<< trim END
1285 g:Ref = 123
1286 call g:Ref()
1287 END
1288 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1289enddef
1290
Bram Moolenaar333894b2020-08-01 18:53:07 +02001291def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001292 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001293 vim9script
1294 def g:Func(): string
1295 return 'global'
1296 enddef
1297 def Func(): string
1298 return 'local'
1299 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001300 g:Func()->assert_equal('global')
1301 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001302 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001303 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001304 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001305
1306 lines =<< trim END
1307 vim9script
1308 def g:Funcy()
1309 echo 'funcy'
1310 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001311 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001312 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001313 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001314enddef
1315
Bram Moolenaar0f769812020-09-12 18:32:34 +02001316def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001317 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001318 vim9script
1319 def g:Gfunc(): string
1320 return 'global'
1321 enddef
1322 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001323 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001324 return Gfunc('testing')
1325 enddef
1326 g:Gfunc()->assert_equal('global')
1327 AnotherFunc()->assert_equal(7)
1328 delfunc g:Gfunc
1329 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001330 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001331
1332 lines =<< trim END
1333 vim9script
1334 def g:Func(): string
1335 return 'global'
1336 enddef
1337 def AnotherFunc()
1338 g:Func = function('len')
1339 enddef
1340 AnotherFunc()
1341 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001342 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001343 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001344
Bram Moolenaar62aec932022-01-29 21:45:34 +00001345 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001346 lines =<< trim END
1347 vim9script
1348 def g:Func(): string
1349 return 'global'
1350 enddef
1351 def AnotherFunc(): string
1352 return Func()
1353 enddef
1354 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001355 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001356 v9.CheckScriptFailure(lines, 'E117:')
1357 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001358
1359 lines =<< trim END
1360 vim9script
1361 def g:Func(): string
1362 return 'global'
1363 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001364 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001365 delfunc g:Func
1366 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001367 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001368
1369 # This does not shadow "i" which is visible only inside the for loop
1370 lines =<< trim END
1371 vim9script
1372
1373 def Foo(i: number)
1374 echo i
1375 enddef
1376
1377 for i in range(3)
1378 # Foo() is compiled here
1379 Foo(i)
1380 endfor
1381 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001382 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001383enddef
1384
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001385func TakesOneArg(arg)
1386 echo a:arg
1387endfunc
1388
1389def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001390 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1391 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1392 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1393 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001394
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001395 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001396 vim9script
1397 def Func(s: string)
1398 echo s
1399 enddef
1400 Func([])
1401 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01001402 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<any>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001403
Bram Moolenaar9a015112021-12-31 14:06:45 +00001404 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001405 lines =<< trim END
1406 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001407 var name = 'piet'
1408 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001409 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001410 enddef
1411 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001412 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001413
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001414 # same, inside the same block
1415 lines =<< trim END
1416 vim9script
1417 if true
1418 var name = 'piet'
1419 def FuncOne(name: string)
1420 echo name
1421 enddef
1422 endif
1423 END
1424 v9.CheckScriptFailure(lines, 'E1168:')
1425
1426 # variable in other block is OK
1427 lines =<< trim END
1428 vim9script
1429 if true
1430 var name = 'piet'
1431 endif
1432 def FuncOne(name: string)
1433 echo name
1434 enddef
1435 END
1436 v9.CheckScriptSuccess(lines)
1437
Bram Moolenaardce24412022-02-08 20:35:30 +00001438 # with another variable in another block
1439 lines =<< trim END
1440 vim9script
1441 if true
1442 var name = 'piet'
1443 # define a function so that the variable isn't cleared
1444 def GetItem(): string
1445 return item
1446 enddef
1447 endif
1448 if true
1449 var name = 'peter'
1450 def FuncOne(name: string)
1451 echo name
1452 enddef
1453 endif
1454 END
1455 v9.CheckScriptFailure(lines, 'E1168:')
1456
1457 # only variable in another block is OK
1458 lines =<< trim END
1459 vim9script
1460 if true
1461 var name = 'piet'
1462 # define a function so that the variable isn't cleared
1463 def GetItem(): string
1464 return item
1465 enddef
1466 endif
1467 if true
1468 def FuncOne(name: string)
1469 echo name
1470 enddef
1471 endif
1472 END
1473 v9.CheckScriptSuccess(lines)
1474
Bram Moolenaar9a015112021-12-31 14:06:45 +00001475 # argument name declared later is only found when compiling
1476 lines =<< trim END
1477 vim9script
1478 def FuncOne(name: string)
1479 echo nr
1480 enddef
1481 var name = 'piet'
1482 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001483 v9.CheckScriptSuccess(lines)
1484 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001485
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001486 lines =<< trim END
1487 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001488 def FuncOne(nr: number)
1489 echo nr
1490 enddef
1491 def FuncTwo()
1492 FuncOne()
1493 enddef
1494 defcompile
1495 END
1496 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001497 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001498 try
1499 source Xscript
1500 catch
1501 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1502 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1503 didCatch = true
1504 endtry
1505 assert_true(didCatch)
1506
1507 lines =<< trim END
1508 vim9script
1509 def FuncOne(nr: number)
1510 echo nr
1511 enddef
1512 def FuncTwo()
1513 FuncOne(1, 2)
1514 enddef
1515 defcompile
1516 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001517 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001518 didCatch = false
1519 try
1520 source Xscript
1521 catch
1522 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1523 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1524 didCatch = true
1525 endtry
1526 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001527enddef
1528
Bram Moolenaar50824712020-12-20 21:10:17 +01001529def Test_call_funcref_wrong_args()
1530 var head =<< trim END
1531 vim9script
1532 def Func3(a1: string, a2: number, a3: list<number>)
1533 echo a1 .. a2 .. a3[0]
1534 enddef
1535 def Testme()
1536 var funcMap: dict<func> = {func: Func3}
1537 END
1538 var tail =<< trim END
1539 enddef
1540 Testme()
1541 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001542 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001543
Bram Moolenaar62aec932022-01-29 21:45:34 +00001544 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1545 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001546
1547 var lines =<< trim END
1548 vim9script
1549 var Ref: func(number): any
1550 Ref = (j) => !j
1551 echo Ref(false)
1552 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001553 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001554
1555 lines =<< trim END
1556 vim9script
1557 var Ref: func(number): any
1558 Ref = (j) => !j
1559 call Ref(false)
1560 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001561 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001562enddef
1563
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001564def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001565 var lines =<< trim END
1566 var Callback = (..._) => 'anything'
1567 assert_equal('anything', Callback())
1568 assert_equal('anything', Callback(1))
1569 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001570
1571 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001572 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001573 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001574
Bram Moolenaar62aec932022-01-29 21:45:34 +00001575 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001576 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001577
Bram Moolenaar2a389082021-04-09 20:24:31 +02001578 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001579 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001580 echo Ref(1, 'x')
1581 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001582 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001583
1584 lines =<< trim END
1585 var Ref: func(job, string, number)
1586 Ref = (x, y) => 0
1587 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001588 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001589
1590 lines =<< trim END
1591 var Ref: func(job, string)
1592 Ref = (x, y, z) => 0
1593 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001594 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001595
1596 lines =<< trim END
1597 var one = 1
1598 var l = [1, 2, 3]
1599 echo map(l, (one) => one)
1600 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001601 v9.CheckDefFailure(lines, 'E1167:')
1602 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001603
1604 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001605 var Ref: func(any, ?any): bool
1606 Ref = (_, y = 1) => false
1607 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001608 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001609
1610 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001611 var a = 0
1612 var b = (a == 0 ? 1 : 2)
1613 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001614 var txt = 'a'
1615 b = (txt =~ 'x' ? 1 : 2)
1616 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001617 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001618 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001619
1620 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001621 def ShadowLocal()
1622 var one = 1
1623 var l = [1, 2, 3]
1624 echo map(l, (one) => one)
1625 enddef
1626 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001627 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001628
1629 lines =<< trim END
1630 def Shadowarg(one: number)
1631 var l = [1, 2, 3]
1632 echo map(l, (one) => one)
1633 enddef
1634 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001635 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001636
1637 lines =<< trim END
1638 echo ((a) => a)('aa', 'bb')
1639 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001640 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001641
1642 lines =<< trim END
1643 echo 'aa'->((a) => a)('bb')
1644 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001645 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1646 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001647enddef
1648
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001649def Test_lambda_line_nr()
1650 var lines =<< trim END
1651 vim9script
1652 # comment
1653 # comment
1654 var id = timer_start(1'000, (_) => 0)
1655 var out = execute('verbose ' .. timer_info(id)[0].callback
1656 ->string()
1657 ->substitute("('\\|')", ' ', 'g'))
1658 assert_match('Last set from .* line 4', out)
1659 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001660 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001661enddef
1662
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001663def FilterWithCond(x: string, Cond: func(string): bool): bool
1664 return Cond(x)
1665enddef
1666
Bram Moolenaar0346b792021-01-31 22:18:29 +01001667def Test_lambda_return_type()
1668 var lines =<< trim END
1669 var Ref = (): => 123
1670 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001671 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001672
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001673 # no space before the return type
1674 lines =<< trim END
1675 var Ref = (x):number => x + 1
1676 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001677 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001678
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001679 # this works
1680 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001681 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001682 endfor
1683
1684 # this fails
1685 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001686 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001687 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001688 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 +02001689
1690 lines =<< trim END
1691 var Lambda1 = (x) => {
1692 return x
1693 }
1694 assert_equal('asdf', Lambda1('asdf'))
1695 var Lambda2 = (x): string => {
1696 return x
1697 }
1698 assert_equal('foo', Lambda2('foo'))
1699 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001700 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001701
1702 lines =<< trim END
1703 var Lambda = (x): string => {
1704 return x
1705 }
1706 echo Lambda(['foo'])
1707 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001708 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001709enddef
1710
Bram Moolenaar709664c2020-12-12 14:33:41 +01001711def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001712 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001713 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001714 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001715enddef
1716
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001717def Test_lambda_invalid_block()
1718 var lines =<< trim END
1719 timer_start(0, (_) => { # echo
1720 echo 'yes'
1721 })
1722 END
1723 v9.CheckDefAndScriptSuccess(lines)
1724
1725 lines =<< trim END
1726 timer_start(0, (_) => { " echo
1727 echo 'yes'
1728 })
1729 END
1730 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1731
1732 lines =<< trim END
1733 timer_start(0, (_) => { | echo
1734 echo 'yes'
1735 })
1736 END
1737 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1738enddef
1739
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001740def Test_lambda_with_following_cmd()
1741 var lines =<< trim END
1742 set ts=2
1743 var Lambda = () => {
1744 set ts=4
1745 } | set ts=3
1746 assert_equal(3, &ts)
1747 Lambda()
1748 assert_equal(4, &ts)
1749 END
1750 v9.CheckDefAndScriptSuccess(lines)
1751 set ts=8
1752enddef
1753
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001754def Test_pass_legacy_lambda_to_def_func()
1755 var lines =<< trim END
1756 vim9script
1757 func Foo()
1758 eval s:Bar({x -> 0})
1759 endfunc
1760 def Bar(y: any)
1761 enddef
1762 Foo()
1763 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001764 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001765
1766 lines =<< trim END
1767 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001768 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001769 enddef
1770 legacy call g:TestFunc({-> 0})
1771 delfunc g:TestFunc
1772
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001773 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001774 enddef
1775 legacy call g:TestFunc({nr -> 0})
1776 delfunc g:TestFunc
1777 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001778 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001779enddef
1780
Bram Moolenaar844fb642021-10-23 13:32:30 +01001781def Test_lambda_in_reduce_line_break()
1782 # this was using freed memory
1783 var lines =<< trim END
1784 vim9script
1785 const result: dict<number> =
1786 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1787 ->reduce((acc, val) => {
1788 if has_key(acc, val)
1789 acc[val] += 1
1790 return acc
1791 else
1792 acc[val] = 1
1793 return acc
1794 endif
1795 }, {})
1796 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1797 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001798 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001799enddef
1800
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001801def Test_set_opfunc_to_lambda()
1802 var lines =<< trim END
1803 vim9script
1804 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1805 def CountSpaces(type = ''): string
1806 if type == ''
1807 &operatorfunc = (t) => CountSpaces(t)
1808 return 'g@'
1809 endif
1810 normal! '[V']y
1811 g:result = getreg('"')->count(' ')
1812 return ''
1813 enddef
1814 new
1815 'a b c d e'->setline(1)
1816 feedkeys("\<F4>", 'x')
1817 assert_equal(4, g:result)
1818 bwipe!
1819 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001820 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001821enddef
1822
Bram Moolenaaref082e12021-12-12 21:02:03 +00001823def Test_set_opfunc_to_global_function()
1824 var lines =<< trim END
1825 vim9script
1826 def g:CountSpaces(type = ''): string
1827 normal! '[V']y
1828 g:result = getreg('"')->count(' ')
1829 return ''
1830 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001831 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001832 &operatorfunc = g:CountSpaces
1833 new
1834 'a b c d e'->setline(1)
1835 feedkeys("g@_", 'x')
1836 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001837
1838 &operatorfunc = ''
1839 g:result = 0
1840 # global function works in :def function
1841 def Func()
1842 &operatorfunc = g:CountSpaces
1843 enddef
1844 Func()
1845 feedkeys("g@_", 'x')
1846 assert_equal(4, g:result)
1847
Bram Moolenaaref082e12021-12-12 21:02:03 +00001848 bwipe!
1849 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001850 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001851 &operatorfunc = ''
1852enddef
1853
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001854def Test_use_script_func_name_with_prefix()
1855 var lines =<< trim END
1856 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001857 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001858 return 'it'
1859 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001860 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001861 assert_equal('it', Fn())
1862 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001863 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001864enddef
1865
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001866def Test_lambda_type_allocated()
1867 # Check that unreferencing a partial using a lambda can use the variable type
1868 # after the lambda has been freed and does not leak memory.
1869 var lines =<< trim END
1870 vim9script
1871
1872 func MyomniFunc1(val, findstart, base)
1873 return a:findstart ? 0 : []
1874 endfunc
1875
1876 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1877 &omnifunc = Lambda
1878 Lambda = (a, b) => MyomniFunc1(20, a, b)
1879 &omnifunc = string(Lambda)
1880 Lambda = (a, b) => strlen(a)
1881 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001882 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001883enddef
1884
Bram Moolenaara7583c42022-05-07 21:14:05 +01001885def Test_define_lambda_in_execute()
1886 var lines =<< trim [CODE]
1887 vim9script
1888
1889 def BuildFuncMultiLine(): func
1890 var x =<< trim END
1891 g:SomeRandomFunc = (d: dict<any>) => {
1892 return d.k1 + d.k2
1893 }
1894 END
1895 execute(x)
1896 return g:SomeRandomFunc
1897 enddef
1898 var ResultPlus = BuildFuncMultiLine()
1899 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1900 [CODE]
1901 v9.CheckScriptSuccess(lines)
1902 unlet g:SomeRandomFunc
1903enddef
1904
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001905" Default arg and varargs
1906def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001907 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001908 for s in rest
1909 res ..= ',' .. s
1910 endfor
1911 return res
1912enddef
1913
1914def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001915 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1916 g:MyDefVarargs('one')->assert_equal('one,foo')
1917 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1918 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1919 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001920 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001921 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001922 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001923
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001924 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001925 vim9script
1926 def Func(...l: list<string>)
1927 echo l
1928 enddef
1929 Func('a', 'b', 'c')
1930 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001931 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001932
1933 lines =<< trim END
1934 vim9script
1935 def Func(...l: list<string>)
1936 echo l
1937 enddef
1938 Func()
1939 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001940 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001941
1942 lines =<< trim END
1943 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001944 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001945 echo l
1946 enddef
1947 Func(0)
1948 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001949 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001950
1951 lines =<< trim END
1952 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001953 def Func(...l: any)
1954 echo l
1955 enddef
1956 Func(0)
1957 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001958 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001959
1960 lines =<< trim END
1961 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001962 def Func(..._l: list<string>)
1963 echo _l
1964 enddef
1965 Func('a', 'b', 'c')
1966 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001967 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001968
1969 lines =<< trim END
1970 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001971 def Func(...l: list<string>)
1972 echo l
1973 enddef
1974 Func(1, 2, 3)
1975 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001976 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001977
1978 lines =<< trim END
1979 vim9script
1980 def Func(...l: list<string>)
1981 echo l
1982 enddef
1983 Func('a', 9)
1984 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001985 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001986
1987 lines =<< trim END
1988 vim9script
1989 def Func(...l: list<string>)
1990 echo l
1991 enddef
1992 Func(1, 'a')
1993 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001994 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001995
1996 lines =<< trim END
1997 vim9script
1998 def Func( # some comment
1999 ...l = []
2000 )
2001 echo l
2002 enddef
2003 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002004 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02002005
2006 lines =<< trim END
2007 vim9script
2008 def DoIt()
2009 g:Later('')
2010 enddef
2011 defcompile
2012 def g:Later(...l: list<number>)
2013 enddef
2014 DoIt()
2015 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002016 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002017enddef
2018
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002019let s:value = ''
2020
2021def FuncOneDefArg(opt = 'text')
2022 s:value = opt
2023enddef
2024
2025def FuncTwoDefArg(nr = 123, opt = 'text'): string
2026 return nr .. opt
2027enddef
2028
2029def FuncVarargs(...arg: list<string>): string
2030 return join(arg, ',')
2031enddef
2032
2033def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002034 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002035 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002036 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002037 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002038 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002039 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002040
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002041 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002042 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002043 RefDef2Arg()->assert_equal('123text')
2044 RefDef2Arg(99)->assert_equal('99text')
2045 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002046
Bram Moolenaar62aec932022-01-29 21:45:34 +00002047 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
2048 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002049
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002050 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002051 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002052 RefVarargs()->assert_equal('')
2053 RefVarargs('one')->assert_equal('one')
2054 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002055
Bram Moolenaar62aec932022-01-29 21:45:34 +00002056 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
2057 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002058enddef
2059
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002060" Only varargs
2061def MyVarargsOnly(...args: list<string>): string
2062 return join(args, ',')
2063enddef
2064
2065def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002066 g:MyVarargsOnly()->assert_equal('')
2067 g:MyVarargsOnly('one')->assert_equal('one')
2068 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
2069 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
2070 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002071enddef
2072
Bram Moolenaar36818a92023-01-03 12:33:26 +00002073def Test_varargs_mismatch()
2074 var lines =<< trim END
2075 vim9script
2076
2077 def Map(Fn: func(...any): number): number
2078 return Fn('12')
2079 enddef
2080
2081 var res = Map((v) => str2nr(v))
2082 assert_equal(12, res)
2083 END
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002084 v9.CheckScriptFailure(lines, 'E1180: Variable arguments type must be a list: any')
Bram Moolenaar36818a92023-01-03 12:33:26 +00002085enddef
2086
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002087def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00002088 var lines =<< trim END
2089 def Func(x: number)
2090 var x = 234
2091 enddef
2092 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002093 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002094
2095 lines =<< trim END
2096 def Func(Ref: number)
2097 def Ref()
2098 enddef
2099 enddef
2100 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002101 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002102enddef
2103
Bram Moolenaar62aec932022-01-29 21:45:34 +00002104def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002105 arg['key'] = 'value'
2106enddef
2107
Bram Moolenaar62aec932022-01-29 21:45:34 +00002108def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002109 arg[0] = 'value'
2110enddef
2111
2112def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002113 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002114 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002115 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002116 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002117 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002118 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002119 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002120
Bram Moolenaar62aec932022-01-29 21:45:34 +00002121 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002122 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002123enddef
2124
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002125" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002126def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002127 return firstline .. lastline
2128enddef
2129
2130def Test_argument_names()
2131 assert_equal('OK', WithReservedNames('O', 'K'))
2132enddef
2133
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002134def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002135 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002136 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002137enddef
2138
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002139func DefinedLater(arg)
2140 return a:arg
2141endfunc
2142
2143def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002144 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002145 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002146 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002147
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002148 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002149 vim9script
2150 def RetNumber(): number
2151 return 123
2152 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002153 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002154 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002155 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002156 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002157
2158 lines =<< trim END
2159 vim9script
2160 def RetNumber(): number
2161 return 123
2162 enddef
2163 def Bar(F: func: number): number
2164 return F()
2165 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002166 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002167 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002168 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002169 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002170
2171 lines =<< trim END
2172 vim9script
2173 def UseNumber(nr: number)
2174 echo nr
2175 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002176 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002177 Funcref(123)
2178 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002179 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002180
2181 lines =<< trim END
2182 vim9script
2183 def UseNumber(nr: number)
2184 echo nr
2185 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002186 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002187 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002188 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002189
2190 lines =<< trim END
2191 vim9script
2192 def EchoNr(nr = 34)
2193 g:echo = nr
2194 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002195 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002196 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002197 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002198 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002199 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002200 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002201 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002202
2203 lines =<< trim END
2204 vim9script
2205 def EchoList(...l: list<number>)
2206 g:echo = l
2207 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002208 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002209 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002210 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002211 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002212 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002213 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002214 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002215
2216 lines =<< trim END
2217 vim9script
2218 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2219 g:optarg = opt
2220 g:listarg = l
2221 return nr
2222 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002223 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002224 Funcref(10)->assert_equal(10)
2225 g:optarg->assert_equal(12)
2226 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002227
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002228 Funcref(11, 22)->assert_equal(11)
2229 g:optarg->assert_equal(22)
2230 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002231
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002232 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2233 g:optarg->assert_equal(18)
2234 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002235 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002236 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002237
2238 lines =<< trim END
2239 function s:func(num)
2240 return a:num * 2
2241 endfunction
2242
2243 def s:CallFuncref()
2244 var Funcref = function('s:func')
2245 Funcref(3)->assert_equal(6)
2246 enddef
2247 call s:CallFuncref()
2248 END
2249 v9.CheckScriptSuccess(lines)
2250
2251 lines =<< trim END
2252 function s:func(num)
2253 return a:num * 2
2254 endfunction
2255
2256 def s:CallFuncref()
2257 var Funcref = function(s:func)
2258 Funcref(3)->assert_equal(6)
2259 enddef
2260 call s:CallFuncref()
2261 END
2262 v9.CheckScriptSuccess(lines)
2263
2264 lines =<< trim END
2265 function s:func(num)
2266 return a:num * 2
2267 endfunction
2268
2269 def s:CallFuncref()
2270 var Funcref = s:func
2271 Funcref(3)->assert_equal(6)
2272 enddef
2273 call s:CallFuncref()
2274 END
2275 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002276enddef
2277
2278let SomeFunc = function('len')
2279let NotAFunc = 'text'
2280
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002281def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002282 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002283 var Ref1: func(bool): string
2284 var Ref2: func(bool): number
2285 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002286 Ref3 = g:cond ? Ref1 : Ref2
2287
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002288 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002289 var Refa1: func(bool): number
2290 var Refa2: func(bool, number): number
2291 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002292 Refa3 = g:cond ? Refa1 : Refa2
2293
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002294 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002295 var Refb1: func(bool, string): number
2296 var Refb2: func(string, number): number
2297 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002298 Refb3 = g:cond ? Refb1 : Refb2
2299enddef
2300
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002301def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002302 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002303enddef
2304
2305def DefinedEvenLater(arg: string): string
2306 return arg
2307enddef
2308
2309def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002310 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002311 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002312enddef
2313
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002314def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002315 var lines =<< trim END
2316 vim9script
2317 # Define an outer function
2318 def FirstFunction()
2319 # Define an inner function
2320 def SecondFunction()
2321 # the function has a body, a double free is detected.
2322 AAAAA
2323
2324 # enddef followed by | or } followed by # one or more characters
2325 enddef|BBBB
2326 enddef
2327
2328 # Compile all functions
2329 defcompile
2330 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002331 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002332enddef
2333
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002334def Test_nested_function_with_args_split()
2335 var lines =<< trim END
2336 vim9script
2337 def FirstFunction()
2338 def SecondFunction(
2339 )
2340 # had a double free if the right parenthesis of the nested function is
2341 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002342
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002343 enddef|BBBB
2344 enddef
2345 # Compile all functions
2346 defcompile
2347 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002348 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002349
2350 lines =<< trim END
2351 vim9script
2352 def FirstFunction()
2353 func SecondFunction()
2354 endfunc|BBBB
2355 enddef
2356 defcompile
2357 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002358 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002359enddef
2360
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002361def Test_error_in_function_args()
2362 var lines =<< trim END
2363 def FirstFunction()
2364 def SecondFunction(J =
2365 # Nois
2366 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002367
2368 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002369 enddef
2370 # Compile all functions
2371 defcompile
2372 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002373 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002374enddef
2375
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002376def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002377 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002378 'def Func(): number',
2379 'return "a"',
2380 'enddef',
2381 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002382 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002383 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002384 'def Func(): string',
2385 'return 1',
2386 'enddef',
2387 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002388 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002389 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002390 'def Func(): void',
2391 'return "a"',
2392 'enddef',
2393 'defcompile'],
2394 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002395 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002396 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002397 'def Func()',
2398 'return "a"',
2399 'enddef',
2400 'defcompile'],
2401 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002402 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002403
Bram Moolenaar62aec932022-01-29 21:45:34 +00002404 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002405 'def Func(): number',
2406 'return',
2407 'enddef',
2408 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002409 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002410
Bram Moolenaar62aec932022-01-29 21:45:34 +00002411 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002412 'def Func():number',
2413 'return 123',
2414 'enddef',
2415 'defcompile'], 'E1069:')
2416 delfunc! g:Func
2417
Bram Moolenaar62aec932022-01-29 21:45:34 +00002418 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002419 'def Func() :number',
2420 'return 123',
2421 'enddef',
2422 'defcompile'], 'E1059:')
2423 delfunc! g:Func
2424
Bram Moolenaar62aec932022-01-29 21:45:34 +00002425 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002426 'def Func() : number',
2427 'return 123',
2428 'enddef',
2429 'defcompile'], 'E1059:')
2430 delfunc! g:Func
2431
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002432 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002433 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002434 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002435 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002436 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002437 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002438
Bram Moolenaar62aec932022-01-29 21:45:34 +00002439 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002440 'vim9script',
2441 'def FuncB()',
2442 ' return 123',
2443 'enddef',
2444 'def FuncA()',
2445 ' FuncB()',
2446 'enddef',
2447 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002448enddef
2449
2450def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002451 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002452 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2453 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2454 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2455 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2456 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002457enddef
2458
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002459def Test_white_space_before_comma()
2460 var lines =<< trim END
2461 vim9script
2462 def Func(a: number , b: number)
2463 enddef
2464 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002465 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002466 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002467enddef
2468
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002469def Test_white_space_after_comma()
2470 var lines =<< trim END
2471 vim9script
2472 def Func(a: number,b: number)
2473 enddef
2474 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002475 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002476
2477 # OK in legacy function
2478 lines =<< trim END
2479 vim9script
2480 func Func(a,b)
2481 endfunc
2482 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002483 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002484enddef
2485
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002486def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002487 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002488 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002489 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002490 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002491 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002492 enddef
2493 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002494 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002495
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002496 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002497 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002498 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002499
Bram Moolenaar67979662020-06-20 22:50:47 +02002500 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002501 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002502 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002503
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002504 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002505 def ListFunc(arg: list<number>)
2506 listvar = arg
2507 enddef
2508 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002509 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002510
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002511 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002512 def DictFunc(arg: dict<number>)
2513 dictvar = arg
2514 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002515 {a: 1, b: 2}->DictFunc()
2516 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002517 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002518 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002519 enddef
2520 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002521 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002522
Bram Moolenaare0de1712020-12-02 17:36:54 +01002523 {a: 3, b: 4}->DictFunc()
2524 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002525
2526 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002527 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002528 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002529 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002530
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002531 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002532 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002533 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002534 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002535 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002536 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002537
2538 def UseString()
2539 'xyork'->MyFunc()
2540 enddef
2541 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002542 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002543
Bram Moolenaar10409562020-07-29 20:00:38 +02002544 def UseString2()
2545 "knife"->MyFunc()
2546 enddef
2547 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002548 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002549
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002550 # prepending a colon makes it a mark
2551 new
2552 setline(1, ['aaa', 'bbb', 'ccc'])
2553 normal! 3Gmt1G
2554 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002555 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002556 bwipe!
2557
Bram Moolenaare6b53242020-07-01 17:28:33 +02002558 MyFunc(
2559 'continued'
2560 )
2561 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002562 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002563 )
2564
2565 call MyFunc(
2566 'more'
2567 ..
2568 'lines'
2569 )
2570 assert_equal(
2571 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002572 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002573 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002574 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002575 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002576enddef
2577
2578def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002579 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002580 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002581 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002582 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002583 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002584 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002585 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002586 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002587 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002588enddef
2589
Bram Moolenaar65b95452020-07-19 14:03:09 +02002590def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002591 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002592 vim9script
2593 def MyFunc(arg: string)
2594 echo arg
2595 enddef
2596 MyFunc(1234)
2597 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002598 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002599enddef
2600
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002601def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002602 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002603 vim9script
2604 const var = ''
2605 def MyFunc(arg: string)
2606 var = 'asdf'
2607 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002608 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002609 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002610 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002611 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002612
2613 lines =<< trim END
2614 const g:Aconst = 77
2615 def Change()
2616 # comment
2617 g:Aconst = 99
2618 enddef
2619 call Change()
2620 unlet g:Aconst
2621 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002622 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002623enddef
2624
2625" Test that inside :function a Python function can be defined, :def is not
2626" recognized.
2627func Test_function_python()
2628 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002629 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002630 execute py "<< EOF"
2631def do_something():
2632 return 1
2633EOF
2634endfunc
2635
2636def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002637 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002638 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002639 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002640 echo 'hello'
2641 enddef
2642
2643 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002644 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002645 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002646 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002647
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002648 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002649 CallGoneSoon()
2650 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002651 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002652 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2653 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002654enddef
2655
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002656func Test_free_dict_while_in_funcstack()
2657 " relies on the sleep command
2658 CheckUnix
2659 call Run_Test_free_dict_while_in_funcstack()
2660endfunc
2661
2662def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002663 # this was freeing the TermRun() default argument dictionary while it was
2664 # still referenced in a funcstack_T
2665 var lines =<< trim END
2666 vim9script
2667
2668 &updatetime = 400
2669 def TermRun(_ = {})
2670 def Post()
2671 enddef
2672 def Exec()
2673 term_start('sleep 1', {
2674 term_finish: 'close',
2675 exit_cb: (_, _) => Post(),
2676 })
2677 enddef
2678 Exec()
2679 enddef
2680 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2681 timer_start(100, (_) => feedkeys("\<F4>"))
2682 timer_start(1000, (_) => feedkeys("\<F4>"))
2683 sleep 1500m
2684 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002685 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002686 nunmap <F4>
2687 set updatetime&
2688enddef
2689
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002690def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002691 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002692 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002693 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002694 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002695 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002696 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002697 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002698 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002699 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002700
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002701 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002702 g:Func1()->assert_equal('Func1')
2703 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002704
2705 delfunc! Func0
2706 delfunc! Func1
2707 delfunc! Func2
2708enddef
2709
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002710def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002711 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002712 vim9script
2713 func Func(arg)
2714 echo a:arg
2715 endfunc
2716 Func('text')
2717 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002718 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002719 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002720enddef
2721
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002722let s:funcResult = 0
2723
2724def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002725 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002726enddef
2727
2728def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002729 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002730 return 1234
2731enddef
2732
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002733def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002734 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002735 return 'text'
2736enddef
2737
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002738def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002739 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002740enddef
2741
2742def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002743 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002744 return arg
2745enddef
2746
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002747def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002748 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002749enddef
2750
Bram Moolenaar62aec932022-01-29 21:45:34 +00002751def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002752 return arg
2753enddef
2754
Bram Moolenaar62aec932022-01-29 21:45:34 +00002755def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002756 return arg
2757enddef
2758
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002759def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002760 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002761 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002762 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002763 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002764 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002765
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002766 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002767 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002768 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002769 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002770 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002771
Bram Moolenaar53900992020-08-22 19:02:02 +02002772 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002773 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002774 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002775 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002776
Bram Moolenaar53900992020-08-22 19:02:02 +02002777 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002778 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002779 Ref2()->assert_equal(1234)
2780 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002781
Bram Moolenaar53900992020-08-22 19:02:02 +02002782 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002783 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002784 Ref2(13)->assert_equal(13)
2785 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002786enddef
2787
Bram Moolenaar9978d472020-07-05 16:01:56 +02002788def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002789 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002790 for n in repeat([1], 3)
2791 res += n
2792 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002793 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002794
2795 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002796 for n in repeat(0z01, 3)->blob2list()
2797 res += n
2798 endfor
2799 res->assert_equal(3)
2800
2801 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002802 for n in add([1, 2], 3)
2803 res += n
2804 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002805 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002806enddef
2807
Bram Moolenaar846178a2020-07-05 17:04:13 +02002808def Test_argv_return_type()
2809 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002810 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002811 for name in argv()
2812 res ..= name
2813 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002814 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002815enddef
2816
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002817def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002818 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002819 RefVoid = g:FuncNoArgNoRet
2820 RefVoid = g:FuncOneArgNoRet
2821 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 +00002822 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 +02002823
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002824 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002825 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002826 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002827 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2828 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 +02002829
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002830 var RefAnyNoArgs: func: any = RefAny
2831
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002832 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002833 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002834 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002835 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 +00002836 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 +02002837
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002838 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002839 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002840 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002841 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2842 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 +02002843enddef
2844
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002845def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002846 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002847
Bram Moolenaar62aec932022-01-29 21:45:34 +00002848 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2849 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002850 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 +00002851 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2852 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 +02002853 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 +02002854
Bram Moolenaar62aec932022-01-29 21:45:34 +00002855 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2856 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2857 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:')
2858 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002859enddef
2860
Bram Moolenaar89228602020-04-05 22:14:54 +02002861def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002862 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002863 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002864 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002865
2866 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002867 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002868
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002869 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002870 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002871 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002872
Bram Moolenaar62aec932022-01-29 21:45:34 +00002873 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002874enddef
2875
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002876def Test_func_common_type()
2877 def FuncOne(n: number): number
2878 return n
2879 enddef
2880 def FuncTwo(s: string): number
2881 return len(s)
2882 enddef
2883 def FuncThree(n: number, s: string): number
2884 return n + len(s)
2885 enddef
2886 var list = [FuncOne, FuncTwo, FuncThree]
2887 assert_equal(8, list[0](8))
2888 assert_equal(4, list[1]('word'))
2889 assert_equal(7, list[2](3, 'word'))
2890enddef
2891
Bram Moolenaar62aec932022-01-29 21:45:34 +00002892def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002893 arg1: string,
2894 arg2 = 1234,
2895 ...rest: list<string>
2896 ): string
2897 return arg1 .. arg2 .. join(rest, '-')
2898enddef
2899
Bram Moolenaar2c330432020-04-13 14:41:35 +02002900def MultiLineComment(
2901 arg1: string, # comment
2902 arg2 = 1234, # comment
2903 ...rest: list<string> # comment
2904 ): string # comment
2905 return arg1 .. arg2 .. join(rest, '-')
2906enddef
2907
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002908def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002909 MultiLine('text')->assert_equal('text1234')
2910 MultiLine('text', 777)->assert_equal('text777')
2911 MultiLine('text', 777, 'one')->assert_equal('text777one')
2912 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002913enddef
2914
Bram Moolenaar23e03252020-04-12 22:22:31 +02002915func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002916 call s:MultiLine('text')->assert_equal('text1234')
2917 call s:MultiLine('text', 777)->assert_equal('text777')
2918 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2919 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002920endfunc
2921
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002922
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002923" When using CheckScriptFailure() for the below test, E1010 is generated instead
2924" of E1056.
2925func Test_E1056_1059()
2926 let caught_1056 = 0
2927 try
2928 def F():
2929 return 1
2930 enddef
2931 catch /E1056:/
2932 let caught_1056 = 1
2933 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002934 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002935
2936 let caught_1059 = 0
2937 try
2938 def F5(items : list)
2939 echo 'a'
2940 enddef
2941 catch /E1059:/
2942 let caught_1059 = 1
2943 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002944 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002945endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002946
Bram Moolenaar015f4262020-05-05 21:25:22 +02002947func DelMe()
2948 echo 'DelMe'
2949endfunc
2950
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002951def Test_error_reporting()
2952 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002953 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002954 " comment
2955 def Func()
2956 # comment
2957 # comment
2958 invalid
2959 enddef
2960 defcompile
2961 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002962 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002963 try
2964 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002965 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002966 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002967 v:exception->assert_match('Invalid command: invalid')
2968 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002969 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002970 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002971
2972 # comment lines after the start of the function
2973 lines =<< trim END
2974 " comment
2975 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002976 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002977 # comment
2978 # comment
2979 invalid
2980 enddef
2981 defcompile
2982 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002983 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002984 try
2985 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002986 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002987 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002988 v:exception->assert_match('Invalid command: invalid')
2989 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002990 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002991 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002992
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002993 lines =<< trim END
2994 vim9script
2995 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002996 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002997 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002998 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002999 enddef
3000 defcompile
3001 Func()
3002 END
Bram Moolenaar08052222020-09-14 17:04:31 +02003003 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02003004 try
3005 source Xdef
3006 assert_report('should have failed')
3007 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003008 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02003009 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003010 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02003011enddef
3012
Bram Moolenaar015f4262020-05-05 21:25:22 +02003013def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003014 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003015 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02003016 'delfunc g:DelMe',
3017 'echo RefMe()'], 'E117:')
3018enddef
3019
3020def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003021 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003022 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003023 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02003024enddef
3025
Bram Moolenaar62aec932022-01-29 21:45:34 +00003026def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02003027 return Ref('more')
3028enddef
3029
3030def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003031 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003032 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02003033enddef
3034
Bram Moolenaar62aec932022-01-29 21:45:34 +00003035def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003036 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003037 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003038enddef
3039
3040def Test_closure_ref_after_return()
3041 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003042 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003043 unlet g:Ref
3044enddef
3045
Bram Moolenaar62aec932022-01-29 21:45:34 +00003046def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003047 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003048 g:Extend = (s) => local->add(s)
3049 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003050enddef
3051
3052def Test_closure_two_refs()
3053 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003054 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003055 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003056 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003057 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003058 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003059
3060 unlet g:Extend
3061 unlet g:Read
3062enddef
3063
Bram Moolenaar62aec932022-01-29 21:45:34 +00003064def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003065 return join(Ref(), ' ')
3066enddef
3067
Bram Moolenaar62aec932022-01-29 21:45:34 +00003068def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003069 Ref(add)
3070enddef
3071
3072def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02003073 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003074 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003075 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003076 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003077 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003078 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003079
3080 unlet g:Extend
3081 unlet g:Read
3082enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003083
Bram Moolenaar62aec932022-01-29 21:45:34 +00003084def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003085 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003086 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003087enddef
3088
Bram Moolenaar62aec932022-01-29 21:45:34 +00003089def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003090 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003091 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003092enddef
3093
3094def Test_closure_using_argument()
3095 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003096 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003097
3098 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003099 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003100
3101 unlet g:UseArg
3102 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003103
3104 var lines =<< trim END
3105 vim9script
3106 def Test(Fun: func(number): number): list<number>
3107 return map([1, 2, 3], (_, i) => Fun(i))
3108 enddef
3109 def Inc(nr: number): number
3110 return nr + 2
3111 enddef
3112 assert_equal([3, 4, 5], Test(Inc))
3113 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003114 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003115enddef
3116
Bram Moolenaar62aec932022-01-29 21:45:34 +00003117def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003118 var local = 'a'
3119
3120 def Append(arg: string)
3121 local ..= arg
3122 enddef
3123 g:Append = Append
3124
3125 def Get(): string
3126 return local
3127 enddef
3128 g:Get = Get
3129enddef
3130
3131def Test_closure_append_get()
3132 MakeGetAndAppendRefs()
3133 g:Get()->assert_equal('a')
3134 g:Append('-b')
3135 g:Get()->assert_equal('a-b')
3136 g:Append('-c')
3137 g:Get()->assert_equal('a-b-c')
3138
3139 unlet g:Append
3140 unlet g:Get
3141enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003142
Bram Moolenaar04b12692020-05-04 23:24:44 +02003143def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003144 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003145 def Closure(arg: string): string
3146 return local .. arg
3147 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003148 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003149enddef
3150
Bram Moolenaar62aec932022-01-29 21:45:34 +00003151func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003152 return a:Ref('some')
3153endfunc
3154
3155def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003156 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003157 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003158 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003159enddef
3160
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003161def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003162 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003163 vim9script
3164 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003165 var name = 0
3166 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003167 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003168 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003169 enddef
3170 Func()
3171 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003172 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003173enddef
3174
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003175def Test_nested_closure_used()
3176 var lines =<< trim END
3177 vim9script
3178 def Func()
3179 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003180 var Closure = () => x
3181 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003182 enddef
3183 Func()
3184 assert_equal('hello', g:Myclosure())
3185 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003186 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003187enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003188
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003189def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003190 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003191 vim9script
3192 def FuncA()
3193 FuncB(0)
3194 enddef
3195 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003196 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003197 enddef
3198 FuncA()
3199 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003200 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003201enddef
3202
Bram Moolenaar6de22962022-09-09 21:35:36 +01003203def Run_Test_closure_in_for_loop_fails()
Drew Vogelea67ba72025-05-07 22:05:17 +02003204 CheckScreendump
Bram Moolenaar6de22962022-09-09 21:35:36 +01003205 var lines =<< trim END
3206 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003207 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003208 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003209 # time should be enough for startup to finish
3210 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003211 echo n
3212 })
3213 endfor
3214 END
3215 writefile(lines, 'XTest_closure_fails', 'D')
3216
3217 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003218 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003219 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003220
3221 # clean up
3222 g:StopVimInTerminal(buf)
3223enddef
3224
3225func Test_closure_in_for_loop_fails()
3226 CheckScreendump
3227 call Run_Test_closure_in_for_loop_fails()
3228endfunc
3229
Bram Moolenaarf112f302020-12-20 17:47:52 +01003230def Test_global_closure()
3231 var lines =<< trim END
3232 vim9script
3233 def ReverseEveryNLines(n: number, line1: number, line2: number)
3234 var mods = 'sil keepj keepp lockm '
3235 var range = ':' .. line1 .. ',' .. line2
3236 def g:Offset(): number
3237 var offset = (line('.') - line1 + 1) % n
3238 return offset != 0 ? offset : n
3239 enddef
3240 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3241 enddef
3242
3243 new
3244 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3245 ReverseEveryNLines(3, 1, 9)
3246 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003247 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003248 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3249 assert_equal(expected, getline(1, 9))
3250 bwipe!
3251enddef
3252
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003253def Test_global_closure_called_directly()
3254 var lines =<< trim END
3255 vim9script
3256 def Outer()
3257 var x = 1
3258 def g:Inner()
3259 var y = x
3260 x += 1
3261 assert_equal(1, y)
3262 enddef
3263 g:Inner()
3264 assert_equal(2, x)
3265 enddef
3266 Outer()
3267 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003268 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003269 delfunc g:Inner
3270enddef
3271
Bram Moolenaar69c76172021-12-02 16:38:52 +00003272def Test_closure_called_from_legacy()
3273 var lines =<< trim END
3274 vim9script
3275 def Func()
3276 var outer = 'foo'
3277 var F = () => {
3278 outer = 'bar'
3279 }
3280 execute printf('call %s()', string(F))
3281 enddef
3282 Func()
3283 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003284 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003285enddef
3286
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003287def Test_failure_in_called_function()
3288 # this was using the frame index as the return value
3289 var lines =<< trim END
3290 vim9script
3291 au TerminalWinOpen * eval [][0]
3292 def PopupTerm(a: any)
3293 # make sure typvals on stack are string
3294 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3295 FireEvent()
3296 enddef
3297 def FireEvent()
3298 do TerminalWinOpen
3299 enddef
3300 # use try/catch to make eval fail
3301 try
3302 call PopupTerm(0)
3303 catch
3304 endtry
3305 au! TerminalWinOpen
3306 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003307 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003308enddef
3309
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003310def Test_nested_lambda()
3311 var lines =<< trim END
3312 vim9script
3313 def Func()
3314 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003315 var Lambda1 = () => 7
3316 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003317 var res = Lambda2()
3318 assert_equal([7, 4], res)
3319 enddef
3320 Func()
3321 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003322 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003323enddef
3324
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003325def Test_double_nested_lambda()
3326 var lines =<< trim END
3327 vim9script
3328 def F(head: string): func(string): func(string): string
3329 return (sep: string): func(string): string => ((tail: string): string => {
3330 return head .. sep .. tail
3331 })
3332 enddef
3333 assert_equal('hello-there', F('hello')('-')('there'))
3334 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003335 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003336enddef
3337
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003338def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003339 var lines =<< trim END
3340 vim9script
3341 def F(text: string): func(string): func(string): string
3342 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003343 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003344 })
3345 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003346 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003347 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003348 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003349
3350 lines =<< trim END
3351 vim9script
3352 echo range(4)->mapnew((_, v) => {
3353 return range(v) ->mapnew((_, s) => {
3354 return string(s)
3355 })
3356 })
3357 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003358 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003359
3360 lines =<< trim END
3361 vim9script
3362
Bram Moolenaara749a422022-02-12 19:52:25 +00003363 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003364 range(10)
3365 ->mapnew((_, _) => ({
3366 key: range(10)->mapnew((_, _) => {
3367 return ' '
3368 }),
3369 }))
3370 enddef
3371
3372 defcomp
3373 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003374 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003375enddef
3376
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003377def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003378 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003379 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003380enddef
3381
3382def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003383 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003384enddef
3385
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003386def Test_compiling_referenced_func_no_shadow()
3387 var lines =<< trim END
3388 vim9script
3389
3390 def InitializeReply(lspserver: dict<any>)
3391 enddef
3392
3393 def ProcessReply(lspserver: dict<any>)
3394 var lsp_reply_handlers: dict<func> =
3395 { 'initialize': InitializeReply }
3396 lsp_reply_handlers['initialize'](lspserver)
3397 enddef
3398
3399 call ProcessReply({})
3400 END
3401 v9.CheckScriptSuccess(lines)
3402enddef
3403
Bram Moolenaar62aec932022-01-29 21:45:34 +00003404def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003405 var path: string = empty(dir)
3406 \ ? 'empty'
3407 \ : 'full'
3408 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003409enddef
3410
3411def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003412 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003413enddef
3414
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003415def Test_script_var_in_lambda()
3416 var lines =<< trim END
3417 vim9script
3418 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003419 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003420 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003421 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003422enddef
3423
Bram Moolenaar62aec932022-01-29 21:45:34 +00003424def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003425 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003426 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003427 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003428 ->reverse()
3429 return x
3430enddef
3431
3432def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003433 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003434
3435 var lines =<< trim END
3436 vim9script
3437 var res = [{n: 1, m: 2, s: 'xxx'}]
3438 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3439 v.n,
3440 v.m,
3441 substitute(v.s, '.*', 'yyy', '')
3442 ))
3443 assert_equal(['1:2:yyy'], res)
3444 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003445 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003446enddef
3447
Bram Moolenaarb6571982021-01-08 22:24:19 +01003448def Test_list_lambda()
3449 timer_start(1000, (_) => 0)
3450 var body = execute(timer_info()[0].callback
3451 ->string()
3452 ->substitute("('", ' ', '')
3453 ->substitute("')", '', '')
3454 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003455 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003456enddef
3457
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003458def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003459 var lines =<< trim END
3460 vim9script
3461 var flist: list<func>
3462 for i in range(10)
3463 var inloop = i
3464 flist[i] = () => inloop
3465 endfor
3466 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003467 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003468
3469 lines =<< trim END
3470 vim9script
3471 if true
3472 var outloop = 5
3473 var flist: list<func>
3474 for i in range(10)
3475 flist[i] = () => outloop
3476 endfor
3477 endif
3478 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003479 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003480
3481 lines =<< trim END
3482 vim9script
3483 if true
3484 var outloop = 5
3485 endif
3486 var flist: list<func>
3487 for i in range(10)
3488 flist[i] = () => outloop
3489 endfor
3490 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003491 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003492
3493 lines =<< trim END
3494 vim9script
3495 for i in range(10)
3496 var Ref = () => 0
3497 endfor
3498 assert_equal(0, ((i) => 0)(0))
3499 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003500 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003501enddef
3502
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003503def Test_legacy_lambda()
3504 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003505
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003506 var lines =<< trim END
3507 echo {x -> 'hello ' .. x}('foo')
3508 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003509 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003510
3511 lines =<< trim END
3512 vim9script
3513 def Func()
3514 echo (() => 'no error')()
3515 enddef
3516 legacy call s:Func()
3517 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003518 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003519enddef
3520
Bram Moolenaarce024c32021-06-26 13:00:49 +02003521def Test_legacy()
3522 var lines =<< trim END
3523 vim9script
3524 func g:LegacyFunction()
3525 let g:legacyvar = 1
3526 endfunc
3527 def Testit()
3528 legacy call g:LegacyFunction()
3529 enddef
3530 Testit()
3531 assert_equal(1, g:legacyvar)
3532 unlet g:legacyvar
3533 delfunc g:LegacyFunction
3534 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003535 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003536enddef
3537
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003538def Test_legacy_errors()
3539 for cmd in ['if', 'elseif', 'else', 'endif',
3540 'for', 'endfor', 'continue', 'break',
3541 'while', 'endwhile',
3542 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003543 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003544 endfor
3545enddef
3546
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003547def Test_call_legacy_with_dict()
3548 var lines =<< trim END
3549 vim9script
3550 func Legacy() dict
3551 let g:result = self.value
3552 endfunc
3553 def TestDirect()
3554 var d = {value: 'yes', func: Legacy}
3555 d.func()
3556 enddef
3557 TestDirect()
3558 assert_equal('yes', g:result)
3559 unlet g:result
3560
3561 def TestIndirect()
3562 var d = {value: 'foo', func: Legacy}
3563 var Fi = d.func
3564 Fi()
3565 enddef
3566 TestIndirect()
3567 assert_equal('foo', g:result)
3568 unlet g:result
3569
3570 var d = {value: 'bar', func: Legacy}
3571 d.func()
3572 assert_equal('bar', g:result)
3573 unlet g:result
3574 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003575 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003576enddef
3577
Bram Moolenaar62aec932022-01-29 21:45:34 +00003578def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003579 # closure nested inside another closure using argument
3580 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3581 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3582enddef
3583
3584def Test_nested_closure_using_argument()
3585 assert_equal(['x', 'x2'], DoFilterThis('x'))
3586enddef
3587
Bram Moolenaar0186e582021-01-10 18:33:11 +01003588def Test_triple_nested_closure()
3589 var what = 'x'
3590 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3591 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3592 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3593enddef
3594
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003595func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003596 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003597 call Run_Test_silent_echo()
3598endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003599
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003600def Run_Test_silent_echo()
Drew Vogelea67ba72025-05-07 22:05:17 +02003601 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003602 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003603 vim9script
3604 def EchoNothing()
3605 silent echo ''
3606 enddef
3607 defcompile
3608 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003609 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003610
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003611 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003612 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003613 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003614 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003615
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003616 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003617 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003618enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003619
Bram Moolenaar171fb922020-10-28 16:54:47 +01003620def SilentlyError()
3621 execute('silent! invalid')
3622 g:did_it = 'yes'
3623enddef
3624
Bram Moolenaar62aec932022-01-29 21:45:34 +00003625func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003626 silent! invalid
3627endfunc
3628
3629def SilentlyUserError()
3630 UserError()
3631 g:did_it = 'yes'
3632enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003633
3634" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003635func Test_ignore_silent_error()
3636 let g:did_it = 'no'
3637 call SilentlyError()
3638 call assert_equal('yes', g:did_it)
3639
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003640 let g:did_it = 'no'
3641 call SilentlyUserError()
3642 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003643
3644 unlet g:did_it
3645endfunc
3646
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003647def Test_ignore_silent_error_in_filter()
3648 var lines =<< trim END
3649 vim9script
3650 def Filter(winid: number, key: string): bool
3651 if key == 'o'
3652 silent! eval [][0]
3653 return true
3654 endif
3655 return popup_filter_menu(winid, key)
3656 enddef
3657
Bram Moolenaare0de1712020-12-02 17:36:54 +01003658 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003659 feedkeys("o\r", 'xnt')
3660 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003661 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003662enddef
3663
Bram Moolenaar62aec932022-01-29 21:45:34 +00003664def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003665 if n < 2
3666 return n
3667 else
3668 return Fibonacci(n - 1) + Fibonacci(n - 2)
3669 endif
3670enddef
3671
Bram Moolenaar985116a2020-07-12 17:31:09 +02003672def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003673 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003674enddef
3675
Bram Moolenaar62aec932022-01-29 21:45:34 +00003676def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003677 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003678 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003679 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003680 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003681 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003682enddef
3683
3684def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003685 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003686 writefile(['111'], 'XclosureDir/file1')
3687 writefile(['222'], 'XclosureDir/file2')
3688 writefile(['333'], 'XclosureDir/tdir/file3')
3689
Bram Moolenaare0de1712020-12-02 17:36:54 +01003690 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003691enddef
3692
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003693def Test_invalid_function_name()
3694 var lines =<< trim END
3695 vim9script
3696 def s: list<string>
3697 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003698 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003699
3700 lines =<< trim END
3701 vim9script
3702 def g: list<string>
3703 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003704 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003705
3706 lines =<< trim END
3707 vim9script
3708 def <SID>: list<string>
3709 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003710 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003711
3712 lines =<< trim END
3713 vim9script
3714 def F list<string>
3715 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003716 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003717enddef
3718
Bram Moolenaara90afb92020-07-15 22:38:56 +02003719def Test_partial_call()
John Marriott45377e22025-03-27 18:12:32 +01003720 CheckFeature quickfix
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003721 var lines =<< trim END
3722 var Xsetlist: func
3723 Xsetlist = function('setloclist', [0])
3724 Xsetlist([], ' ', {title: 'test'})
3725 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003726
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003727 Xsetlist = function('setloclist', [0, [], ' '])
3728 Xsetlist({title: 'test'})
3729 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003730
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003731 Xsetlist = function('setqflist')
3732 Xsetlist([], ' ', {title: 'test'})
3733 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003734
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003735 Xsetlist = function('setqflist', [[], ' '])
3736 Xsetlist({title: 'test'})
3737 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003738
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003739 var Len: func: number = function('len', ['word'])
3740 assert_equal(4, Len())
3741
3742 var RepeatFunc = function('repeat', ['o'])
3743 assert_equal('ooooo', RepeatFunc(5))
3744 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003745 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003746
3747 lines =<< trim END
3748 vim9script
3749 def Foo(Parser: any)
3750 enddef
3751 var Expr: func(dict<any>): dict<any>
3752 const Call = Foo(Expr)
3753 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003754 v9.CheckScriptFailure(lines, 'E1031:')
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02003755
3756 # Test for calling a partial that takes a single argument.
3757 # This used to produce a "E340: Internal error" message.
3758 lines =<< trim END
3759 def Foo(n: number): number
3760 return n * 2
3761 enddef
3762 var Fn = function(Foo, [10])
3763 assert_equal(20, Fn())
3764 END
3765 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara90afb92020-07-15 22:38:56 +02003766enddef
3767
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003768def Test_partial_double_nested()
3769 var idx = 123
3770 var Get = () => idx
3771 var Ref = function(Get, [])
3772 var RefRef = function(Ref, [])
3773 assert_equal(123, RefRef())
3774enddef
3775
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003776def Test_partial_null_function()
3777 var lines =<< trim END
3778 var d: dict<func> = {f: null_function}
3779 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003780 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003781 END
3782 v9.CheckDefAndScriptSuccess(lines)
3783enddef
3784
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003785def Test_cmd_modifier()
3786 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003787 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003788enddef
3789
3790def Test_restore_modifiers()
3791 # check that when compiling a :def function command modifiers are not messed
3792 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003793 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003794 vim9script
3795 set eventignore=
3796 autocmd QuickFixCmdPost * copen
3797 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003798 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003799 enddef
3800 func Func()
3801 noautocmd call s:AutocmdsDisabled()
3802 let g:ei_after = &eventignore
3803 endfunc
3804 Func()
3805 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003806 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003807 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003808enddef
3809
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003810def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003811 eval 1 + 2
3812 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003813 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003814 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003815enddef
3816
3817def StackBot()
3818 # throw an error
3819 eval [][0]
3820enddef
3821
3822def Test_callstack_def()
3823 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003824 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003825 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003826 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003827 endtry
3828enddef
3829
Bram Moolenaare8211a32020-10-09 22:04:29 +02003830" Re-using spot for variable used in block
3831def Test_block_scoped_var()
3832 var lines =<< trim END
3833 vim9script
3834 def Func()
3835 var x = ['a', 'b', 'c']
3836 if 1
3837 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003838 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003839 endif
3840 var z = x
3841 assert_equal(['x', 'x', 'x'], z)
3842 enddef
3843 Func()
3844 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003845 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003846enddef
3847
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003848def Test_reset_did_emsg()
3849 var lines =<< trim END
3850 @s = 'blah'
3851 au BufWinLeave * #
3852 def Func()
3853 var winid = popup_create('popup', {})
3854 exe '*s'
3855 popup_close(winid)
3856 enddef
3857 Func()
3858 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003859 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003860 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003861enddef
3862
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003863def Test_did_emsg_reset()
3864 # executing an autocommand resets did_emsg, this should not result in a
3865 # builtin function considered failing
3866 var lines =<< trim END
3867 vim9script
3868 au BufWinLeave * #
3869 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003870 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003871 eval [][0]
3872 enddef
3873 nno <F3> <cmd>call <sid>Func()<cr>
3874 feedkeys("\<F3>\e", 'xt')
3875 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003876 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003877 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003878
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003879 nunmap <F3>
3880 au! BufWinLeave
3881enddef
3882
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003883def Test_abort_with_silent_call()
3884 var lines =<< trim END
3885 vim9script
3886 g:result = 'none'
3887 def Func()
3888 g:result += 3
3889 g:result = 'yes'
3890 enddef
3891 # error is silenced, but function aborts on error
3892 silent! Func()
3893 assert_equal('none', g:result)
3894 unlet g:result
3895 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003896 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003897enddef
3898
Bram Moolenaarf665e972020-12-05 19:17:16 +01003899def Test_continues_with_silent_error()
3900 var lines =<< trim END
3901 vim9script
3902 g:result = 'none'
3903 def Func()
3904 silent! g:result += 3
3905 g:result = 'yes'
3906 enddef
3907 # error is silenced, function does not abort
3908 Func()
3909 assert_equal('yes', g:result)
3910 unlet g:result
3911 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003912 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003913enddef
3914
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003915def Test_abort_even_with_silent()
3916 var lines =<< trim END
3917 vim9script
3918 g:result = 'none'
3919 def Func()
3920 eval {-> ''}() .. '' .. {}['X']
3921 g:result = 'yes'
3922 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003923 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003924 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003925 unlet g:result
3926 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003927 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003928enddef
3929
Bram Moolenaarf665e972020-12-05 19:17:16 +01003930def Test_cmdmod_silent_restored()
3931 var lines =<< trim END
3932 vim9script
3933 def Func()
3934 g:result = 'none'
3935 silent! g:result += 3
3936 g:result = 'none'
3937 g:result += 3
3938 enddef
3939 Func()
3940 END
3941 # can't use CheckScriptFailure, it ignores the :silent!
3942 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003943 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003944 var caught = 'no'
3945 try
3946 exe 'source ' .. fname
3947 catch /E1030:/
3948 caught = 'yes'
3949 assert_match('Func, line 4', v:throwpoint)
3950 endtry
3951 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003952enddef
3953
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003954def Test_cmdmod_silent_nested()
3955 var lines =<< trim END
3956 vim9script
3957 var result = ''
3958
3959 def Error()
3960 result ..= 'Eb'
3961 eval [][0]
3962 result ..= 'Ea'
3963 enddef
3964
3965 def Crash()
3966 result ..= 'Cb'
3967 sil! Error()
3968 result ..= 'Ca'
3969 enddef
3970
3971 Crash()
3972 assert_equal('CbEbEaCa', result)
3973 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003974 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003975enddef
3976
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003977def Test_dict_member_with_silent()
3978 var lines =<< trim END
3979 vim9script
3980 g:result = 'none'
3981 var d: dict<any>
3982 def Func()
3983 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003984 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003985 catch
3986 endtry
3987 enddef
3988 silent! Func()
3989 assert_equal('0', g:result)
3990 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003991 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003992 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003993enddef
3994
Bram Moolenaarf9041332021-01-21 19:41:16 +01003995def Test_skip_cmds_with_silent()
3996 var lines =<< trim END
3997 vim9script
3998
3999 def Func(b: bool)
4000 Crash()
4001 enddef
4002
4003 def Crash()
4004 sil! :/not found/d _
4005 sil! :/not found/put _
4006 enddef
4007
4008 Func(true)
4009 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004010 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01004011enddef
4012
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01004013def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00004014 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01004015 def g:Opfunc(_: any): string
4016 setline(1, 'ASDF')
4017 return ''
4018 enddef
4019 new
4020 setline(1, 'asdf')
4021 feedkeys("\<F3>$", 'x')
4022 assert_equal('ASDF', getline(1))
4023
4024 bwipe!
4025 nunmap <F3>
4026enddef
4027
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004028func Test_opfunc_error()
4029 CheckScreendump
4030 call Run_Test_opfunc_error()
4031endfunc
4032
4033def Run_Test_opfunc_error()
4034 # test that the error from Opfunc() is displayed right away
4035 var lines =<< trim END
4036 vim9script
4037
4038 def Opfunc(type: string)
4039 try
4040 eval [][0]
4041 catch /nothing/ # error not caught
4042 endtry
4043 enddef
4044 &operatorfunc = Opfunc
4045 nnoremap <expr> l <SID>L()
4046 def L(): string
4047 return 'l'
4048 enddef
4049 'x'->repeat(10)->setline(1)
4050 feedkeys('g@l', 'n')
4051 feedkeys('llll')
4052 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004053 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004054
Bram Moolenaar62aec932022-01-29 21:45:34 +00004055 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
4056 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01004057 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004058
4059 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00004060 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004061enddef
4062
Bram Moolenaar077a4232020-12-22 18:33:27 +01004063" this was crashing on exit
4064def Test_nested_lambda_in_closure()
4065 var lines =<< trim END
4066 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004067 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004068 def Outer()
4069 def g:Inner()
4070 echo map([1, 2, 3], {_, v -> v + 1})
4071 enddef
4072 g:Inner()
4073 enddef
4074 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004075 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01004076 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004077 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004078 return
4079 endif
4080 assert_equal(['Done'], readfile('XnestedDone'))
4081 delete('XnestedDone')
4082enddef
4083
Bram Moolenaar92368aa2022-02-07 17:50:39 +00004084def Test_nested_closure_funcref()
4085 var lines =<< trim END
4086 vim9script
4087 def Func()
4088 var n: number
4089 def Nested()
4090 ++n
4091 enddef
4092 Nested()
4093 g:result_one = n
4094 var Ref = function(Nested)
4095 Ref()
4096 g:result_two = n
4097 enddef
4098 Func()
4099 END
4100 v9.CheckScriptSuccess(lines)
4101 assert_equal(1, g:result_one)
4102 assert_equal(2, g:result_two)
4103 unlet g:result_one g:result_two
4104enddef
4105
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004106def Test_nested_closure_in_dict()
4107 var lines =<< trim END
4108 vim9script
4109 def Func(): dict<any>
4110 var n: number
4111 def Inc(): number
4112 ++n
4113 return n
4114 enddef
4115 return {inc: function(Inc)}
4116 enddef
4117 disas Func
4118 var d = Func()
4119 assert_equal(1, d.inc())
4120 assert_equal(2, d.inc())
4121 END
4122 v9.CheckScriptSuccess(lines)
4123enddef
4124
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004125def Test_script_local_other_script()
4126 var lines =<< trim END
4127 function LegacyJob()
4128 let FuncRef = function('s:close_cb')
4129 endfunction
4130 function s:close_cb(...)
4131 endfunction
4132 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004133 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004134 source Xlegacy.vim
4135 g:LegacyJob()
4136 g:LegacyJob()
4137 g:LegacyJob()
4138
4139 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004140enddef
4141
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004142def Test_check_func_arg_types()
4143 var lines =<< trim END
4144 vim9script
4145 def F1(x: string): string
4146 return x
4147 enddef
4148
4149 def F2(x: number): number
4150 return x + 1
4151 enddef
4152
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004153 def G(Fg: func): dict<func>
4154 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004155 enddef
4156
4157 def H(d: dict<func>): string
4158 return d.f('a')
4159 enddef
4160 END
4161
Bram Moolenaar62aec932022-01-29 21:45:34 +00004162 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4163 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004164
4165 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004166enddef
4167
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004168def Test_call_func_with_null()
4169 var lines =<< trim END
4170 def Fstring(v: string)
4171 assert_equal(null_string, v)
4172 enddef
4173 Fstring(null_string)
4174 def Fblob(v: blob)
4175 assert_equal(null_blob, v)
4176 enddef
4177 Fblob(null_blob)
4178 def Flist(v: list<number>)
4179 assert_equal(null_list, v)
4180 enddef
4181 Flist(null_list)
4182 def Fdict(v: dict<number>)
4183 assert_equal(null_dict, v)
4184 enddef
4185 Fdict(null_dict)
4186 def Ffunc(Fv: func(number): number)
4187 assert_equal(null_function, Fv)
4188 enddef
4189 Ffunc(null_function)
4190 if has('channel')
4191 def Fchannel(v: channel)
4192 assert_equal(null_channel, v)
4193 enddef
4194 Fchannel(null_channel)
4195 def Fjob(v: job)
4196 assert_equal(null_job, v)
4197 enddef
4198 Fjob(null_job)
4199 endif
4200 END
4201 v9.CheckDefAndScriptSuccess(lines)
4202enddef
4203
4204def Test_null_default_argument()
4205 var lines =<< trim END
4206 def Fstring(v: string = null_string)
4207 assert_equal(null_string, v)
4208 enddef
4209 Fstring()
4210 def Fblob(v: blob = null_blob)
4211 assert_equal(null_blob, v)
4212 enddef
4213 Fblob()
4214 def Flist(v: list<number> = null_list)
4215 assert_equal(null_list, v)
4216 enddef
4217 Flist()
4218 def Fdict(v: dict<number> = null_dict)
4219 assert_equal(null_dict, v)
4220 enddef
4221 Fdict()
4222 def Ffunc(Fv: func(number): number = null_function)
4223 assert_equal(null_function, Fv)
4224 enddef
4225 Ffunc()
4226 if has('channel')
4227 def Fchannel(v: channel = null_channel)
4228 assert_equal(null_channel, v)
4229 enddef
4230 Fchannel()
4231 def Fjob(v: job = null_job)
4232 assert_equal(null_job, v)
4233 enddef
4234 Fjob()
4235 endif
4236 END
4237 v9.CheckDefAndScriptSuccess(lines)
4238enddef
4239
4240def Test_null_return()
4241 var lines =<< trim END
4242 def Fstring(): string
4243 return null_string
4244 enddef
4245 assert_equal(null_string, Fstring())
4246 def Fblob(): blob
4247 return null_blob
4248 enddef
4249 assert_equal(null_blob, Fblob())
4250 def Flist(): list<number>
4251 return null_list
4252 enddef
4253 assert_equal(null_list, Flist())
4254 def Fdict(): dict<number>
4255 return null_dict
4256 enddef
4257 assert_equal(null_dict, Fdict())
4258 def Ffunc(): func(number): number
4259 return null_function
4260 enddef
4261 assert_equal(null_function, Ffunc())
4262 if has('channel')
4263 def Fchannel(): channel
4264 return null_channel
4265 enddef
4266 assert_equal(null_channel, Fchannel())
4267 def Fjob(): job
4268 return null_job
4269 enddef
4270 assert_equal(null_job, Fjob())
4271 endif
4272 END
4273 v9.CheckDefAndScriptSuccess(lines)
4274enddef
4275
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004276def Test_list_any_type_checked()
4277 var lines =<< trim END
4278 vim9script
4279 def Foo()
4280 --decl--
4281 Bar(l)
4282 enddef
4283 def Bar(ll: list<dict<any>>)
4284 enddef
4285 Foo()
4286 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004287 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004288 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004289 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004290 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004291 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004292
4293 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004294 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004295enddef
4296
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004297def Test_compile_error()
4298 var lines =<< trim END
4299 def g:Broken()
4300 echo 'a' + {}
4301 enddef
4302 call g:Broken()
4303 END
4304 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004305 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004306
4307 # Second call won't try compiling again
4308 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004309 delfunc g:Broken
4310
4311 # No error when compiling with :silent!
4312 lines =<< trim END
4313 def g:Broken()
4314 echo 'a' + []
4315 enddef
4316 silent! defcompile
4317 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004318 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004319
4320 # Calling the function won't try compiling again
4321 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4322 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004323enddef
4324
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004325def Test_ignored_argument()
4326 var lines =<< trim END
4327 vim9script
4328 def Ignore(_, _): string
4329 return 'yes'
4330 enddef
4331 assert_equal('yes', Ignore(1, 2))
4332
4333 func Ok(_)
4334 return a:_
4335 endfunc
4336 assert_equal('ok', Ok('ok'))
4337
4338 func Oktoo()
4339 let _ = 'too'
4340 return _
4341 endfunc
4342 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004343
4344 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004345 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004346 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004347
4348 lines =<< trim END
4349 def Ignore(_: string): string
4350 return _
4351 enddef
4352 defcompile
4353 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004354 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004355
4356 lines =<< trim END
4357 var _ = 1
4358 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004359 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004360
4361 lines =<< trim END
4362 var x = _
4363 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004364 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004365enddef
4366
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004367def Test_too_many_arguments()
4368 var lines =<< trim END
4369 echo [0, 1, 2]->map(() => 123)
4370 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004371 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004372
4373 lines =<< trim END
4374 echo [0, 1, 2]->map((_) => 123)
4375 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004376 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004377
4378 lines =<< trim END
4379 vim9script
4380 def OneArgument(arg: string)
4381 echo arg
4382 enddef
4383 var Ref = OneArgument
4384 Ref('a', 'b')
4385 END
4386 v9.CheckScriptFailure(lines, 'E118:')
4387enddef
4388
4389def Test_funcref_with_base()
4390 var lines =<< trim END
4391 vim9script
4392 def TwoArguments(str: string, nr: number)
4393 echo str nr
4394 enddef
4395 var Ref = TwoArguments
4396 Ref('a', 12)
4397 'b'->Ref(34)
4398 END
4399 v9.CheckScriptSuccess(lines)
4400
4401 lines =<< trim END
4402 vim9script
4403 def TwoArguments(str: string, nr: number)
4404 echo str nr
4405 enddef
4406 var Ref = TwoArguments
4407 'a'->Ref('b')
4408 END
4409 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4410
4411 lines =<< trim END
4412 vim9script
4413 def TwoArguments(str: string, nr: number)
4414 echo str nr
4415 enddef
4416 var Ref = TwoArguments
4417 123->Ref(456)
4418 END
4419 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4420
4421 lines =<< trim END
4422 vim9script
4423 def TwoArguments(nr: number, str: string)
4424 echo str nr
4425 enddef
4426 var Ref = TwoArguments
4427 123->Ref('b')
4428 def AndNowCompiled()
4429 456->Ref('x')
4430 enddef
4431 AndNowCompiled()
4432 END
4433 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004434enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004435
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004436def Test_closing_brace_at_start_of_line()
4437 var lines =<< trim END
4438 def Func()
4439 enddef
4440 Func(
4441 )
4442 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004443 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004444enddef
4445
Bram Moolenaar62aec932022-01-29 21:45:34 +00004446func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004447 let g:mydict = {}
4448 func g:mydict.afunc()
4449 let g:result = self.key
4450 endfunc
4451endfunc
4452
4453def Test_numbered_function_reference()
4454 CreateMydict()
4455 var output = execute('legacy func g:mydict.afunc')
4456 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4457 execute 'function(' .. funcName .. ', [], {key: 42})()'
4458 # check that the function still exists
4459 assert_equal(output, execute('legacy func g:mydict.afunc'))
4460 unlet g:mydict
4461enddef
4462
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004463def Test_numbered_function_call()
4464 var lines =<< trim END
4465 let s:legacyscript = {}
4466 func s:legacyscript.Helper() abort
4467 return "Success"
4468 endfunc
4469 let g:legacyscript = deepcopy(s:legacyscript)
4470
4471 let g:legacy_result = eval("g:legacyscript.Helper()")
4472 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4473 END
4474 v9.CheckScriptSuccess(lines)
4475 assert_equal('Success', g:legacy_result)
4476 assert_equal('Success', g:vim9_result)
4477
4478 unlet g:legacy_result
4479 unlet g:vim9_result
4480enddef
4481
Bram Moolenaard3a11782022-01-05 16:50:40 +00004482def Test_go_beyond_end_of_cmd()
4483 # this was reading the byte after the end of the line
4484 var lines =<< trim END
4485 def F()
4486 cal
4487 enddef
4488 defcompile
4489 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004490 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004491enddef
4492
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004493" Test for memory allocation failure when defining a new lambda
4494func Test_lambda_allocation_failure()
4495 new
4496 let lines =<< trim END
4497 vim9script
4498 g:Xlambda = (x): number => {
4499 return x + 1
4500 }
4501 END
4502 call setline(1, lines)
4503 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4504 call assert_fails('source', 'E342:')
4505 call assert_false(exists('g:Xlambda'))
4506 bw!
4507endfunc
4508
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004509def Test_lambda_argument_type_check()
4510 var lines =<< trim END
4511 vim9script
4512
4513 def Scan(ll: list<any>): func(func(any))
4514 return (Emit: func(any)) => {
4515 for e in ll
4516 Emit(e)
4517 endfor
4518 }
4519 enddef
4520
4521 def Sum(Cont: func(func(any))): any
4522 var sum = 0.0
4523 Cont((v: float) => { # <== NOTE: the lambda expects a float
4524 sum += v
4525 })
4526 return sum
4527 enddef
4528
Bram Moolenaar47bba532023-01-20 18:49:46 +00004529 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004530 echo Scan(ml)->Sum()
4531 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004532 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004533enddef
4534
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004535def Test_multiple_funcref()
4536 # This was using a NULL pointer
4537 var lines =<< trim END
4538 vim9script
4539 def A(F: func, ...args: list<any>): func
4540 return funcref(F, args)
4541 enddef
4542
4543 def B(F: func): func
4544 return funcref(A, [F])
4545 enddef
4546
4547 def Test(n: number)
4548 enddef
4549
4550 const X = B(Test)
4551 X(1)
4552 END
4553 v9.CheckScriptSuccess(lines)
4554
4555 # slightly different case
4556 lines =<< trim END
4557 vim9script
4558
4559 def A(F: func, ...args: list<any>): any
4560 return call(F, args)
4561 enddef
4562
4563 def B(F: func): func
4564 return funcref(A, [F])
4565 enddef
4566
4567 def Test(n: number)
4568 enddef
4569
4570 const X = B(Test)
4571 X(1)
4572 END
4573 v9.CheckScriptSuccess(lines)
4574enddef
4575
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004576def Test_cexpr_errmsg_line_number()
John Marriott45377e22025-03-27 18:12:32 +01004577 CheckFeature quickfix
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004578 var lines =<< trim END
4579 vim9script
4580 def Func()
4581 var qfl = {}
4582 cexpr qfl
4583 enddef
4584 Func()
4585 END
4586 v9.CheckScriptFailure(lines, 'E777', 2)
4587enddef
4588
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004589def AddDefer(s: string)
4590 g:deferred->extend([s])
4591enddef
4592
4593def DeferTwo()
4594 g:deferred->extend(['in Two'])
4595 for n in range(3)
4596 defer g:AddDefer('two' .. n)
4597 endfor
4598 g:deferred->extend(['end Two'])
4599enddef
4600
4601def DeferOne()
4602 g:deferred->extend(['in One'])
4603 defer g:AddDefer('one')
4604 g:DeferTwo()
4605 g:deferred->extend(['end One'])
4606
4607 writefile(['text'], 'XdeferFile')
4608 defer delete('XdeferFile')
4609enddef
4610
4611def Test_defer()
4612 g:deferred = []
4613 g:DeferOne()
4614 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4615 unlet g:deferred
4616 assert_equal('', glob('XdeferFile'))
4617enddef
4618
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004619def Test_invalid_redir()
4620 var lines =<< trim END
4621 def Tone()
4622 if 1
4623 redi =>@�0
4624 redi END
4625 endif
4626 enddef
4627 defcompile
4628 END
4629 v9.CheckScriptFailure(lines, 'E354:')
4630 delfunc g:Tone
4631
4632 # this was reading past the end of the line
4633 lines =<< trim END
4634 def Ttwo()
4635 if 0
4636 redi =>@�0
4637 redi END
4638 endif
4639 enddef
4640 defcompile
4641 END
4642 v9.CheckScriptFailure(lines, 'E354:')
4643 delfunc g:Ttwo
4644enddef
4645
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004646func Test_keytyped_in_nested_function()
Drew Vogelea67ba72025-05-07 22:05:17 +02004647 CheckScreendump
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004648 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