blob: a3f21491f2162d1f16d9f88df606e52cff28da61 [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
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100379def Test_call_lambda_args()
380 CheckDefFailure(['echo {i -> 0}()'],
381 'E119: Not enough arguments for function: {i -> 0}()')
382
383 var lines =<< trim END
384 var Ref = {x: number, y: number -> x + y}
385 echo Ref(1, 'x')
386 END
387 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
388enddef
389
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200390" Default arg and varargs
391def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200392 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200393 for s in rest
394 res ..= ',' .. s
395 endfor
396 return res
397enddef
398
399def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200400 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200401 MyDefVarargs('one')->assert_equal('one,foo')
402 MyDefVarargs('one', 'two')->assert_equal('one,two')
403 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200404 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200405 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200406 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200407 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200408
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200409 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200410 vim9script
411 def Func(...l: list<string>)
412 echo l
413 enddef
414 Func('a', 'b', 'c')
415 END
416 CheckScriptSuccess(lines)
417
418 lines =<< trim END
419 vim9script
420 def Func(...l: list<string>)
421 echo l
422 enddef
423 Func()
424 END
425 CheckScriptSuccess(lines)
426
427 lines =<< trim END
428 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200429 def Func(...l: any)
430 echo l
431 enddef
432 Func(0)
433 END
434 CheckScriptSuccess(lines)
435
436 lines =<< trim END
437 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200438 def Func(..._l: list<string>)
439 echo _l
440 enddef
441 Func('a', 'b', 'c')
442 END
443 CheckScriptSuccess(lines)
444
445 lines =<< trim END
446 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200447 def Func(...l: list<string>)
448 echo l
449 enddef
450 Func(1, 2, 3)
451 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200452 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200453
454 lines =<< trim END
455 vim9script
456 def Func(...l: list<string>)
457 echo l
458 enddef
459 Func('a', 9)
460 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200461 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200462
463 lines =<< trim END
464 vim9script
465 def Func(...l: list<string>)
466 echo l
467 enddef
468 Func(1, 'a')
469 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200470 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200471enddef
472
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200473let s:value = ''
474
475def FuncOneDefArg(opt = 'text')
476 s:value = opt
477enddef
478
479def FuncTwoDefArg(nr = 123, opt = 'text'): string
480 return nr .. opt
481enddef
482
483def FuncVarargs(...arg: list<string>): string
484 return join(arg, ',')
485enddef
486
487def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200488 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200489 RefDefArg = FuncOneDefArg
490 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200491 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200492 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200493 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200494
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200495 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200496 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200497 RefDef2Arg()->assert_equal('123text')
498 RefDef2Arg(99)->assert_equal('99text')
499 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200500
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200501 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
502 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200503
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200504 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200505 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200506 RefVarargs()->assert_equal('')
507 RefVarargs('one')->assert_equal('one')
508 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200509
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200510 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
511 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200512enddef
513
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200514" Only varargs
515def MyVarargsOnly(...args: list<string>): string
516 return join(args, ',')
517enddef
518
519def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200520 MyVarargsOnly()->assert_equal('')
521 MyVarargsOnly('one')->assert_equal('one')
522 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200523 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
524 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200525enddef
526
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200527def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200528 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200529 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200530 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200531enddef
532
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200533def DictArg(arg: dict<string>)
534 arg['key'] = 'value'
535enddef
536
537def ListArg(arg: list<string>)
538 arg[0] = 'value'
539enddef
540
541def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200542 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200543 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200544 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200545 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200546 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200547 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200548 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200549
Bram Moolenaard2c61702020-09-06 15:58:36 +0200550 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200551enddef
552
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200553" These argument names are reserved in legacy functions.
554def WithReservedNames(firstline: string, lastline: string): string
555 return firstline .. lastline
556enddef
557
558def Test_argument_names()
559 assert_equal('OK', WithReservedNames('O', 'K'))
560enddef
561
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200562def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200563 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200564 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200565enddef
566
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200567func DefinedLater(arg)
568 return a:arg
569endfunc
570
571def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200572 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200573 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
574 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200575
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200576 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200577 vim9script
578 def RetNumber(): number
579 return 123
580 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200581 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200582 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200583 END
584 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200585
586 lines =<< trim END
587 vim9script
588 def RetNumber(): number
589 return 123
590 enddef
591 def Bar(F: func: number): number
592 return F()
593 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200594 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200595 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200596 END
597 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200598
599 lines =<< trim END
600 vim9script
601 def UseNumber(nr: number)
602 echo nr
603 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200604 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200605 Funcref(123)
606 END
607 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200608
609 lines =<< trim END
610 vim9script
611 def UseNumber(nr: number)
612 echo nr
613 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200614 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200615 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200616 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200617
618 lines =<< trim END
619 vim9script
620 def EchoNr(nr = 34)
621 g:echo = nr
622 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200623 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200624 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200625 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200626 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200627 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200628 END
629 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200630
631 lines =<< trim END
632 vim9script
633 def EchoList(...l: list<number>)
634 g:echo = l
635 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200636 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200637 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200638 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200639 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200640 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200641 END
642 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200643
644 lines =<< trim END
645 vim9script
646 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
647 g:optarg = opt
648 g:listarg = l
649 return nr
650 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200651 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200652 Funcref(10)->assert_equal(10)
653 g:optarg->assert_equal(12)
654 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200655
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200656 Funcref(11, 22)->assert_equal(11)
657 g:optarg->assert_equal(22)
658 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200659
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200660 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
661 g:optarg->assert_equal(18)
662 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200663 END
664 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200665enddef
666
667let SomeFunc = function('len')
668let NotAFunc = 'text'
669
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200670def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200671 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200672 var Ref1: func(bool): string
673 var Ref2: func(bool): number
674 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200675 Ref3 = g:cond ? Ref1 : Ref2
676
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200677 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200678 var Refa1: func(bool): number
679 var Refa2: func(bool, number): number
680 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200681 Refa3 = g:cond ? Refa1 : Refa2
682
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200683 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200684 var Refb1: func(bool, string): number
685 var Refb2: func(string, number): number
686 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200687 Refb3 = g:cond ? Refb1 : Refb2
688enddef
689
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200690def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200691 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200692enddef
693
694def DefinedEvenLater(arg: string): string
695 return arg
696enddef
697
698def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200699 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200700 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200701enddef
702
703def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200704 CheckScriptFailure([
705 'def Func(): number',
706 'return "a"',
707 'enddef',
708 'defcompile'], 'expected number but got string')
709 CheckScriptFailure([
710 'def Func(): string',
711 'return 1',
712 'enddef',
713 'defcompile'], 'expected string but got number')
714 CheckScriptFailure([
715 'def Func(): void',
716 'return "a"',
717 'enddef',
718 'defcompile'],
719 'E1096: Returning a value in a function without a return type')
720 CheckScriptFailure([
721 'def Func()',
722 'return "a"',
723 'enddef',
724 'defcompile'],
725 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200726
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200727 CheckScriptFailure([
728 'def Func(): number',
729 'return',
730 'enddef',
731 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200732
733 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
734 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200735 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200736
737 CheckScriptFailure([
738 'vim9script',
739 'def FuncB()',
740 ' return 123',
741 'enddef',
742 'def FuncA()',
743 ' FuncB()',
744 'enddef',
745 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200746enddef
747
748def Test_arg_type_wrong()
749 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200750 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200751 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200752 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753enddef
754
755def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200756 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200757 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200758 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200759 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200760 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200761 enddef
762 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200763 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200764
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200765 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200766 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200767 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200768
Bram Moolenaar67979662020-06-20 22:50:47 +0200769 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200770 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200771 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200772
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200773 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200774 def ListFunc(arg: list<number>)
775 listvar = arg
776 enddef
777 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200778 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200779
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200780 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200781 def DictFunc(arg: dict<number>)
782 dictvar = arg
783 enddef
784 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200785 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200786 def CompiledDict()
787 {'a': 3, 'b': 4}->DictFunc()
788 enddef
789 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200790 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200791
792 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200793 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200794
795 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200796 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200797 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200798 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200799
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200800 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200801 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200802 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200803 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200804 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200805 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200806
807 def UseString()
808 'xyork'->MyFunc()
809 enddef
810 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200811 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200812
Bram Moolenaar10409562020-07-29 20:00:38 +0200813 def UseString2()
814 "knife"->MyFunc()
815 enddef
816 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200817 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200818
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200819 # prepending a colon makes it a mark
820 new
821 setline(1, ['aaa', 'bbb', 'ccc'])
822 normal! 3Gmt1G
823 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200824 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200825 bwipe!
826
Bram Moolenaare6b53242020-07-01 17:28:33 +0200827 MyFunc(
828 'continued'
829 )
830 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200831 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200832 )
833
834 call MyFunc(
835 'more'
836 ..
837 'lines'
838 )
839 assert_equal(
840 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200841 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200842 END
843 writefile(lines, 'Xcall.vim')
844 source Xcall.vim
845 delete('Xcall.vim')
846enddef
847
848def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200849 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200850 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200851 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200852 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200853 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200854 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200855 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200856 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200857 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200858enddef
859
Bram Moolenaar65b95452020-07-19 14:03:09 +0200860def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200861 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200862 vim9script
863 def MyFunc(arg: string)
864 echo arg
865 enddef
866 MyFunc(1234)
867 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200868 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200869enddef
870
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200871def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200872 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200873 vim9script
874 const var = ''
875 def MyFunc(arg: string)
876 var = 'asdf'
877 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200878 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200879 END
880 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200881 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200882 delete('Xcall_const.vim')
883enddef
884
885" Test that inside :function a Python function can be defined, :def is not
886" recognized.
887func Test_function_python()
888 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200889 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200890 execute py "<< EOF"
891def do_something():
892 return 1
893EOF
894endfunc
895
896def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200897 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200898 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200899 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200900 echo 'hello'
901 enddef
902
903 def CallGoneSoon()
904 GoneSoon()
905 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200906 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200907
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200908 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909 CallGoneSoon()
910 END
911 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200912 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
913 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200914
915 delete('XToDelFunc')
916enddef
917
918def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200919 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200920 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200921 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200922 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200923 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200924 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200925 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200926 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200927 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200928
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200929 g:Func0()->assert_equal(0)
930 g:Func1()->assert_equal('Func1')
931 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200932
933 delfunc! Func0
934 delfunc! Func1
935 delfunc! Func2
936enddef
937
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200938def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200939 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200940 vim9script
941 func Func(arg)
942 echo a:arg
943 endfunc
944 Func('text')
945 END
946 writefile(lines, 'XVim9Func')
947 so XVim9Func
948
949 delete('XVim9Func')
950enddef
951
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200952let s:funcResult = 0
953
954def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200955 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200956enddef
957
958def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200959 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200960 return 1234
961enddef
962
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200963def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200964 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200965 return 'text'
966enddef
967
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200968def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200969 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200970enddef
971
972def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200973 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200974 return arg
975enddef
976
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200977def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200978 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200979enddef
980
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200981def FuncOneArgRetString(arg: string): string
982 return arg
983enddef
984
Bram Moolenaar89228602020-04-05 22:14:54 +0200985def FuncOneArgRetAny(arg: any): any
986 return arg
987enddef
988
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200989def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200990 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200991 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200992 Ref1 = FuncNoArgNoRet
993 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200994 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200995
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200996 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200997 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200998 Ref2 = FuncNoArgNoRet
999 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001000 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001001
Bram Moolenaar53900992020-08-22 19:02:02 +02001002 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001003 Ref2 = FuncOneArgNoRet
1004 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001005 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001006
Bram Moolenaar53900992020-08-22 19:02:02 +02001007 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001008 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001009 Ref2()->assert_equal(1234)
1010 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001011
Bram Moolenaar53900992020-08-22 19:02:02 +02001012 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001013 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001014 Ref2(13)->assert_equal(13)
1015 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001016enddef
1017
Bram Moolenaar9978d472020-07-05 16:01:56 +02001018def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001019 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001020 for n in repeat([1], 3)
1021 res += n
1022 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001023 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001024
1025 res = 0
1026 for n in add([1, 2], 3)
1027 res += n
1028 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001029 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001030enddef
1031
Bram Moolenaar846178a2020-07-05 17:04:13 +02001032def Test_argv_return_type()
1033 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001034 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001035 for name in argv()
1036 res ..= name
1037 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001038 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001039enddef
1040
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001041def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001042 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001043 RefVoid = FuncNoArgNoRet
1044 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001045 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1046 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001047
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001048 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001049 RefAny = FuncNoArgRetNumber
1050 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001051 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1052 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001053
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001054 var RefAnyNoArgs: func: any = RefAny
1055
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001056 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001057 RefNr = FuncNoArgRetNumber
1058 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001059 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1060 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001061
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001062 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001063 RefStr = FuncNoArgRetString
1064 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001065 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1066 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001067enddef
1068
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001069def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001070 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001071
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001072 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1073 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1074 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1075 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1076 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1077 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 +02001078
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001079 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1080 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1081 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:')
1082 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001083enddef
1084
Bram Moolenaar89228602020-04-05 22:14:54 +02001085def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001086 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001087 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001088 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001089
1090 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001091 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001092
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001093 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001094 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001095 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001096
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001097 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001098enddef
1099
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001100def Test_func_common_type()
1101 def FuncOne(n: number): number
1102 return n
1103 enddef
1104 def FuncTwo(s: string): number
1105 return len(s)
1106 enddef
1107 def FuncThree(n: number, s: string): number
1108 return n + len(s)
1109 enddef
1110 var list = [FuncOne, FuncTwo, FuncThree]
1111 assert_equal(8, list[0](8))
1112 assert_equal(4, list[1]('word'))
1113 assert_equal(7, list[2](3, 'word'))
1114enddef
1115
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001116def MultiLine(
1117 arg1: string,
1118 arg2 = 1234,
1119 ...rest: list<string>
1120 ): string
1121 return arg1 .. arg2 .. join(rest, '-')
1122enddef
1123
Bram Moolenaar2c330432020-04-13 14:41:35 +02001124def MultiLineComment(
1125 arg1: string, # comment
1126 arg2 = 1234, # comment
1127 ...rest: list<string> # comment
1128 ): string # comment
1129 return arg1 .. arg2 .. join(rest, '-')
1130enddef
1131
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001132def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001133 MultiLine('text')->assert_equal('text1234')
1134 MultiLine('text', 777)->assert_equal('text777')
1135 MultiLine('text', 777, 'one')->assert_equal('text777one')
1136 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001137enddef
1138
Bram Moolenaar23e03252020-04-12 22:22:31 +02001139func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001140 call MultiLine('text')->assert_equal('text1234')
1141 call MultiLine('text', 777)->assert_equal('text777')
1142 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1143 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001144endfunc
1145
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001146
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001147" When using CheckScriptFailure() for the below test, E1010 is generated instead
1148" of E1056.
1149func Test_E1056_1059()
1150 let caught_1056 = 0
1151 try
1152 def F():
1153 return 1
1154 enddef
1155 catch /E1056:/
1156 let caught_1056 = 1
1157 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001158 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001159
1160 let caught_1059 = 0
1161 try
1162 def F5(items : list)
1163 echo 'a'
1164 enddef
1165 catch /E1059:/
1166 let caught_1059 = 1
1167 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001168 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001169endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001170
Bram Moolenaar015f4262020-05-05 21:25:22 +02001171func DelMe()
1172 echo 'DelMe'
1173endfunc
1174
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001175def Test_error_reporting()
1176 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001177 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001178 " comment
1179 def Func()
1180 # comment
1181 # comment
1182 invalid
1183 enddef
1184 defcompile
1185 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001186 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001187 try
1188 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001189 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001190 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001191 v:exception->assert_match('Invalid command: invalid')
1192 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001193 endtry
1194
1195 # comment lines after the start of the function
1196 lines =<< trim END
1197 " comment
1198 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001199 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001200 # comment
1201 # comment
1202 invalid
1203 enddef
1204 defcompile
1205 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001206 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001207 try
1208 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001209 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001210 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001211 v:exception->assert_match('Invalid command: invalid')
1212 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001213 endtry
1214
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001215 lines =<< trim END
1216 vim9script
1217 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001218 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001219 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001220 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001221 enddef
1222 defcompile
1223 Func()
1224 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001225 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001226 try
1227 source Xdef
1228 assert_report('should have failed')
1229 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001230 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001231 endtry
1232
Bram Moolenaar08052222020-09-14 17:04:31 +02001233 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001234enddef
1235
Bram Moolenaar015f4262020-05-05 21:25:22 +02001236def Test_deleted_function()
1237 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001238 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001239 'delfunc g:DelMe',
1240 'echo RefMe()'], 'E117:')
1241enddef
1242
1243def Test_unknown_function()
1244 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001245 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001246 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001247enddef
1248
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001249def RefFunc(Ref: func(string): string): string
1250 return Ref('more')
1251enddef
1252
1253def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001254 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001255 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001256enddef
1257
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001258def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001259 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001260 g:Ref = {s -> local .. s}
1261enddef
1262
1263def Test_closure_ref_after_return()
1264 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001265 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001266 unlet g:Ref
1267enddef
1268
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001269def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001270 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001271 g:Extend = {s -> local->add(s)}
1272 g:Read = {-> local}
1273enddef
1274
1275def Test_closure_two_refs()
1276 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001277 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001278 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001279 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001280 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001281 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001282
1283 unlet g:Extend
1284 unlet g:Read
1285enddef
1286
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001287def ReadRef(Ref: func(): list<string>): string
1288 return join(Ref(), ' ')
1289enddef
1290
Bram Moolenaar5e654232020-09-16 15:22:00 +02001291def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001292 Ref(add)
1293enddef
1294
1295def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001296 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001297 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001298 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001299 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001300 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001301 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001302
1303 unlet g:Extend
1304 unlet g:Read
1305enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001306
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001307def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001308 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001309 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1310enddef
1311
1312def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001313 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001314 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1315enddef
1316
1317def Test_closure_using_argument()
1318 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001319 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001320
1321 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001322 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001323
1324 unlet g:UseArg
1325 unlet g:UseVararg
1326enddef
1327
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001328def MakeGetAndAppendRefs()
1329 var local = 'a'
1330
1331 def Append(arg: string)
1332 local ..= arg
1333 enddef
1334 g:Append = Append
1335
1336 def Get(): string
1337 return local
1338 enddef
1339 g:Get = Get
1340enddef
1341
1342def Test_closure_append_get()
1343 MakeGetAndAppendRefs()
1344 g:Get()->assert_equal('a')
1345 g:Append('-b')
1346 g:Get()->assert_equal('a-b')
1347 g:Append('-c')
1348 g:Get()->assert_equal('a-b-c')
1349
1350 unlet g:Append
1351 unlet g:Get
1352enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001353
Bram Moolenaar04b12692020-05-04 23:24:44 +02001354def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001355 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001356 def Closure(arg: string): string
1357 return local .. arg
1358 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001359 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001360enddef
1361
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001362func GetResult(Ref)
1363 return a:Ref('some')
1364endfunc
1365
1366def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001367 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001368 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001369 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001370enddef
1371
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001372def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001373 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001374 vim9script
1375 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001376 var name = 0
1377 for i in range(2)
1378 timer_start(0, {-> name})
1379 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001380 enddef
1381 Func()
1382 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001383 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001384enddef
1385
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001386def Test_nested_closure_used()
1387 var lines =<< trim END
1388 vim9script
1389 def Func()
1390 var x = 'hello'
1391 var Closure = {-> x}
1392 g:Myclosure = {-> Closure()}
1393 enddef
1394 Func()
1395 assert_equal('hello', g:Myclosure())
1396 END
1397 CheckScriptSuccess(lines)
1398enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001399
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001400def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001401 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001402 vim9script
1403 def FuncA()
1404 FuncB(0)
1405 enddef
1406 def FuncB(n: number): list<string>
1407 return map([0], {_, v -> n})
1408 enddef
1409 FuncA()
1410 END
1411 CheckScriptFailure(lines, 'E1012:')
1412enddef
1413
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001414def Test_nested_lambda()
1415 var lines =<< trim END
1416 vim9script
1417 def Func()
1418 var x = 4
1419 var Lambda1 = {-> 7}
1420 var Lambda2 = {-> [Lambda1(), x]}
1421 var res = Lambda2()
1422 assert_equal([7, 4], res)
1423 enddef
1424 Func()
1425 END
1426 CheckScriptSuccess(lines)
1427enddef
1428
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001429def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001430 var path: string = empty(dir)
1431 \ ? 'empty'
1432 \ : 'full'
1433 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001434enddef
1435
1436def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001437 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001438enddef
1439
Bram Moolenaar5e654232020-09-16 15:22:00 +02001440def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001441 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001442 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001443 ->toupper()})
1444 ->reverse()
1445 return x
1446enddef
1447
1448def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001449 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001450enddef
1451
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001452func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001453 CheckScreendump
1454
1455 let lines =<< trim END
1456 vim9script
1457 def EchoNothing()
1458 silent echo ''
1459 enddef
1460 defcompile
1461 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001462 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001463
1464 " Check that the balloon shows up after a mouse move
1465 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001466 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001467 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1468
1469 " clean up
1470 call StopVimInTerminal(buf)
1471 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001472endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001473
Bram Moolenaar171fb922020-10-28 16:54:47 +01001474def SilentlyError()
1475 execute('silent! invalid')
1476 g:did_it = 'yes'
1477enddef
1478
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001479func UserError()
1480 silent! invalid
1481endfunc
1482
1483def SilentlyUserError()
1484 UserError()
1485 g:did_it = 'yes'
1486enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001487
1488" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001489func Test_ignore_silent_error()
1490 let g:did_it = 'no'
1491 call SilentlyError()
1492 call assert_equal('yes', g:did_it)
1493
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001494 let g:did_it = 'no'
1495 call SilentlyUserError()
1496 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001497
1498 unlet g:did_it
1499endfunc
1500
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001501def Test_ignore_silent_error_in_filter()
1502 var lines =<< trim END
1503 vim9script
1504 def Filter(winid: number, key: string): bool
1505 if key == 'o'
1506 silent! eval [][0]
1507 return true
1508 endif
1509 return popup_filter_menu(winid, key)
1510 enddef
1511
1512 popup_create('popup', #{filter: Filter})
1513 feedkeys("o\r", 'xnt')
1514 END
1515 CheckScriptSuccess(lines)
1516enddef
1517
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001518def Fibonacci(n: number): number
1519 if n < 2
1520 return n
1521 else
1522 return Fibonacci(n - 1) + Fibonacci(n - 2)
1523 endif
1524enddef
1525
Bram Moolenaar985116a2020-07-12 17:31:09 +02001526def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001527 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001528enddef
1529
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001530def TreeWalk(dir: string): list<any>
1531 return readdir(dir)->map({_, val ->
1532 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001533 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001534 : val
1535 })
1536enddef
1537
1538def Test_closure_in_map()
1539 mkdir('XclosureDir/tdir', 'p')
1540 writefile(['111'], 'XclosureDir/file1')
1541 writefile(['222'], 'XclosureDir/file2')
1542 writefile(['333'], 'XclosureDir/tdir/file3')
1543
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001544 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001545
1546 delete('XclosureDir', 'rf')
1547enddef
1548
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001549def Test_invalid_function_name()
1550 var lines =<< trim END
1551 vim9script
1552 def s: list<string>
1553 END
1554 CheckScriptFailure(lines, 'E129:')
1555
1556 lines =<< trim END
1557 vim9script
1558 def g: list<string>
1559 END
1560 CheckScriptFailure(lines, 'E129:')
1561
1562 lines =<< trim END
1563 vim9script
1564 def <SID>: list<string>
1565 END
1566 CheckScriptFailure(lines, 'E884:')
1567
1568 lines =<< trim END
1569 vim9script
1570 def F list<string>
1571 END
1572 CheckScriptFailure(lines, 'E488:')
1573enddef
1574
Bram Moolenaara90afb92020-07-15 22:38:56 +02001575def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001576 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02001577 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001578 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001579
1580 Xsetlist = function('setloclist', [0, [], ' '])
1581 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001582 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001583
1584 Xsetlist = function('setqflist')
1585 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001586 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001587
1588 Xsetlist = function('setqflist', [[], ' '])
1589 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001590 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001591
1592 var Len: func: number = function('len', ['word'])
1593 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001594enddef
1595
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001596def Test_cmd_modifier()
1597 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001598 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001599enddef
1600
1601def Test_restore_modifiers()
1602 # check that when compiling a :def function command modifiers are not messed
1603 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001604 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001605 vim9script
1606 set eventignore=
1607 autocmd QuickFixCmdPost * copen
1608 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001609 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001610 enddef
1611 func Func()
1612 noautocmd call s:AutocmdsDisabled()
1613 let g:ei_after = &eventignore
1614 endfunc
1615 Func()
1616 END
1617 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001618 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001619enddef
1620
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001621def StackTop()
1622 eval 1
1623 eval 2
1624 # call not on fourth line
1625 StackBot()
1626enddef
1627
1628def StackBot()
1629 # throw an error
1630 eval [][0]
1631enddef
1632
1633def Test_callstack_def()
1634 try
1635 StackTop()
1636 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001637 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001638 endtry
1639enddef
1640
Bram Moolenaare8211a32020-10-09 22:04:29 +02001641" Re-using spot for variable used in block
1642def Test_block_scoped_var()
1643 var lines =<< trim END
1644 vim9script
1645 def Func()
1646 var x = ['a', 'b', 'c']
1647 if 1
1648 var y = 'x'
1649 map(x, {-> y})
1650 endif
1651 var z = x
1652 assert_equal(['x', 'x', 'x'], z)
1653 enddef
1654 Func()
1655 END
1656 CheckScriptSuccess(lines)
1657enddef
1658
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001659
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001660" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker