blob: 7b5d3e9d7ea8621df37467db08041c34e4efb1fe [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 Moolenaar52bf81c2020-11-17 18:50:44 +01001459def Shadowed(): list<number>
1460 var FuncList: list<func: number> = [{ -> 42}]
1461 return FuncList->map({_, Shadowed -> Shadowed()})
1462enddef
1463
1464def Test_lambda_arg_shadows_func()
1465 assert_equal([42], Shadowed())
1466enddef
1467
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001468def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001469 var path: string = empty(dir)
1470 \ ? 'empty'
1471 \ : 'full'
1472 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001473enddef
1474
1475def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001476 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001477enddef
1478
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001479def Test_script_var_in_lambda()
1480 var lines =<< trim END
1481 vim9script
1482 var script = 'test'
1483 assert_equal(['test'], map(['one'], {-> script}))
1484 END
1485 CheckScriptSuccess(lines)
1486enddef
1487
Bram Moolenaar5e654232020-09-16 15:22:00 +02001488def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001489 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001490 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001491 ->toupper()})
1492 ->reverse()
1493 return x
1494enddef
1495
1496def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001497 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001498enddef
1499
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001500func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001501 CheckScreendump
1502
1503 let lines =<< trim END
1504 vim9script
1505 def EchoNothing()
1506 silent echo ''
1507 enddef
1508 defcompile
1509 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001510 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001511
1512 " Check that the balloon shows up after a mouse move
1513 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001514 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001515 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1516
1517 " clean up
1518 call StopVimInTerminal(buf)
1519 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001520endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001521
Bram Moolenaar171fb922020-10-28 16:54:47 +01001522def SilentlyError()
1523 execute('silent! invalid')
1524 g:did_it = 'yes'
1525enddef
1526
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001527func UserError()
1528 silent! invalid
1529endfunc
1530
1531def SilentlyUserError()
1532 UserError()
1533 g:did_it = 'yes'
1534enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001535
1536" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001537func Test_ignore_silent_error()
1538 let g:did_it = 'no'
1539 call SilentlyError()
1540 call assert_equal('yes', g:did_it)
1541
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001542 let g:did_it = 'no'
1543 call SilentlyUserError()
1544 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001545
1546 unlet g:did_it
1547endfunc
1548
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001549def Test_ignore_silent_error_in_filter()
1550 var lines =<< trim END
1551 vim9script
1552 def Filter(winid: number, key: string): bool
1553 if key == 'o'
1554 silent! eval [][0]
1555 return true
1556 endif
1557 return popup_filter_menu(winid, key)
1558 enddef
1559
1560 popup_create('popup', #{filter: Filter})
1561 feedkeys("o\r", 'xnt')
1562 END
1563 CheckScriptSuccess(lines)
1564enddef
1565
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001566def Fibonacci(n: number): number
1567 if n < 2
1568 return n
1569 else
1570 return Fibonacci(n - 1) + Fibonacci(n - 2)
1571 endif
1572enddef
1573
Bram Moolenaar985116a2020-07-12 17:31:09 +02001574def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001575 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001576enddef
1577
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001578def TreeWalk(dir: string): list<any>
1579 return readdir(dir)->map({_, val ->
1580 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001581 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001582 : val
1583 })
1584enddef
1585
1586def Test_closure_in_map()
1587 mkdir('XclosureDir/tdir', 'p')
1588 writefile(['111'], 'XclosureDir/file1')
1589 writefile(['222'], 'XclosureDir/file2')
1590 writefile(['333'], 'XclosureDir/tdir/file3')
1591
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001592 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001593
1594 delete('XclosureDir', 'rf')
1595enddef
1596
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001597def Test_invalid_function_name()
1598 var lines =<< trim END
1599 vim9script
1600 def s: list<string>
1601 END
1602 CheckScriptFailure(lines, 'E129:')
1603
1604 lines =<< trim END
1605 vim9script
1606 def g: list<string>
1607 END
1608 CheckScriptFailure(lines, 'E129:')
1609
1610 lines =<< trim END
1611 vim9script
1612 def <SID>: list<string>
1613 END
1614 CheckScriptFailure(lines, 'E884:')
1615
1616 lines =<< trim END
1617 vim9script
1618 def F list<string>
1619 END
1620 CheckScriptFailure(lines, 'E488:')
1621enddef
1622
Bram Moolenaara90afb92020-07-15 22:38:56 +02001623def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001624 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02001625 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001626 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001627
1628 Xsetlist = function('setloclist', [0, [], ' '])
1629 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001630 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001631
1632 Xsetlist = function('setqflist')
1633 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001634 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001635
1636 Xsetlist = function('setqflist', [[], ' '])
1637 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001638 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001639
1640 var Len: func: number = function('len', ['word'])
1641 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001642enddef
1643
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001644def Test_cmd_modifier()
1645 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001646 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001647enddef
1648
1649def Test_restore_modifiers()
1650 # check that when compiling a :def function command modifiers are not messed
1651 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001652 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001653 vim9script
1654 set eventignore=
1655 autocmd QuickFixCmdPost * copen
1656 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001657 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001658 enddef
1659 func Func()
1660 noautocmd call s:AutocmdsDisabled()
1661 let g:ei_after = &eventignore
1662 endfunc
1663 Func()
1664 END
1665 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001666 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001667enddef
1668
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001669def StackTop()
1670 eval 1
1671 eval 2
1672 # call not on fourth line
1673 StackBot()
1674enddef
1675
1676def StackBot()
1677 # throw an error
1678 eval [][0]
1679enddef
1680
1681def Test_callstack_def()
1682 try
1683 StackTop()
1684 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001685 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001686 endtry
1687enddef
1688
Bram Moolenaare8211a32020-10-09 22:04:29 +02001689" Re-using spot for variable used in block
1690def Test_block_scoped_var()
1691 var lines =<< trim END
1692 vim9script
1693 def Func()
1694 var x = ['a', 'b', 'c']
1695 if 1
1696 var y = 'x'
1697 map(x, {-> y})
1698 endif
1699 var z = x
1700 assert_equal(['x', 'x', 'x'], z)
1701 enddef
1702 Func()
1703 END
1704 CheckScriptSuccess(lines)
1705enddef
1706
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001707def Test_reset_did_emsg()
1708 var lines =<< trim END
1709 @s = 'blah'
1710 au BufWinLeave * #
1711 def Func()
1712 var winid = popup_create('popup', {})
1713 exe '*s'
1714 popup_close(winid)
1715 enddef
1716 Func()
1717 END
1718 CheckScriptFailure(lines, 'E492:', 8)
1719enddef
1720
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001721
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001722" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker