blob: bbfce23c4ad7419f5af589c472734872b4b809a5 [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" Test various aspects of the Vim9 script language.
2
3source check.vim
Bram Moolenaarad304702020-09-06 18:22:53 +02004source term_util.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02005source view_util.vim
Bram Moolenaar04b12692020-05-04 23:24:44 +02006source vim9.vim
Bram Moolenaar47e7d702020-07-05 18:18:42 +02007source screendump.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02008
9func Test_def_basic()
10 def SomeFunc(): string
11 return 'yes'
12 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020013 call SomeFunc()->assert_equal('yes')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020014endfunc
15
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020016func Test_compiling_error()
17 " use a terminal to see the whole error message
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020018 CheckRunVimInTerminal
19
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020020 call TestCompilingError()
21endfunc
22
23def TestCompilingError()
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020024 var lines =<< trim END
25 vim9script
26 def Fails()
27 echo nothing
28 enddef
29 defcompile
30 END
31 call writefile(lines, 'XTest_compile_error')
32 var buf = RunVimInTerminal('-S XTest_compile_error',
33 #{rows: 10, wait_for_ruler: 0})
34 var text = ''
35 for loop in range(100)
36 text = ''
37 for i in range(1, 9)
38 text ..= term_getline(buf, i)
39 endfor
40 if text =~ 'Error detected'
41 break
42 endif
43 sleep 20m
44 endfor
45 assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text)
46
47 # clean up
48 call StopVimInTerminal(buf)
49 call delete('XTest_compile_error')
50enddef
51
Bram Moolenaar0ba48e82020-11-17 18:23:19 +010052def CallRecursive(n: number): number
53 return CallRecursive(n + 1)
54enddef
55
56def CallMapRecursive(l: list<number>): number
57 return map(l, {_, v -> CallMapRecursive([v])})[0]
58enddef
59
60def Test_funcdepth_error()
61 set maxfuncdepth=10
62
63 var caught = false
64 try
65 CallRecursive(1)
66 catch /E132:/
67 caught = true
68 endtry
69 assert_true(caught)
70
71 caught = false
72 try
73 CallMapRecursive([1])
74 catch /E132:/
75 caught = true
76 endtry
77 assert_true(caught)
78
79 set maxfuncdepth&
80enddef
81
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020082def ReturnString(): string
83 return 'string'
84enddef
85
86def ReturnNumber(): number
87 return 123
88enddef
89
90let g:notNumber = 'string'
91
92def ReturnGlobal(): number
93 return g:notNumber
94enddef
95
96def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020097 ReturnString()->assert_equal('string')
98 ReturnNumber()->assert_equal(123)
Bram Moolenaar5e654232020-09-16 15:22:00 +020099 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200100enddef
101
Bram Moolenaarefd88552020-06-18 20:50:10 +0200102def Test_missing_return()
103 CheckDefFailure(['def Missing(): number',
104 ' if g:cond',
105 ' echo "no return"',
106 ' else',
107 ' return 0',
108 ' endif'
109 'enddef'], 'E1027:')
110 CheckDefFailure(['def Missing(): number',
111 ' if g:cond',
112 ' return 1',
113 ' else',
114 ' echo "no return"',
115 ' endif'
116 'enddef'], 'E1027:')
117 CheckDefFailure(['def Missing(): number',
118 ' if g:cond',
119 ' return 1',
120 ' else',
121 ' return 2',
122 ' endif'
123 ' return 3'
124 'enddef'], 'E1095:')
125enddef
126
Bram Moolenaar403dc312020-10-17 19:29:51 +0200127def Test_return_bool()
128 var lines =<< trim END
129 vim9script
130 def MenuFilter(id: number, key: string): bool
131 return popup_filter_menu(id, key)
132 enddef
133 def YesnoFilter(id: number, key: string): bool
134 return popup_filter_yesno(id, key)
135 enddef
136 defcompile
137 END
138 CheckScriptSuccess(lines)
139enddef
140
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200141let s:nothing = 0
142def ReturnNothing()
143 s:nothing = 1
144 if true
145 return
146 endif
147 s:nothing = 2
148enddef
149
150def Test_return_nothing()
151 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200152 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200153enddef
154
155func Increment()
156 let g:counter += 1
157endfunc
158
159def Test_call_ufunc_count()
160 g:counter = 1
161 Increment()
162 Increment()
163 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200164 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200165 g:counter->assert_equal(4)
166 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200167 unlet g:counter
168enddef
169
170def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200171 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200172 for s in rest
173 res ..= ',' .. s
174 endfor
175 return res
176enddef
177
178def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200179 MyVarargs('one')->assert_equal('one')
180 MyVarargs('one', 'two')->assert_equal('one,two')
181 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200182enddef
183
184def MyDefaultArgs(name = 'string'): string
185 return name
186enddef
187
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200188def MyDefaultSecond(name: string, second: bool = true): string
189 return second ? name : 'none'
190enddef
191
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200192def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200193 MyDefaultArgs()->assert_equal('string')
194 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200195 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200196
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200197 MyDefaultSecond('test')->assert_equal('test')
198 MyDefaultSecond('test', true)->assert_equal('test')
199 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200200
Bram Moolenaar822ba242020-05-24 23:00:18 +0200201 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar77072282020-09-16 17:55:40 +0200202 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200203enddef
204
205def Test_nested_function()
206 def Nested(arg: string): string
207 return 'nested ' .. arg
208 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200209 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200210
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200211 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
212 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
213
Bram Moolenaar04b12692020-05-04 23:24:44 +0200214 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200215 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
216 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200217
218 CheckDefFailure([
219 'def Outer()',
220 ' def Inner()',
221 ' # comment',
222 ' enddef',
223 ' def Inner()',
224 ' enddef',
225 'enddef'], 'E1073:')
226 CheckDefFailure([
227 'def Outer()',
228 ' def Inner()',
229 ' # comment',
230 ' enddef',
231 ' def! Inner()',
232 ' enddef',
233 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200234enddef
235
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200236func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200237 call MyDefaultArgs()->assert_equal('string')
238 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200239 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200240endfunc
241
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200242def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200243 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200244 vim9script
245 def Outer()
246 def g:Inner(): string
247 return 'inner'
248 enddef
249 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200250 defcompile
251 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200252 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200253 delfunc g:Inner
254 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200255 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200256 delfunc g:Inner
257 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200258 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200259 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200260 END
261 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200262
263 lines =<< trim END
264 vim9script
265 def Outer()
266 def g:Inner(): string
267 return 'inner'
268 enddef
269 enddef
270 defcompile
271 Outer()
272 Outer()
273 END
274 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200275
276 lines =<< trim END
277 vim9script
278 def Func()
279 echo 'script'
280 enddef
281 def Outer()
282 def Func()
283 echo 'inner'
284 enddef
285 enddef
286 defcompile
287 END
288 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200289enddef
290
Bram Moolenaar333894b2020-08-01 18:53:07 +0200291def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200292 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200293 vim9script
294 def g:Func(): string
295 return 'global'
296 enddef
297 def Func(): string
298 return 'local'
299 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200300 g:Func()->assert_equal('global')
301 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200302 END
303 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200304
305 lines =<< trim END
306 vim9script
307 def g:Funcy()
308 echo 'funcy'
309 enddef
310 s:Funcy()
311 END
312 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200313enddef
314
Bram Moolenaar0f769812020-09-12 18:32:34 +0200315def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200316 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200317 vim9script
318 def g:Gfunc(): string
319 return 'global'
320 enddef
321 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200322 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200323 return Gfunc('testing')
324 enddef
325 g:Gfunc()->assert_equal('global')
326 AnotherFunc()->assert_equal(7)
327 delfunc g:Gfunc
328 END
329 CheckScriptSuccess(lines)
330
331 lines =<< trim END
332 vim9script
333 def g:Func(): string
334 return 'global'
335 enddef
336 def AnotherFunc()
337 g:Func = function('len')
338 enddef
339 AnotherFunc()
340 END
341 CheckScriptFailure(lines, 'E705:')
342 delfunc g:Func
343enddef
344
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200345func TakesOneArg(arg)
346 echo a:arg
347endfunc
348
349def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200350 CheckDefFailure(['TakesOneArg()'], 'E119:')
351 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
352 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
353 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200354
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200355 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200356 vim9script
357 def Func(s: string)
358 echo s
359 enddef
360 Func([])
361 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200362 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200363
364 lines =<< trim END
365 vim9script
366 def FuncOne(nr: number)
367 echo nr
368 enddef
369 def FuncTwo()
370 FuncOne()
371 enddef
372 defcompile
373 END
374 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200375 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200376 try
377 source Xscript
378 catch
379 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
380 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
381 didCatch = true
382 endtry
383 assert_true(didCatch)
384
385 lines =<< trim END
386 vim9script
387 def FuncOne(nr: number)
388 echo nr
389 enddef
390 def FuncTwo()
391 FuncOne(1, 2)
392 enddef
393 defcompile
394 END
395 writefile(lines, 'Xscript')
396 didCatch = false
397 try
398 source Xscript
399 catch
400 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
401 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
402 didCatch = true
403 endtry
404 assert_true(didCatch)
405
406 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200407enddef
408
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100409def Test_call_lambda_args()
410 CheckDefFailure(['echo {i -> 0}()'],
411 'E119: Not enough arguments for function: {i -> 0}()')
412
413 var lines =<< trim END
414 var Ref = {x: number, y: number -> x + y}
415 echo Ref(1, 'x')
416 END
417 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
418enddef
419
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200420" Default arg and varargs
421def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200422 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200423 for s in rest
424 res ..= ',' .. s
425 endfor
426 return res
427enddef
428
429def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200430 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200431 MyDefVarargs('one')->assert_equal('one,foo')
432 MyDefVarargs('one', 'two')->assert_equal('one,two')
433 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200434 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200435 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200436 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200437 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200438
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200439 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200440 vim9script
441 def Func(...l: list<string>)
442 echo l
443 enddef
444 Func('a', 'b', 'c')
445 END
446 CheckScriptSuccess(lines)
447
448 lines =<< trim END
449 vim9script
450 def Func(...l: list<string>)
451 echo l
452 enddef
453 Func()
454 END
455 CheckScriptSuccess(lines)
456
457 lines =<< trim END
458 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200459 def Func(...l: any)
460 echo l
461 enddef
462 Func(0)
463 END
464 CheckScriptSuccess(lines)
465
466 lines =<< trim END
467 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200468 def Func(..._l: list<string>)
469 echo _l
470 enddef
471 Func('a', 'b', 'c')
472 END
473 CheckScriptSuccess(lines)
474
475 lines =<< trim END
476 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200477 def Func(...l: list<string>)
478 echo l
479 enddef
480 Func(1, 2, 3)
481 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200482 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200483
484 lines =<< trim END
485 vim9script
486 def Func(...l: list<string>)
487 echo l
488 enddef
489 Func('a', 9)
490 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200491 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200492
493 lines =<< trim END
494 vim9script
495 def Func(...l: list<string>)
496 echo l
497 enddef
498 Func(1, 'a')
499 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200500 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200501enddef
502
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200503let s:value = ''
504
505def FuncOneDefArg(opt = 'text')
506 s:value = opt
507enddef
508
509def FuncTwoDefArg(nr = 123, opt = 'text'): string
510 return nr .. opt
511enddef
512
513def FuncVarargs(...arg: list<string>): string
514 return join(arg, ',')
515enddef
516
517def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200518 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200519 RefDefArg = FuncOneDefArg
520 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200521 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200522 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200523 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200524
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200525 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200526 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200527 RefDef2Arg()->assert_equal('123text')
528 RefDef2Arg(99)->assert_equal('99text')
529 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200530
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200531 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
532 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200533
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200534 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200535 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200536 RefVarargs()->assert_equal('')
537 RefVarargs('one')->assert_equal('one')
538 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200539
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200540 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
541 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200542enddef
543
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200544" Only varargs
545def MyVarargsOnly(...args: list<string>): string
546 return join(args, ',')
547enddef
548
549def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200550 MyVarargsOnly()->assert_equal('')
551 MyVarargsOnly('one')->assert_equal('one')
552 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200553 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
554 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200555enddef
556
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200557def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200558 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200559 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200560 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200561enddef
562
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200563def DictArg(arg: dict<string>)
564 arg['key'] = 'value'
565enddef
566
567def ListArg(arg: list<string>)
568 arg[0] = 'value'
569enddef
570
571def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200572 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200573 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200574 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200575 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200576 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200577 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200578 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200579
Bram Moolenaard2c61702020-09-06 15:58:36 +0200580 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200581enddef
582
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200583" These argument names are reserved in legacy functions.
584def WithReservedNames(firstline: string, lastline: string): string
585 return firstline .. lastline
586enddef
587
588def Test_argument_names()
589 assert_equal('OK', WithReservedNames('O', 'K'))
590enddef
591
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200592def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200593 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200594 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200595enddef
596
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200597func DefinedLater(arg)
598 return a:arg
599endfunc
600
601def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200602 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200603 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
604 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200605
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200606 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200607 vim9script
608 def RetNumber(): number
609 return 123
610 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200611 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200612 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200613 END
614 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200615
616 lines =<< trim END
617 vim9script
618 def RetNumber(): number
619 return 123
620 enddef
621 def Bar(F: func: number): number
622 return F()
623 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200624 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200625 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200626 END
627 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200628
629 lines =<< trim END
630 vim9script
631 def UseNumber(nr: number)
632 echo nr
633 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200634 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200635 Funcref(123)
636 END
637 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200638
639 lines =<< trim END
640 vim9script
641 def UseNumber(nr: number)
642 echo nr
643 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200644 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200645 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200646 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200647
648 lines =<< trim END
649 vim9script
650 def EchoNr(nr = 34)
651 g:echo = nr
652 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200653 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200654 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200655 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200656 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200657 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200658 END
659 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200660
661 lines =<< trim END
662 vim9script
663 def EchoList(...l: list<number>)
664 g:echo = l
665 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200666 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200667 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200668 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200669 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200670 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200671 END
672 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200673
674 lines =<< trim END
675 vim9script
676 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
677 g:optarg = opt
678 g:listarg = l
679 return nr
680 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200681 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200682 Funcref(10)->assert_equal(10)
683 g:optarg->assert_equal(12)
684 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200685
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200686 Funcref(11, 22)->assert_equal(11)
687 g:optarg->assert_equal(22)
688 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200689
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200690 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
691 g:optarg->assert_equal(18)
692 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200693 END
694 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200695enddef
696
697let SomeFunc = function('len')
698let NotAFunc = 'text'
699
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200700def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200701 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200702 var Ref1: func(bool): string
703 var Ref2: func(bool): number
704 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200705 Ref3 = g:cond ? Ref1 : Ref2
706
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200707 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200708 var Refa1: func(bool): number
709 var Refa2: func(bool, number): number
710 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200711 Refa3 = g:cond ? Refa1 : Refa2
712
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200713 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200714 var Refb1: func(bool, string): number
715 var Refb2: func(string, number): number
716 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200717 Refb3 = g:cond ? Refb1 : Refb2
718enddef
719
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200720def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200721 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200722enddef
723
724def DefinedEvenLater(arg: string): string
725 return arg
726enddef
727
728def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200729 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200730 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200731enddef
732
733def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200734 CheckScriptFailure([
735 'def Func(): number',
736 'return "a"',
737 'enddef',
738 'defcompile'], 'expected number but got string')
739 CheckScriptFailure([
740 'def Func(): string',
741 'return 1',
742 'enddef',
743 'defcompile'], 'expected string but got number')
744 CheckScriptFailure([
745 'def Func(): void',
746 'return "a"',
747 'enddef',
748 'defcompile'],
749 'E1096: Returning a value in a function without a return type')
750 CheckScriptFailure([
751 'def Func()',
752 'return "a"',
753 'enddef',
754 'defcompile'],
755 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200756
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200757 CheckScriptFailure([
758 'def Func(): number',
759 'return',
760 'enddef',
761 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200762
763 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
764 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200765 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200766
767 CheckScriptFailure([
768 'vim9script',
769 'def FuncB()',
770 ' return 123',
771 'enddef',
772 'def FuncA()',
773 ' FuncB()',
774 'enddef',
775 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200776enddef
777
778def Test_arg_type_wrong()
779 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200780 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200781 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200782 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200783enddef
784
785def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200786 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200787 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200788 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200789 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200790 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200791 enddef
792 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200793 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200794
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200795 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200796 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200797 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200798
Bram Moolenaar67979662020-06-20 22:50:47 +0200799 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200800 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200801 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200802
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200803 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200804 def ListFunc(arg: list<number>)
805 listvar = arg
806 enddef
807 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200808 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200809
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200810 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200811 def DictFunc(arg: dict<number>)
812 dictvar = arg
813 enddef
814 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200815 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200816 def CompiledDict()
817 {'a': 3, 'b': 4}->DictFunc()
818 enddef
819 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200820 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200821
822 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200823 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200824
825 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200826 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200827 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200828 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200829
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200830 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200831 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200832 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200833 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200834 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200835 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200836
837 def UseString()
838 'xyork'->MyFunc()
839 enddef
840 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200841 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200842
Bram Moolenaar10409562020-07-29 20:00:38 +0200843 def UseString2()
844 "knife"->MyFunc()
845 enddef
846 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200847 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200848
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200849 # prepending a colon makes it a mark
850 new
851 setline(1, ['aaa', 'bbb', 'ccc'])
852 normal! 3Gmt1G
853 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200854 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200855 bwipe!
856
Bram Moolenaare6b53242020-07-01 17:28:33 +0200857 MyFunc(
858 'continued'
859 )
860 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200861 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200862 )
863
864 call MyFunc(
865 'more'
866 ..
867 'lines'
868 )
869 assert_equal(
870 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200871 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200872 END
873 writefile(lines, 'Xcall.vim')
874 source Xcall.vim
875 delete('Xcall.vim')
876enddef
877
878def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200879 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200880 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200881 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200882 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200883 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200884 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200885 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200886 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200887 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200888enddef
889
Bram Moolenaar65b95452020-07-19 14:03:09 +0200890def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200891 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200892 vim9script
893 def MyFunc(arg: string)
894 echo arg
895 enddef
896 MyFunc(1234)
897 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200898 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200899enddef
900
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200901def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200902 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200903 vim9script
904 const var = ''
905 def MyFunc(arg: string)
906 var = 'asdf'
907 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200908 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909 END
910 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200911 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200912 delete('Xcall_const.vim')
913enddef
914
915" Test that inside :function a Python function can be defined, :def is not
916" recognized.
917func Test_function_python()
918 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200919 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200920 execute py "<< EOF"
921def do_something():
922 return 1
923EOF
924endfunc
925
926def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200927 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200928 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200929 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200930 echo 'hello'
931 enddef
932
933 def CallGoneSoon()
934 GoneSoon()
935 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200936 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200937
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200938 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200939 CallGoneSoon()
940 END
941 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200942 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
943 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200944
945 delete('XToDelFunc')
946enddef
947
948def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200949 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200950 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200951 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200952 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200953 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200954 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200955 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200956 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200957 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200958
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200959 g:Func0()->assert_equal(0)
960 g:Func1()->assert_equal('Func1')
961 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200962
963 delfunc! Func0
964 delfunc! Func1
965 delfunc! Func2
966enddef
967
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200968def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200969 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200970 vim9script
971 func Func(arg)
972 echo a:arg
973 endfunc
974 Func('text')
975 END
976 writefile(lines, 'XVim9Func')
977 so XVim9Func
978
979 delete('XVim9Func')
980enddef
981
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200982let s:funcResult = 0
983
984def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200985 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200986enddef
987
988def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200989 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200990 return 1234
991enddef
992
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200993def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200994 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200995 return 'text'
996enddef
997
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200998def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200999 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001000enddef
1001
1002def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001003 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001004 return arg
1005enddef
1006
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001007def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001008 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001009enddef
1010
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001011def FuncOneArgRetString(arg: string): string
1012 return arg
1013enddef
1014
Bram Moolenaar89228602020-04-05 22:14:54 +02001015def FuncOneArgRetAny(arg: any): any
1016 return arg
1017enddef
1018
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001019def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001020 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001021 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001022 Ref1 = FuncNoArgNoRet
1023 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001024 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001025
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001026 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001027 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001028 Ref2 = FuncNoArgNoRet
1029 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001030 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001031
Bram Moolenaar53900992020-08-22 19:02:02 +02001032 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001033 Ref2 = FuncOneArgNoRet
1034 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001035 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001036
Bram Moolenaar53900992020-08-22 19:02:02 +02001037 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001038 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001039 Ref2()->assert_equal(1234)
1040 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001041
Bram Moolenaar53900992020-08-22 19:02:02 +02001042 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001043 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001044 Ref2(13)->assert_equal(13)
1045 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001046enddef
1047
Bram Moolenaar9978d472020-07-05 16:01:56 +02001048def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001049 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001050 for n in repeat([1], 3)
1051 res += n
1052 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001053 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001054
1055 res = 0
1056 for n in add([1, 2], 3)
1057 res += n
1058 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001059 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001060enddef
1061
Bram Moolenaar846178a2020-07-05 17:04:13 +02001062def Test_argv_return_type()
1063 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001064 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001065 for name in argv()
1066 res ..= name
1067 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001068 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001069enddef
1070
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001071def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001072 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001073 RefVoid = FuncNoArgNoRet
1074 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001075 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1076 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001077
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001078 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001079 RefAny = FuncNoArgRetNumber
1080 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001081 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1082 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001083
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001084 var RefAnyNoArgs: func: any = RefAny
1085
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001086 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001087 RefNr = FuncNoArgRetNumber
1088 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001089 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1090 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001091
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001092 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001093 RefStr = FuncNoArgRetString
1094 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001095 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1096 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001097enddef
1098
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001099def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001100 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001101
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001102 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1103 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1104 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1105 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1106 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1107 CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001108
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001109 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1110 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1111 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:')
1112 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001113enddef
1114
Bram Moolenaar89228602020-04-05 22:14:54 +02001115def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001116 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001117 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001118 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001119
1120 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001121 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001122
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001123 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001124 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001125 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001126
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001127 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001128enddef
1129
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001130def Test_func_common_type()
1131 def FuncOne(n: number): number
1132 return n
1133 enddef
1134 def FuncTwo(s: string): number
1135 return len(s)
1136 enddef
1137 def FuncThree(n: number, s: string): number
1138 return n + len(s)
1139 enddef
1140 var list = [FuncOne, FuncTwo, FuncThree]
1141 assert_equal(8, list[0](8))
1142 assert_equal(4, list[1]('word'))
1143 assert_equal(7, list[2](3, 'word'))
1144enddef
1145
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001146def MultiLine(
1147 arg1: string,
1148 arg2 = 1234,
1149 ...rest: list<string>
1150 ): string
1151 return arg1 .. arg2 .. join(rest, '-')
1152enddef
1153
Bram Moolenaar2c330432020-04-13 14:41:35 +02001154def MultiLineComment(
1155 arg1: string, # comment
1156 arg2 = 1234, # comment
1157 ...rest: list<string> # comment
1158 ): string # comment
1159 return arg1 .. arg2 .. join(rest, '-')
1160enddef
1161
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001162def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001163 MultiLine('text')->assert_equal('text1234')
1164 MultiLine('text', 777)->assert_equal('text777')
1165 MultiLine('text', 777, 'one')->assert_equal('text777one')
1166 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001167enddef
1168
Bram Moolenaar23e03252020-04-12 22:22:31 +02001169func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001170 call MultiLine('text')->assert_equal('text1234')
1171 call MultiLine('text', 777)->assert_equal('text777')
1172 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1173 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001174endfunc
1175
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001176
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001177" When using CheckScriptFailure() for the below test, E1010 is generated instead
1178" of E1056.
1179func Test_E1056_1059()
1180 let caught_1056 = 0
1181 try
1182 def F():
1183 return 1
1184 enddef
1185 catch /E1056:/
1186 let caught_1056 = 1
1187 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001188 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001189
1190 let caught_1059 = 0
1191 try
1192 def F5(items : list)
1193 echo 'a'
1194 enddef
1195 catch /E1059:/
1196 let caught_1059 = 1
1197 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001198 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001199endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001200
Bram Moolenaar015f4262020-05-05 21:25:22 +02001201func DelMe()
1202 echo 'DelMe'
1203endfunc
1204
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001205def Test_error_reporting()
1206 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001207 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001208 " comment
1209 def Func()
1210 # comment
1211 # comment
1212 invalid
1213 enddef
1214 defcompile
1215 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001216 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001217 try
1218 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001219 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001220 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001221 v:exception->assert_match('Invalid command: invalid')
1222 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001223 endtry
1224
1225 # comment lines after the start of the function
1226 lines =<< trim END
1227 " comment
1228 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001229 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001230 # comment
1231 # comment
1232 invalid
1233 enddef
1234 defcompile
1235 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001236 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001237 try
1238 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001239 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001240 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001241 v:exception->assert_match('Invalid command: invalid')
1242 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001243 endtry
1244
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001245 lines =<< trim END
1246 vim9script
1247 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001248 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001249 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001250 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001251 enddef
1252 defcompile
1253 Func()
1254 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001255 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001256 try
1257 source Xdef
1258 assert_report('should have failed')
1259 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001260 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001261 endtry
1262
Bram Moolenaar08052222020-09-14 17:04:31 +02001263 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001264enddef
1265
Bram Moolenaar015f4262020-05-05 21:25:22 +02001266def Test_deleted_function()
1267 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001268 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001269 'delfunc g:DelMe',
1270 'echo RefMe()'], 'E117:')
1271enddef
1272
1273def Test_unknown_function()
1274 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001275 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001276 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001277enddef
1278
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001279def RefFunc(Ref: func(string): string): string
1280 return Ref('more')
1281enddef
1282
1283def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001284 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001285 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001286enddef
1287
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001288def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001289 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001290 g:Ref = {s -> local .. s}
1291enddef
1292
1293def Test_closure_ref_after_return()
1294 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001295 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001296 unlet g:Ref
1297enddef
1298
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001299def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001300 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001301 g:Extend = {s -> local->add(s)}
1302 g:Read = {-> local}
1303enddef
1304
1305def Test_closure_two_refs()
1306 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001307 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001308 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001309 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001310 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001311 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001312
1313 unlet g:Extend
1314 unlet g:Read
1315enddef
1316
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001317def ReadRef(Ref: func(): list<string>): string
1318 return join(Ref(), ' ')
1319enddef
1320
Bram Moolenaar5e654232020-09-16 15:22:00 +02001321def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001322 Ref(add)
1323enddef
1324
1325def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001326 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001327 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001328 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001329 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001330 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001331 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001332
1333 unlet g:Extend
1334 unlet g:Read
1335enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001336
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001337def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001338 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001339 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1340enddef
1341
1342def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001343 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001344 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1345enddef
1346
1347def Test_closure_using_argument()
1348 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001349 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001350
1351 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001352 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001353
1354 unlet g:UseArg
1355 unlet g:UseVararg
1356enddef
1357
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001358def MakeGetAndAppendRefs()
1359 var local = 'a'
1360
1361 def Append(arg: string)
1362 local ..= arg
1363 enddef
1364 g:Append = Append
1365
1366 def Get(): string
1367 return local
1368 enddef
1369 g:Get = Get
1370enddef
1371
1372def Test_closure_append_get()
1373 MakeGetAndAppendRefs()
1374 g:Get()->assert_equal('a')
1375 g:Append('-b')
1376 g:Get()->assert_equal('a-b')
1377 g:Append('-c')
1378 g:Get()->assert_equal('a-b-c')
1379
1380 unlet g:Append
1381 unlet g:Get
1382enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001383
Bram Moolenaar04b12692020-05-04 23:24:44 +02001384def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001385 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001386 def Closure(arg: string): string
1387 return local .. arg
1388 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001389 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001390enddef
1391
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001392func GetResult(Ref)
1393 return a:Ref('some')
1394endfunc
1395
1396def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001397 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001398 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001399 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001400enddef
1401
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001402def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001403 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001404 vim9script
1405 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001406 var name = 0
1407 for i in range(2)
1408 timer_start(0, {-> name})
1409 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001410 enddef
1411 Func()
1412 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001413 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001414enddef
1415
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001416def Test_nested_closure_used()
1417 var lines =<< trim END
1418 vim9script
1419 def Func()
1420 var x = 'hello'
1421 var Closure = {-> x}
1422 g:Myclosure = {-> Closure()}
1423 enddef
1424 Func()
1425 assert_equal('hello', g:Myclosure())
1426 END
1427 CheckScriptSuccess(lines)
1428enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001429
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001430def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001431 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001432 vim9script
1433 def FuncA()
1434 FuncB(0)
1435 enddef
1436 def FuncB(n: number): list<string>
1437 return map([0], {_, v -> n})
1438 enddef
1439 FuncA()
1440 END
1441 CheckScriptFailure(lines, 'E1012:')
1442enddef
1443
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001444def Test_nested_lambda()
1445 var lines =<< trim END
1446 vim9script
1447 def Func()
1448 var x = 4
1449 var Lambda1 = {-> 7}
1450 var Lambda2 = {-> [Lambda1(), x]}
1451 var res = Lambda2()
1452 assert_equal([7, 4], res)
1453 enddef
1454 Func()
1455 END
1456 CheckScriptSuccess(lines)
1457enddef
1458
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001459def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001460 var path: string = empty(dir)
1461 \ ? 'empty'
1462 \ : 'full'
1463 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001464enddef
1465
1466def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001467 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001468enddef
1469
Bram Moolenaar5e654232020-09-16 15:22:00 +02001470def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001471 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001472 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001473 ->toupper()})
1474 ->reverse()
1475 return x
1476enddef
1477
1478def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001479 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001480enddef
1481
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001482func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001483 CheckScreendump
1484
1485 let lines =<< trim END
1486 vim9script
1487 def EchoNothing()
1488 silent echo ''
1489 enddef
1490 defcompile
1491 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001492 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001493
1494 " Check that the balloon shows up after a mouse move
1495 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001496 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001497 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1498
1499 " clean up
1500 call StopVimInTerminal(buf)
1501 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001502endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001503
Bram Moolenaar171fb922020-10-28 16:54:47 +01001504def SilentlyError()
1505 execute('silent! invalid')
1506 g:did_it = 'yes'
1507enddef
1508
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001509func UserError()
1510 silent! invalid
1511endfunc
1512
1513def SilentlyUserError()
1514 UserError()
1515 g:did_it = 'yes'
1516enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001517
1518" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001519func Test_ignore_silent_error()
1520 let g:did_it = 'no'
1521 call SilentlyError()
1522 call assert_equal('yes', g:did_it)
1523
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001524 let g:did_it = 'no'
1525 call SilentlyUserError()
1526 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001527
1528 unlet g:did_it
1529endfunc
1530
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001531def Test_ignore_silent_error_in_filter()
1532 var lines =<< trim END
1533 vim9script
1534 def Filter(winid: number, key: string): bool
1535 if key == 'o'
1536 silent! eval [][0]
1537 return true
1538 endif
1539 return popup_filter_menu(winid, key)
1540 enddef
1541
1542 popup_create('popup', #{filter: Filter})
1543 feedkeys("o\r", 'xnt')
1544 END
1545 CheckScriptSuccess(lines)
1546enddef
1547
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001548def Fibonacci(n: number): number
1549 if n < 2
1550 return n
1551 else
1552 return Fibonacci(n - 1) + Fibonacci(n - 2)
1553 endif
1554enddef
1555
Bram Moolenaar985116a2020-07-12 17:31:09 +02001556def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001557 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001558enddef
1559
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001560def TreeWalk(dir: string): list<any>
1561 return readdir(dir)->map({_, val ->
1562 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001563 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001564 : val
1565 })
1566enddef
1567
1568def Test_closure_in_map()
1569 mkdir('XclosureDir/tdir', 'p')
1570 writefile(['111'], 'XclosureDir/file1')
1571 writefile(['222'], 'XclosureDir/file2')
1572 writefile(['333'], 'XclosureDir/tdir/file3')
1573
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001574 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001575
1576 delete('XclosureDir', 'rf')
1577enddef
1578
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001579def Test_invalid_function_name()
1580 var lines =<< trim END
1581 vim9script
1582 def s: list<string>
1583 END
1584 CheckScriptFailure(lines, 'E129:')
1585
1586 lines =<< trim END
1587 vim9script
1588 def g: list<string>
1589 END
1590 CheckScriptFailure(lines, 'E129:')
1591
1592 lines =<< trim END
1593 vim9script
1594 def <SID>: list<string>
1595 END
1596 CheckScriptFailure(lines, 'E884:')
1597
1598 lines =<< trim END
1599 vim9script
1600 def F list<string>
1601 END
1602 CheckScriptFailure(lines, 'E488:')
1603enddef
1604
Bram Moolenaara90afb92020-07-15 22:38:56 +02001605def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001606 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02001607 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001608 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001609
1610 Xsetlist = function('setloclist', [0, [], ' '])
1611 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001612 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001613
1614 Xsetlist = function('setqflist')
1615 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001616 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001617
1618 Xsetlist = function('setqflist', [[], ' '])
1619 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001620 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001621
1622 var Len: func: number = function('len', ['word'])
1623 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001624enddef
1625
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001626def Test_cmd_modifier()
1627 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001628 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001629enddef
1630
1631def Test_restore_modifiers()
1632 # check that when compiling a :def function command modifiers are not messed
1633 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001634 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001635 vim9script
1636 set eventignore=
1637 autocmd QuickFixCmdPost * copen
1638 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001639 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001640 enddef
1641 func Func()
1642 noautocmd call s:AutocmdsDisabled()
1643 let g:ei_after = &eventignore
1644 endfunc
1645 Func()
1646 END
1647 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001648 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001649enddef
1650
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001651def StackTop()
1652 eval 1
1653 eval 2
1654 # call not on fourth line
1655 StackBot()
1656enddef
1657
1658def StackBot()
1659 # throw an error
1660 eval [][0]
1661enddef
1662
1663def Test_callstack_def()
1664 try
1665 StackTop()
1666 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001667 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001668 endtry
1669enddef
1670
Bram Moolenaare8211a32020-10-09 22:04:29 +02001671" Re-using spot for variable used in block
1672def Test_block_scoped_var()
1673 var lines =<< trim END
1674 vim9script
1675 def Func()
1676 var x = ['a', 'b', 'c']
1677 if 1
1678 var y = 'x'
1679 map(x, {-> y})
1680 endif
1681 var z = x
1682 assert_equal(['x', 'x', 'x'], z)
1683 enddef
1684 Func()
1685 END
1686 CheckScriptSuccess(lines)
1687enddef
1688
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001689
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001690" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker