blob: b69001850bdb4f52f2dc42c6328a7c9062987dc5 [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 Moolenaar5deeb3f2020-04-05 17:08:17 +020052def ReturnString(): string
53 return 'string'
54enddef
55
56def ReturnNumber(): number
57 return 123
58enddef
59
60let g:notNumber = 'string'
61
62def ReturnGlobal(): number
63 return g:notNumber
64enddef
65
66def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020067 ReturnString()->assert_equal('string')
68 ReturnNumber()->assert_equal(123)
Bram Moolenaar5e654232020-09-16 15:22:00 +020069 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020070enddef
71
Bram Moolenaarefd88552020-06-18 20:50:10 +020072def Test_missing_return()
73 CheckDefFailure(['def Missing(): number',
74 ' if g:cond',
75 ' echo "no return"',
76 ' else',
77 ' return 0',
78 ' endif'
79 'enddef'], 'E1027:')
80 CheckDefFailure(['def Missing(): number',
81 ' if g:cond',
82 ' return 1',
83 ' else',
84 ' echo "no return"',
85 ' endif'
86 'enddef'], 'E1027:')
87 CheckDefFailure(['def Missing(): number',
88 ' if g:cond',
89 ' return 1',
90 ' else',
91 ' return 2',
92 ' endif'
93 ' return 3'
94 'enddef'], 'E1095:')
95enddef
96
Bram Moolenaar403dc312020-10-17 19:29:51 +020097def Test_return_bool()
98 var lines =<< trim END
99 vim9script
100 def MenuFilter(id: number, key: string): bool
101 return popup_filter_menu(id, key)
102 enddef
103 def YesnoFilter(id: number, key: string): bool
104 return popup_filter_yesno(id, key)
105 enddef
106 defcompile
107 END
108 CheckScriptSuccess(lines)
109enddef
110
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200111let s:nothing = 0
112def ReturnNothing()
113 s:nothing = 1
114 if true
115 return
116 endif
117 s:nothing = 2
118enddef
119
120def Test_return_nothing()
121 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200122 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200123enddef
124
125func Increment()
126 let g:counter += 1
127endfunc
128
129def Test_call_ufunc_count()
130 g:counter = 1
131 Increment()
132 Increment()
133 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200134 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200135 g:counter->assert_equal(4)
136 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200137 unlet g:counter
138enddef
139
140def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200141 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200142 for s in rest
143 res ..= ',' .. s
144 endfor
145 return res
146enddef
147
148def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200149 MyVarargs('one')->assert_equal('one')
150 MyVarargs('one', 'two')->assert_equal('one,two')
151 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200152enddef
153
154def MyDefaultArgs(name = 'string'): string
155 return name
156enddef
157
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200158def MyDefaultSecond(name: string, second: bool = true): string
159 return second ? name : 'none'
160enddef
161
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200162def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200163 MyDefaultArgs()->assert_equal('string')
164 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200165 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200166
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200167 MyDefaultSecond('test')->assert_equal('test')
168 MyDefaultSecond('test', true)->assert_equal('test')
169 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200170
Bram Moolenaar822ba242020-05-24 23:00:18 +0200171 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar77072282020-09-16 17:55:40 +0200172 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 +0200173enddef
174
175def Test_nested_function()
176 def Nested(arg: string): string
177 return 'nested ' .. arg
178 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200179 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200180
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200181 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
182 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
183
Bram Moolenaar04b12692020-05-04 23:24:44 +0200184 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200185 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
186 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200187
188 CheckDefFailure([
189 'def Outer()',
190 ' def Inner()',
191 ' # comment',
192 ' enddef',
193 ' def Inner()',
194 ' enddef',
195 'enddef'], 'E1073:')
196 CheckDefFailure([
197 'def Outer()',
198 ' def Inner()',
199 ' # comment',
200 ' enddef',
201 ' def! Inner()',
202 ' enddef',
203 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200204enddef
205
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200206func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200207 call MyDefaultArgs()->assert_equal('string')
208 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200209 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200210endfunc
211
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200212def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200213 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200214 vim9script
215 def Outer()
216 def g:Inner(): string
217 return 'inner'
218 enddef
219 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200220 defcompile
221 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200222 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200223 delfunc g:Inner
224 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200225 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200226 delfunc g:Inner
227 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200228 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200229 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200230 END
231 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200232
233 lines =<< trim END
234 vim9script
235 def Outer()
236 def g:Inner(): string
237 return 'inner'
238 enddef
239 enddef
240 defcompile
241 Outer()
242 Outer()
243 END
244 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200245
246 lines =<< trim END
247 vim9script
248 def Func()
249 echo 'script'
250 enddef
251 def Outer()
252 def Func()
253 echo 'inner'
254 enddef
255 enddef
256 defcompile
257 END
258 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200259enddef
260
Bram Moolenaar333894b2020-08-01 18:53:07 +0200261def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200262 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200263 vim9script
264 def g:Func(): string
265 return 'global'
266 enddef
267 def Func(): string
268 return 'local'
269 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200270 g:Func()->assert_equal('global')
271 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200272 END
273 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200274
275 lines =<< trim END
276 vim9script
277 def g:Funcy()
278 echo 'funcy'
279 enddef
280 s:Funcy()
281 END
282 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200283enddef
284
Bram Moolenaar0f769812020-09-12 18:32:34 +0200285def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200286 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200287 vim9script
288 def g:Gfunc(): string
289 return 'global'
290 enddef
291 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200292 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200293 return Gfunc('testing')
294 enddef
295 g:Gfunc()->assert_equal('global')
296 AnotherFunc()->assert_equal(7)
297 delfunc g:Gfunc
298 END
299 CheckScriptSuccess(lines)
300
301 lines =<< trim END
302 vim9script
303 def g:Func(): string
304 return 'global'
305 enddef
306 def AnotherFunc()
307 g:Func = function('len')
308 enddef
309 AnotherFunc()
310 END
311 CheckScriptFailure(lines, 'E705:')
312 delfunc g:Func
313enddef
314
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200315func TakesOneArg(arg)
316 echo a:arg
317endfunc
318
319def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200320 CheckDefFailure(['TakesOneArg()'], 'E119:')
321 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
322 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
323 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200324
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200325 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200326 vim9script
327 def Func(s: string)
328 echo s
329 enddef
330 Func([])
331 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200332 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200333
334 lines =<< trim END
335 vim9script
336 def FuncOne(nr: number)
337 echo nr
338 enddef
339 def FuncTwo()
340 FuncOne()
341 enddef
342 defcompile
343 END
344 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200345 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200346 try
347 source Xscript
348 catch
349 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
350 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
351 didCatch = true
352 endtry
353 assert_true(didCatch)
354
355 lines =<< trim END
356 vim9script
357 def FuncOne(nr: number)
358 echo nr
359 enddef
360 def FuncTwo()
361 FuncOne(1, 2)
362 enddef
363 defcompile
364 END
365 writefile(lines, 'Xscript')
366 didCatch = false
367 try
368 source Xscript
369 catch
370 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
371 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
372 didCatch = true
373 endtry
374 assert_true(didCatch)
375
376 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200377enddef
378
379" Default arg and varargs
380def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200381 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200382 for s in rest
383 res ..= ',' .. s
384 endfor
385 return res
386enddef
387
388def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200389 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200390 MyDefVarargs('one')->assert_equal('one,foo')
391 MyDefVarargs('one', 'two')->assert_equal('one,two')
392 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200393 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200394 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200395 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200396 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200397
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200398 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200399 vim9script
400 def Func(...l: list<string>)
401 echo l
402 enddef
403 Func('a', 'b', 'c')
404 END
405 CheckScriptSuccess(lines)
406
407 lines =<< trim END
408 vim9script
409 def Func(...l: list<string>)
410 echo l
411 enddef
412 Func()
413 END
414 CheckScriptSuccess(lines)
415
416 lines =<< trim END
417 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200418 def Func(...l: any)
419 echo l
420 enddef
421 Func(0)
422 END
423 CheckScriptSuccess(lines)
424
425 lines =<< trim END
426 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200427 def Func(..._l: list<string>)
428 echo _l
429 enddef
430 Func('a', 'b', 'c')
431 END
432 CheckScriptSuccess(lines)
433
434 lines =<< trim END
435 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200436 def Func(...l: list<string>)
437 echo l
438 enddef
439 Func(1, 2, 3)
440 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200441 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200442
443 lines =<< trim END
444 vim9script
445 def Func(...l: list<string>)
446 echo l
447 enddef
448 Func('a', 9)
449 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200450 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200451
452 lines =<< trim END
453 vim9script
454 def Func(...l: list<string>)
455 echo l
456 enddef
457 Func(1, 'a')
458 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200459 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200460enddef
461
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200462let s:value = ''
463
464def FuncOneDefArg(opt = 'text')
465 s:value = opt
466enddef
467
468def FuncTwoDefArg(nr = 123, opt = 'text'): string
469 return nr .. opt
470enddef
471
472def FuncVarargs(...arg: list<string>): string
473 return join(arg, ',')
474enddef
475
476def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200477 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200478 RefDefArg = FuncOneDefArg
479 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200480 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200481 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200482 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200483
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200484 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200485 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200486 RefDef2Arg()->assert_equal('123text')
487 RefDef2Arg(99)->assert_equal('99text')
488 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200489
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200490 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
491 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200492
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200493 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200494 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200495 RefVarargs()->assert_equal('')
496 RefVarargs('one')->assert_equal('one')
497 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200498
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200499 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
500 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200501enddef
502
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200503" Only varargs
504def MyVarargsOnly(...args: list<string>): string
505 return join(args, ',')
506enddef
507
508def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200509 MyVarargsOnly()->assert_equal('')
510 MyVarargsOnly('one')->assert_equal('one')
511 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200512 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
513 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200514enddef
515
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200516def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200517 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200518 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200519 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200520enddef
521
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200522def DictArg(arg: dict<string>)
523 arg['key'] = 'value'
524enddef
525
526def ListArg(arg: list<string>)
527 arg[0] = 'value'
528enddef
529
530def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200531 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200532 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200533 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200534 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200535 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200536 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200537 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200538
Bram Moolenaard2c61702020-09-06 15:58:36 +0200539 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200540enddef
541
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200542" These argument names are reserved in legacy functions.
543def WithReservedNames(firstline: string, lastline: string): string
544 return firstline .. lastline
545enddef
546
547def Test_argument_names()
548 assert_equal('OK', WithReservedNames('O', 'K'))
549enddef
550
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200551def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200552 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200553 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200554enddef
555
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200556func DefinedLater(arg)
557 return a:arg
558endfunc
559
560def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200561 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200562 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
563 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200564
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200565 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200566 vim9script
567 def RetNumber(): number
568 return 123
569 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200570 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200571 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200572 END
573 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200574
575 lines =<< trim END
576 vim9script
577 def RetNumber(): number
578 return 123
579 enddef
580 def Bar(F: func: number): number
581 return F()
582 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200583 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200584 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200585 END
586 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200587
588 lines =<< trim END
589 vim9script
590 def UseNumber(nr: number)
591 echo nr
592 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200593 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200594 Funcref(123)
595 END
596 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200597
598 lines =<< trim END
599 vim9script
600 def UseNumber(nr: number)
601 echo nr
602 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200603 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200604 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200605 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200606
607 lines =<< trim END
608 vim9script
609 def EchoNr(nr = 34)
610 g:echo = nr
611 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200612 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200613 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200614 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200615 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200616 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200617 END
618 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200619
620 lines =<< trim END
621 vim9script
622 def EchoList(...l: list<number>)
623 g:echo = l
624 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200625 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200626 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200627 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200628 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200629 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200630 END
631 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200632
633 lines =<< trim END
634 vim9script
635 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
636 g:optarg = opt
637 g:listarg = l
638 return nr
639 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200640 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200641 Funcref(10)->assert_equal(10)
642 g:optarg->assert_equal(12)
643 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200644
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200645 Funcref(11, 22)->assert_equal(11)
646 g:optarg->assert_equal(22)
647 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200648
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200649 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
650 g:optarg->assert_equal(18)
651 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200652 END
653 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200654enddef
655
656let SomeFunc = function('len')
657let NotAFunc = 'text'
658
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200659def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200660 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200661 var Ref1: func(bool): string
662 var Ref2: func(bool): number
663 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200664 Ref3 = g:cond ? Ref1 : Ref2
665
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200666 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200667 var Refa1: func(bool): number
668 var Refa2: func(bool, number): number
669 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200670 Refa3 = g:cond ? Refa1 : Refa2
671
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200672 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200673 var Refb1: func(bool, string): number
674 var Refb2: func(string, number): number
675 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200676 Refb3 = g:cond ? Refb1 : Refb2
677enddef
678
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200679def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200680 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200681enddef
682
683def DefinedEvenLater(arg: string): string
684 return arg
685enddef
686
687def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200688 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200689 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200690enddef
691
692def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200693 CheckScriptFailure([
694 'def Func(): number',
695 'return "a"',
696 'enddef',
697 'defcompile'], 'expected number but got string')
698 CheckScriptFailure([
699 'def Func(): string',
700 'return 1',
701 'enddef',
702 'defcompile'], 'expected string but got number')
703 CheckScriptFailure([
704 'def Func(): void',
705 'return "a"',
706 'enddef',
707 'defcompile'],
708 'E1096: Returning a value in a function without a return type')
709 CheckScriptFailure([
710 'def Func()',
711 'return "a"',
712 'enddef',
713 'defcompile'],
714 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200715
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200716 CheckScriptFailure([
717 'def Func(): number',
718 'return',
719 'enddef',
720 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200721
722 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
723 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200724 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200725
726 CheckScriptFailure([
727 'vim9script',
728 'def FuncB()',
729 ' return 123',
730 'enddef',
731 'def FuncA()',
732 ' FuncB()',
733 'enddef',
734 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200735enddef
736
737def Test_arg_type_wrong()
738 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200739 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200740 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200741 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200742enddef
743
744def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200745 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200746 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200747 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200748 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200749 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200750 enddef
751 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200752 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200754 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200755 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200756 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200757
Bram Moolenaar67979662020-06-20 22:50:47 +0200758 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200759 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200760 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200761
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200762 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200763 def ListFunc(arg: list<number>)
764 listvar = arg
765 enddef
766 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200767 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200768
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200769 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200770 def DictFunc(arg: dict<number>)
771 dictvar = arg
772 enddef
773 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200774 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200775 def CompiledDict()
776 {'a': 3, 'b': 4}->DictFunc()
777 enddef
778 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200779 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200780
781 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200782 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200783
784 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200785 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200786 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200787 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200788
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200789 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200790 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200791 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200792 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200793 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200794 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200795
796 def UseString()
797 'xyork'->MyFunc()
798 enddef
799 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200800 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200801
Bram Moolenaar10409562020-07-29 20:00:38 +0200802 def UseString2()
803 "knife"->MyFunc()
804 enddef
805 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200806 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200807
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200808 # prepending a colon makes it a mark
809 new
810 setline(1, ['aaa', 'bbb', 'ccc'])
811 normal! 3Gmt1G
812 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200813 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200814 bwipe!
815
Bram Moolenaare6b53242020-07-01 17:28:33 +0200816 MyFunc(
817 'continued'
818 )
819 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200820 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200821 )
822
823 call MyFunc(
824 'more'
825 ..
826 'lines'
827 )
828 assert_equal(
829 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200830 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200831 END
832 writefile(lines, 'Xcall.vim')
833 source Xcall.vim
834 delete('Xcall.vim')
835enddef
836
837def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200838 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200839 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200840 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200841 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200842 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200843 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200844 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200845 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200846 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200847enddef
848
Bram Moolenaar65b95452020-07-19 14:03:09 +0200849def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200850 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200851 vim9script
852 def MyFunc(arg: string)
853 echo arg
854 enddef
855 MyFunc(1234)
856 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200857 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200858enddef
859
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200860def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200861 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200862 vim9script
863 const var = ''
864 def MyFunc(arg: string)
865 var = 'asdf'
866 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200867 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200868 END
869 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200870 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200871 delete('Xcall_const.vim')
872enddef
873
874" Test that inside :function a Python function can be defined, :def is not
875" recognized.
876func Test_function_python()
877 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200878 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200879 execute py "<< EOF"
880def do_something():
881 return 1
882EOF
883endfunc
884
885def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200886 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200887 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200888 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200889 echo 'hello'
890 enddef
891
892 def CallGoneSoon()
893 GoneSoon()
894 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200895 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200896
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200897 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200898 CallGoneSoon()
899 END
900 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200901 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
902 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200903
904 delete('XToDelFunc')
905enddef
906
907def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200908 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200910 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200911 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200912 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200913 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200914 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200915 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200916 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200917
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200918 g:Func0()->assert_equal(0)
919 g:Func1()->assert_equal('Func1')
920 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200921
922 delfunc! Func0
923 delfunc! Func1
924 delfunc! Func2
925enddef
926
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200927def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200928 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200929 vim9script
930 func Func(arg)
931 echo a:arg
932 endfunc
933 Func('text')
934 END
935 writefile(lines, 'XVim9Func')
936 so XVim9Func
937
938 delete('XVim9Func')
939enddef
940
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200941let s:funcResult = 0
942
943def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200944 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200945enddef
946
947def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200948 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200949 return 1234
950enddef
951
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200952def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200953 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200954 return 'text'
955enddef
956
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200957def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200958 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200959enddef
960
961def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200962 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200963 return arg
964enddef
965
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200966def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200967 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200968enddef
969
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200970def FuncOneArgRetString(arg: string): string
971 return arg
972enddef
973
Bram Moolenaar89228602020-04-05 22:14:54 +0200974def FuncOneArgRetAny(arg: any): any
975 return arg
976enddef
977
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200978def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200979 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200980 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200981 Ref1 = FuncNoArgNoRet
982 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200983 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200984
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200985 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200986 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200987 Ref2 = FuncNoArgNoRet
988 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200989 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200990
Bram Moolenaar53900992020-08-22 19:02:02 +0200991 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200992 Ref2 = FuncOneArgNoRet
993 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200994 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200995
Bram Moolenaar53900992020-08-22 19:02:02 +0200996 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200997 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200998 Ref2()->assert_equal(1234)
999 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001000
Bram Moolenaar53900992020-08-22 19:02:02 +02001001 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001002 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001003 Ref2(13)->assert_equal(13)
1004 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001005enddef
1006
Bram Moolenaar9978d472020-07-05 16:01:56 +02001007def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001008 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001009 for n in repeat([1], 3)
1010 res += n
1011 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001012 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001013
1014 res = 0
1015 for n in add([1, 2], 3)
1016 res += n
1017 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001018 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001019enddef
1020
Bram Moolenaar846178a2020-07-05 17:04:13 +02001021def Test_argv_return_type()
1022 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001023 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001024 for name in argv()
1025 res ..= name
1026 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001027 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001028enddef
1029
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001030def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001031 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001032 RefVoid = FuncNoArgNoRet
1033 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001034 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1035 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001036
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001037 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001038 RefAny = FuncNoArgRetNumber
1039 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001040 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1041 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001042
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001043 var RefAnyNoArgs: func: any = RefAny
1044
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001045 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001046 RefNr = FuncNoArgRetNumber
1047 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001048 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1049 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001050
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001051 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001052 RefStr = FuncNoArgRetString
1053 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001054 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1055 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001056enddef
1057
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001058def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001059 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001060
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001061 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1062 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1063 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1064 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1065 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1066 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 +02001067
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001068 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1069 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1070 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:')
1071 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001072enddef
1073
Bram Moolenaar89228602020-04-05 22:14:54 +02001074def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001075 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001076 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001077 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001078
1079 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001080 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001081
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001082 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001083 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001084 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001085
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001086 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001087enddef
1088
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001089def Test_func_common_type()
1090 def FuncOne(n: number): number
1091 return n
1092 enddef
1093 def FuncTwo(s: string): number
1094 return len(s)
1095 enddef
1096 def FuncThree(n: number, s: string): number
1097 return n + len(s)
1098 enddef
1099 var list = [FuncOne, FuncTwo, FuncThree]
1100 assert_equal(8, list[0](8))
1101 assert_equal(4, list[1]('word'))
1102 assert_equal(7, list[2](3, 'word'))
1103enddef
1104
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001105def MultiLine(
1106 arg1: string,
1107 arg2 = 1234,
1108 ...rest: list<string>
1109 ): string
1110 return arg1 .. arg2 .. join(rest, '-')
1111enddef
1112
Bram Moolenaar2c330432020-04-13 14:41:35 +02001113def MultiLineComment(
1114 arg1: string, # comment
1115 arg2 = 1234, # comment
1116 ...rest: list<string> # comment
1117 ): string # comment
1118 return arg1 .. arg2 .. join(rest, '-')
1119enddef
1120
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001121def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001122 MultiLine('text')->assert_equal('text1234')
1123 MultiLine('text', 777)->assert_equal('text777')
1124 MultiLine('text', 777, 'one')->assert_equal('text777one')
1125 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001126enddef
1127
Bram Moolenaar23e03252020-04-12 22:22:31 +02001128func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001129 call MultiLine('text')->assert_equal('text1234')
1130 call MultiLine('text', 777)->assert_equal('text777')
1131 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1132 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001133endfunc
1134
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001135
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001136" When using CheckScriptFailure() for the below test, E1010 is generated instead
1137" of E1056.
1138func Test_E1056_1059()
1139 let caught_1056 = 0
1140 try
1141 def F():
1142 return 1
1143 enddef
1144 catch /E1056:/
1145 let caught_1056 = 1
1146 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001147 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001148
1149 let caught_1059 = 0
1150 try
1151 def F5(items : list)
1152 echo 'a'
1153 enddef
1154 catch /E1059:/
1155 let caught_1059 = 1
1156 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001157 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001158endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001159
Bram Moolenaar015f4262020-05-05 21:25:22 +02001160func DelMe()
1161 echo 'DelMe'
1162endfunc
1163
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001164def Test_error_reporting()
1165 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001166 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001167 " comment
1168 def Func()
1169 # comment
1170 # comment
1171 invalid
1172 enddef
1173 defcompile
1174 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001175 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001176 try
1177 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001178 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001179 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001180 v:exception->assert_match('Invalid command: invalid')
1181 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001182 endtry
1183
1184 # comment lines after the start of the function
1185 lines =<< trim END
1186 " comment
1187 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001188 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001189 # comment
1190 # comment
1191 invalid
1192 enddef
1193 defcompile
1194 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001195 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001196 try
1197 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001198 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001199 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001200 v:exception->assert_match('Invalid command: invalid')
1201 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001202 endtry
1203
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001204 lines =<< trim END
1205 vim9script
1206 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001207 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001208 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001209 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001210 enddef
1211 defcompile
1212 Func()
1213 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001214 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001215 try
1216 source Xdef
1217 assert_report('should have failed')
1218 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001219 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001220 endtry
1221
Bram Moolenaar08052222020-09-14 17:04:31 +02001222 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001223enddef
1224
Bram Moolenaar015f4262020-05-05 21:25:22 +02001225def Test_deleted_function()
1226 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001227 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001228 'delfunc g:DelMe',
1229 'echo RefMe()'], 'E117:')
1230enddef
1231
1232def Test_unknown_function()
1233 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001234 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001235 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001236enddef
1237
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001238def RefFunc(Ref: func(string): string): string
1239 return Ref('more')
1240enddef
1241
1242def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001243 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001244 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001245enddef
1246
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001247def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001248 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001249 g:Ref = {s -> local .. s}
1250enddef
1251
1252def Test_closure_ref_after_return()
1253 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001254 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001255 unlet g:Ref
1256enddef
1257
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001258def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001259 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001260 g:Extend = {s -> local->add(s)}
1261 g:Read = {-> local}
1262enddef
1263
1264def Test_closure_two_refs()
1265 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001266 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001267 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001268 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001269 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001270 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001271
1272 unlet g:Extend
1273 unlet g:Read
1274enddef
1275
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001276def ReadRef(Ref: func(): list<string>): string
1277 return join(Ref(), ' ')
1278enddef
1279
Bram Moolenaar5e654232020-09-16 15:22:00 +02001280def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001281 Ref(add)
1282enddef
1283
1284def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001285 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001286 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001287 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001288 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001289 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001290 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001291
1292 unlet g:Extend
1293 unlet g:Read
1294enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001295
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001296def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001297 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001298 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1299enddef
1300
1301def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001302 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001303 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1304enddef
1305
1306def Test_closure_using_argument()
1307 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001308 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001309
1310 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001311 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001312
1313 unlet g:UseArg
1314 unlet g:UseVararg
1315enddef
1316
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001317def MakeGetAndAppendRefs()
1318 var local = 'a'
1319
1320 def Append(arg: string)
1321 local ..= arg
1322 enddef
1323 g:Append = Append
1324
1325 def Get(): string
1326 return local
1327 enddef
1328 g:Get = Get
1329enddef
1330
1331def Test_closure_append_get()
1332 MakeGetAndAppendRefs()
1333 g:Get()->assert_equal('a')
1334 g:Append('-b')
1335 g:Get()->assert_equal('a-b')
1336 g:Append('-c')
1337 g:Get()->assert_equal('a-b-c')
1338
1339 unlet g:Append
1340 unlet g:Get
1341enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001342
Bram Moolenaar04b12692020-05-04 23:24:44 +02001343def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001344 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001345 def Closure(arg: string): string
1346 return local .. arg
1347 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001348 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001349enddef
1350
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001351func GetResult(Ref)
1352 return a:Ref('some')
1353endfunc
1354
1355def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001356 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001357 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001358 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001359enddef
1360
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001361def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001362 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001363 vim9script
1364 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001365 var name = 0
1366 for i in range(2)
1367 timer_start(0, {-> name})
1368 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001369 enddef
1370 Func()
1371 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001372 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001373enddef
1374
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001375def Test_nested_closure_used()
1376 var lines =<< trim END
1377 vim9script
1378 def Func()
1379 var x = 'hello'
1380 var Closure = {-> x}
1381 g:Myclosure = {-> Closure()}
1382 enddef
1383 Func()
1384 assert_equal('hello', g:Myclosure())
1385 END
1386 CheckScriptSuccess(lines)
1387enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001388
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001389def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001390 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001391 vim9script
1392 def FuncA()
1393 FuncB(0)
1394 enddef
1395 def FuncB(n: number): list<string>
1396 return map([0], {_, v -> n})
1397 enddef
1398 FuncA()
1399 END
1400 CheckScriptFailure(lines, 'E1012:')
1401enddef
1402
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001403def Test_nested_lambda()
1404 var lines =<< trim END
1405 vim9script
1406 def Func()
1407 var x = 4
1408 var Lambda1 = {-> 7}
1409 var Lambda2 = {-> [Lambda1(), x]}
1410 var res = Lambda2()
1411 assert_equal([7, 4], res)
1412 enddef
1413 Func()
1414 END
1415 CheckScriptSuccess(lines)
1416enddef
1417
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001418def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001419 var path: string = empty(dir)
1420 \ ? 'empty'
1421 \ : 'full'
1422 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001423enddef
1424
1425def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001426 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001427enddef
1428
Bram Moolenaar5e654232020-09-16 15:22:00 +02001429def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001430 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001431 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001432 ->toupper()})
1433 ->reverse()
1434 return x
1435enddef
1436
1437def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001438 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001439enddef
1440
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001441func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001442 CheckScreendump
1443
1444 let lines =<< trim END
1445 vim9script
1446 def EchoNothing()
1447 silent echo ''
1448 enddef
1449 defcompile
1450 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001451 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001452
1453 " Check that the balloon shows up after a mouse move
1454 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001455 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001456 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1457
1458 " clean up
1459 call StopVimInTerminal(buf)
1460 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001461endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001462
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001463def Fibonacci(n: number): number
1464 if n < 2
1465 return n
1466 else
1467 return Fibonacci(n - 1) + Fibonacci(n - 2)
1468 endif
1469enddef
1470
Bram Moolenaar985116a2020-07-12 17:31:09 +02001471def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001472 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001473enddef
1474
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001475def TreeWalk(dir: string): list<any>
1476 return readdir(dir)->map({_, val ->
1477 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001478 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001479 : val
1480 })
1481enddef
1482
1483def Test_closure_in_map()
1484 mkdir('XclosureDir/tdir', 'p')
1485 writefile(['111'], 'XclosureDir/file1')
1486 writefile(['222'], 'XclosureDir/file2')
1487 writefile(['333'], 'XclosureDir/tdir/file3')
1488
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001489 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001490
1491 delete('XclosureDir', 'rf')
1492enddef
1493
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001494def Test_invalid_function_name()
1495 var lines =<< trim END
1496 vim9script
1497 def s: list<string>
1498 END
1499 CheckScriptFailure(lines, 'E129:')
1500
1501 lines =<< trim END
1502 vim9script
1503 def g: list<string>
1504 END
1505 CheckScriptFailure(lines, 'E129:')
1506
1507 lines =<< trim END
1508 vim9script
1509 def <SID>: list<string>
1510 END
1511 CheckScriptFailure(lines, 'E884:')
1512
1513 lines =<< trim END
1514 vim9script
1515 def F list<string>
1516 END
1517 CheckScriptFailure(lines, 'E488:')
1518enddef
1519
Bram Moolenaara90afb92020-07-15 22:38:56 +02001520def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001521 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02001522 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001523 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001524
1525 Xsetlist = function('setloclist', [0, [], ' '])
1526 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001527 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001528
1529 Xsetlist = function('setqflist')
1530 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001531 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001532
1533 Xsetlist = function('setqflist', [[], ' '])
1534 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001535 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001536
1537 var Len: func: number = function('len', ['word'])
1538 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001539enddef
1540
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001541def Test_cmd_modifier()
1542 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001543 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001544enddef
1545
1546def Test_restore_modifiers()
1547 # check that when compiling a :def function command modifiers are not messed
1548 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001549 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001550 vim9script
1551 set eventignore=
1552 autocmd QuickFixCmdPost * copen
1553 def AutocmdsDisabled()
1554 eval 0
1555 enddef
1556 func Func()
1557 noautocmd call s:AutocmdsDisabled()
1558 let g:ei_after = &eventignore
1559 endfunc
1560 Func()
1561 END
1562 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001563 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001564enddef
1565
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001566def StackTop()
1567 eval 1
1568 eval 2
1569 # call not on fourth line
1570 StackBot()
1571enddef
1572
1573def StackBot()
1574 # throw an error
1575 eval [][0]
1576enddef
1577
1578def Test_callstack_def()
1579 try
1580 StackTop()
1581 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001582 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001583 endtry
1584enddef
1585
Bram Moolenaare8211a32020-10-09 22:04:29 +02001586" Re-using spot for variable used in block
1587def Test_block_scoped_var()
1588 var lines =<< trim END
1589 vim9script
1590 def Func()
1591 var x = ['a', 'b', 'c']
1592 if 1
1593 var y = 'x'
1594 map(x, {-> y})
1595 endif
1596 var z = x
1597 assert_equal(['x', 'x', 'x'], z)
1598 enddef
1599 Func()
1600 END
1601 CheckScriptSuccess(lines)
1602enddef
1603
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001604
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001605" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker