blob: 9b10c2bda33403c3232512420fcaa149f3cd5e45 [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 Moolenaar6cf7e3b2020-10-28 14:31:16 +0100325 CheckDefFailure(['echo {i -> 0}()'], 'E119: Not enough arguments for function: {i -> 0}()')
326
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200327 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200328 vim9script
329 def Func(s: string)
330 echo s
331 enddef
332 Func([])
333 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200334 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200335
336 lines =<< trim END
337 vim9script
338 def FuncOne(nr: number)
339 echo nr
340 enddef
341 def FuncTwo()
342 FuncOne()
343 enddef
344 defcompile
345 END
346 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200347 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200348 try
349 source Xscript
350 catch
351 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
352 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
353 didCatch = true
354 endtry
355 assert_true(didCatch)
356
357 lines =<< trim END
358 vim9script
359 def FuncOne(nr: number)
360 echo nr
361 enddef
362 def FuncTwo()
363 FuncOne(1, 2)
364 enddef
365 defcompile
366 END
367 writefile(lines, 'Xscript')
368 didCatch = false
369 try
370 source Xscript
371 catch
372 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
373 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
374 didCatch = true
375 endtry
376 assert_true(didCatch)
377
378 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200379enddef
380
381" Default arg and varargs
382def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200383 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200384 for s in rest
385 res ..= ',' .. s
386 endfor
387 return res
388enddef
389
390def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200391 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200392 MyDefVarargs('one')->assert_equal('one,foo')
393 MyDefVarargs('one', 'two')->assert_equal('one,two')
394 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200395 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200396 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200397 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200398 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200399
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200400 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200401 vim9script
402 def Func(...l: list<string>)
403 echo l
404 enddef
405 Func('a', 'b', 'c')
406 END
407 CheckScriptSuccess(lines)
408
409 lines =<< trim END
410 vim9script
411 def Func(...l: list<string>)
412 echo l
413 enddef
414 Func()
415 END
416 CheckScriptSuccess(lines)
417
418 lines =<< trim END
419 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200420 def Func(...l: any)
421 echo l
422 enddef
423 Func(0)
424 END
425 CheckScriptSuccess(lines)
426
427 lines =<< trim END
428 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200429 def Func(..._l: list<string>)
430 echo _l
431 enddef
432 Func('a', 'b', 'c')
433 END
434 CheckScriptSuccess(lines)
435
436 lines =<< trim END
437 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200438 def Func(...l: list<string>)
439 echo l
440 enddef
441 Func(1, 2, 3)
442 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200443 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200444
445 lines =<< trim END
446 vim9script
447 def Func(...l: list<string>)
448 echo l
449 enddef
450 Func('a', 9)
451 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200452 CheckScriptFailure(lines, 'E1013: Argument 2: 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(1, 'a')
460 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200461 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200462enddef
463
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200464let s:value = ''
465
466def FuncOneDefArg(opt = 'text')
467 s:value = opt
468enddef
469
470def FuncTwoDefArg(nr = 123, opt = 'text'): string
471 return nr .. opt
472enddef
473
474def FuncVarargs(...arg: list<string>): string
475 return join(arg, ',')
476enddef
477
478def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200479 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200480 RefDefArg = FuncOneDefArg
481 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200482 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200483 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200484 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200485
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200486 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200487 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200488 RefDef2Arg()->assert_equal('123text')
489 RefDef2Arg(99)->assert_equal('99text')
490 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200491
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200492 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
493 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200494
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200495 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200496 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200497 RefVarargs()->assert_equal('')
498 RefVarargs('one')->assert_equal('one')
499 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200500
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200501 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
502 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200503enddef
504
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200505" Only varargs
506def MyVarargsOnly(...args: list<string>): string
507 return join(args, ',')
508enddef
509
510def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200511 MyVarargsOnly()->assert_equal('')
512 MyVarargsOnly('one')->assert_equal('one')
513 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200514 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
515 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200516enddef
517
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200518def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200519 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200520 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200521 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200522enddef
523
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200524def DictArg(arg: dict<string>)
525 arg['key'] = 'value'
526enddef
527
528def ListArg(arg: list<string>)
529 arg[0] = 'value'
530enddef
531
532def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200533 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200534 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200535 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200536 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200537 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200538 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200539 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200540
Bram Moolenaard2c61702020-09-06 15:58:36 +0200541 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200542enddef
543
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200544" These argument names are reserved in legacy functions.
545def WithReservedNames(firstline: string, lastline: string): string
546 return firstline .. lastline
547enddef
548
549def Test_argument_names()
550 assert_equal('OK', WithReservedNames('O', 'K'))
551enddef
552
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200553def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200554 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200555 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200556enddef
557
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200558func DefinedLater(arg)
559 return a:arg
560endfunc
561
562def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200563 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200564 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
565 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200566
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200567 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200568 vim9script
569 def RetNumber(): number
570 return 123
571 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200572 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200573 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200574 END
575 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200576
577 lines =<< trim END
578 vim9script
579 def RetNumber(): number
580 return 123
581 enddef
582 def Bar(F: func: number): number
583 return F()
584 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200585 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200586 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200587 END
588 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200589
590 lines =<< trim END
591 vim9script
592 def UseNumber(nr: number)
593 echo nr
594 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200595 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200596 Funcref(123)
597 END
598 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200599
600 lines =<< trim END
601 vim9script
602 def UseNumber(nr: number)
603 echo nr
604 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200605 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200606 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200607 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200608
609 lines =<< trim END
610 vim9script
611 def EchoNr(nr = 34)
612 g:echo = nr
613 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200614 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200615 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200616 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200617 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200618 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200619 END
620 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200621
622 lines =<< trim END
623 vim9script
624 def EchoList(...l: list<number>)
625 g:echo = l
626 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200627 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200628 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200629 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200630 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200631 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200632 END
633 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200634
635 lines =<< trim END
636 vim9script
637 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
638 g:optarg = opt
639 g:listarg = l
640 return nr
641 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200642 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200643 Funcref(10)->assert_equal(10)
644 g:optarg->assert_equal(12)
645 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200646
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200647 Funcref(11, 22)->assert_equal(11)
648 g:optarg->assert_equal(22)
649 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200650
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200651 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
652 g:optarg->assert_equal(18)
653 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200654 END
655 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200656enddef
657
658let SomeFunc = function('len')
659let NotAFunc = 'text'
660
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200661def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200662 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200663 var Ref1: func(bool): string
664 var Ref2: func(bool): number
665 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200666 Ref3 = g:cond ? Ref1 : Ref2
667
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200668 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200669 var Refa1: func(bool): number
670 var Refa2: func(bool, number): number
671 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200672 Refa3 = g:cond ? Refa1 : Refa2
673
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200674 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200675 var Refb1: func(bool, string): number
676 var Refb2: func(string, number): number
677 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200678 Refb3 = g:cond ? Refb1 : Refb2
679enddef
680
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200681def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200682 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200683enddef
684
685def DefinedEvenLater(arg: string): string
686 return arg
687enddef
688
689def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200690 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200691 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200692enddef
693
694def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200695 CheckScriptFailure([
696 'def Func(): number',
697 'return "a"',
698 'enddef',
699 'defcompile'], 'expected number but got string')
700 CheckScriptFailure([
701 'def Func(): string',
702 'return 1',
703 'enddef',
704 'defcompile'], 'expected string but got number')
705 CheckScriptFailure([
706 'def Func(): void',
707 'return "a"',
708 'enddef',
709 'defcompile'],
710 'E1096: Returning a value in a function without a return type')
711 CheckScriptFailure([
712 'def Func()',
713 'return "a"',
714 'enddef',
715 'defcompile'],
716 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200717
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200718 CheckScriptFailure([
719 'def Func(): number',
720 'return',
721 'enddef',
722 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200723
724 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
725 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200726 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200727
728 CheckScriptFailure([
729 'vim9script',
730 'def FuncB()',
731 ' return 123',
732 'enddef',
733 'def FuncA()',
734 ' FuncB()',
735 'enddef',
736 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200737enddef
738
739def Test_arg_type_wrong()
740 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200741 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200742 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200743 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200744enddef
745
746def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200747 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200748 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200749 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200750 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200751 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200752 enddef
753 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200754 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200755
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200756 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200757 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200758 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200759
Bram Moolenaar67979662020-06-20 22:50:47 +0200760 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200761 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200762 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200763
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200764 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200765 def ListFunc(arg: list<number>)
766 listvar = arg
767 enddef
768 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200769 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200770
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200771 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200772 def DictFunc(arg: dict<number>)
773 dictvar = arg
774 enddef
775 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200776 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200777 def CompiledDict()
778 {'a': 3, 'b': 4}->DictFunc()
779 enddef
780 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200781 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200782
783 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200784 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200785
786 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200787 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200788 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200789 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200790
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200791 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200792 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200793 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200794 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200795 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200796 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200797
798 def UseString()
799 'xyork'->MyFunc()
800 enddef
801 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200802 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200803
Bram Moolenaar10409562020-07-29 20:00:38 +0200804 def UseString2()
805 "knife"->MyFunc()
806 enddef
807 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200808 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200809
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200810 # prepending a colon makes it a mark
811 new
812 setline(1, ['aaa', 'bbb', 'ccc'])
813 normal! 3Gmt1G
814 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200815 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200816 bwipe!
817
Bram Moolenaare6b53242020-07-01 17:28:33 +0200818 MyFunc(
819 'continued'
820 )
821 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200822 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200823 )
824
825 call MyFunc(
826 'more'
827 ..
828 'lines'
829 )
830 assert_equal(
831 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200832 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200833 END
834 writefile(lines, 'Xcall.vim')
835 source Xcall.vim
836 delete('Xcall.vim')
837enddef
838
839def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200840 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200841 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200842 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200843 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200844 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200845 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200846 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200847 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200848 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200849enddef
850
Bram Moolenaar65b95452020-07-19 14:03:09 +0200851def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200852 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200853 vim9script
854 def MyFunc(arg: string)
855 echo arg
856 enddef
857 MyFunc(1234)
858 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200859 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200860enddef
861
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200862def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200863 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200864 vim9script
865 const var = ''
866 def MyFunc(arg: string)
867 var = 'asdf'
868 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200869 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200870 END
871 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200872 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200873 delete('Xcall_const.vim')
874enddef
875
876" Test that inside :function a Python function can be defined, :def is not
877" recognized.
878func Test_function_python()
879 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200880 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200881 execute py "<< EOF"
882def do_something():
883 return 1
884EOF
885endfunc
886
887def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200888 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200889 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200890 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200891 echo 'hello'
892 enddef
893
894 def CallGoneSoon()
895 GoneSoon()
896 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200897 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200898
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200899 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200900 CallGoneSoon()
901 END
902 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200903 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
904 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200905
906 delete('XToDelFunc')
907enddef
908
909def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200910 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200911 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200912 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200913 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200914 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200915 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200916 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200917 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200918 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200919
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200920 g:Func0()->assert_equal(0)
921 g:Func1()->assert_equal('Func1')
922 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200923
924 delfunc! Func0
925 delfunc! Func1
926 delfunc! Func2
927enddef
928
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200929def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200930 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200931 vim9script
932 func Func(arg)
933 echo a:arg
934 endfunc
935 Func('text')
936 END
937 writefile(lines, 'XVim9Func')
938 so XVim9Func
939
940 delete('XVim9Func')
941enddef
942
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200943let s:funcResult = 0
944
945def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200946 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200947enddef
948
949def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200950 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200951 return 1234
952enddef
953
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200954def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200955 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200956 return 'text'
957enddef
958
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200959def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200960 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200961enddef
962
963def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200964 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200965 return arg
966enddef
967
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200968def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200969 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200970enddef
971
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200972def FuncOneArgRetString(arg: string): string
973 return arg
974enddef
975
Bram Moolenaar89228602020-04-05 22:14:54 +0200976def FuncOneArgRetAny(arg: any): any
977 return arg
978enddef
979
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200980def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200981 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200982 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200983 Ref1 = FuncNoArgNoRet
984 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200985 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200986
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200987 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200988 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200989 Ref2 = FuncNoArgNoRet
990 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200991 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200992
Bram Moolenaar53900992020-08-22 19:02:02 +0200993 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200994 Ref2 = FuncOneArgNoRet
995 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200996 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200997
Bram Moolenaar53900992020-08-22 19:02:02 +0200998 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200999 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001000 Ref2()->assert_equal(1234)
1001 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001002
Bram Moolenaar53900992020-08-22 19:02:02 +02001003 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001004 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001005 Ref2(13)->assert_equal(13)
1006 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001007enddef
1008
Bram Moolenaar9978d472020-07-05 16:01:56 +02001009def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001010 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001011 for n in repeat([1], 3)
1012 res += n
1013 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001014 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001015
1016 res = 0
1017 for n in add([1, 2], 3)
1018 res += n
1019 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001020 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001021enddef
1022
Bram Moolenaar846178a2020-07-05 17:04:13 +02001023def Test_argv_return_type()
1024 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001025 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001026 for name in argv()
1027 res ..= name
1028 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001029 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001030enddef
1031
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001032def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001033 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001034 RefVoid = FuncNoArgNoRet
1035 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001036 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1037 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001038
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001039 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001040 RefAny = FuncNoArgRetNumber
1041 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001042 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1043 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001044
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001045 var RefAnyNoArgs: func: any = RefAny
1046
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001047 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001048 RefNr = FuncNoArgRetNumber
1049 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001050 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1051 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001052
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001053 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001054 RefStr = FuncNoArgRetString
1055 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001056 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1057 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001058enddef
1059
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001060def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001061 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001062
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001063 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1064 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1065 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1066 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1067 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1068 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 +02001069
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001070 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1071 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1072 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:')
1073 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001074enddef
1075
Bram Moolenaar89228602020-04-05 22:14:54 +02001076def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001077 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001078 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001079 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001080
1081 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001082 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001083
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001084 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001085 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001086 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001087
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001088 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001089enddef
1090
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001091def Test_func_common_type()
1092 def FuncOne(n: number): number
1093 return n
1094 enddef
1095 def FuncTwo(s: string): number
1096 return len(s)
1097 enddef
1098 def FuncThree(n: number, s: string): number
1099 return n + len(s)
1100 enddef
1101 var list = [FuncOne, FuncTwo, FuncThree]
1102 assert_equal(8, list[0](8))
1103 assert_equal(4, list[1]('word'))
1104 assert_equal(7, list[2](3, 'word'))
1105enddef
1106
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001107def MultiLine(
1108 arg1: string,
1109 arg2 = 1234,
1110 ...rest: list<string>
1111 ): string
1112 return arg1 .. arg2 .. join(rest, '-')
1113enddef
1114
Bram Moolenaar2c330432020-04-13 14:41:35 +02001115def MultiLineComment(
1116 arg1: string, # comment
1117 arg2 = 1234, # comment
1118 ...rest: list<string> # comment
1119 ): string # comment
1120 return arg1 .. arg2 .. join(rest, '-')
1121enddef
1122
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001123def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001124 MultiLine('text')->assert_equal('text1234')
1125 MultiLine('text', 777)->assert_equal('text777')
1126 MultiLine('text', 777, 'one')->assert_equal('text777one')
1127 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001128enddef
1129
Bram Moolenaar23e03252020-04-12 22:22:31 +02001130func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001131 call MultiLine('text')->assert_equal('text1234')
1132 call MultiLine('text', 777)->assert_equal('text777')
1133 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1134 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001135endfunc
1136
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001137
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001138" When using CheckScriptFailure() for the below test, E1010 is generated instead
1139" of E1056.
1140func Test_E1056_1059()
1141 let caught_1056 = 0
1142 try
1143 def F():
1144 return 1
1145 enddef
1146 catch /E1056:/
1147 let caught_1056 = 1
1148 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001149 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001150
1151 let caught_1059 = 0
1152 try
1153 def F5(items : list)
1154 echo 'a'
1155 enddef
1156 catch /E1059:/
1157 let caught_1059 = 1
1158 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001159 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001160endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001161
Bram Moolenaar015f4262020-05-05 21:25:22 +02001162func DelMe()
1163 echo 'DelMe'
1164endfunc
1165
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001166def Test_error_reporting()
1167 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001168 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001169 " comment
1170 def Func()
1171 # comment
1172 # comment
1173 invalid
1174 enddef
1175 defcompile
1176 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001177 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001178 try
1179 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001180 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001181 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001182 v:exception->assert_match('Invalid command: invalid')
1183 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001184 endtry
1185
1186 # comment lines after the start of the function
1187 lines =<< trim END
1188 " comment
1189 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001190 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001191 # comment
1192 # comment
1193 invalid
1194 enddef
1195 defcompile
1196 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001197 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001198 try
1199 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001200 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001201 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001202 v:exception->assert_match('Invalid command: invalid')
1203 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001204 endtry
1205
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001206 lines =<< trim END
1207 vim9script
1208 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001209 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001210 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001211 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001212 enddef
1213 defcompile
1214 Func()
1215 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001216 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001217 try
1218 source Xdef
1219 assert_report('should have failed')
1220 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001221 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001222 endtry
1223
Bram Moolenaar08052222020-09-14 17:04:31 +02001224 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001225enddef
1226
Bram Moolenaar015f4262020-05-05 21:25:22 +02001227def Test_deleted_function()
1228 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001229 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001230 'delfunc g:DelMe',
1231 'echo RefMe()'], 'E117:')
1232enddef
1233
1234def Test_unknown_function()
1235 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001236 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001237 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001238enddef
1239
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001240def RefFunc(Ref: func(string): string): string
1241 return Ref('more')
1242enddef
1243
1244def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001245 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001246 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001247enddef
1248
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001249def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001250 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001251 g:Ref = {s -> local .. s}
1252enddef
1253
1254def Test_closure_ref_after_return()
1255 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001256 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001257 unlet g:Ref
1258enddef
1259
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001260def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001261 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001262 g:Extend = {s -> local->add(s)}
1263 g:Read = {-> local}
1264enddef
1265
1266def Test_closure_two_refs()
1267 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001268 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001269 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001270 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001271 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001272 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001273
1274 unlet g:Extend
1275 unlet g:Read
1276enddef
1277
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001278def ReadRef(Ref: func(): list<string>): string
1279 return join(Ref(), ' ')
1280enddef
1281
Bram Moolenaar5e654232020-09-16 15:22:00 +02001282def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001283 Ref(add)
1284enddef
1285
1286def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001287 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001288 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001289 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001290 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001291 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001292 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001293
1294 unlet g:Extend
1295 unlet g:Read
1296enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001297
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001298def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001299 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001300 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1301enddef
1302
1303def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001304 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001305 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1306enddef
1307
1308def Test_closure_using_argument()
1309 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001310 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001311
1312 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001313 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001314
1315 unlet g:UseArg
1316 unlet g:UseVararg
1317enddef
1318
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001319def MakeGetAndAppendRefs()
1320 var local = 'a'
1321
1322 def Append(arg: string)
1323 local ..= arg
1324 enddef
1325 g:Append = Append
1326
1327 def Get(): string
1328 return local
1329 enddef
1330 g:Get = Get
1331enddef
1332
1333def Test_closure_append_get()
1334 MakeGetAndAppendRefs()
1335 g:Get()->assert_equal('a')
1336 g:Append('-b')
1337 g:Get()->assert_equal('a-b')
1338 g:Append('-c')
1339 g:Get()->assert_equal('a-b-c')
1340
1341 unlet g:Append
1342 unlet g:Get
1343enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001344
Bram Moolenaar04b12692020-05-04 23:24:44 +02001345def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001346 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001347 def Closure(arg: string): string
1348 return local .. arg
1349 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001350 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001351enddef
1352
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001353func GetResult(Ref)
1354 return a:Ref('some')
1355endfunc
1356
1357def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001358 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001359 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001360 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001361enddef
1362
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001363def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001364 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001365 vim9script
1366 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001367 var name = 0
1368 for i in range(2)
1369 timer_start(0, {-> name})
1370 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001371 enddef
1372 Func()
1373 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001374 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001375enddef
1376
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001377def Test_nested_closure_used()
1378 var lines =<< trim END
1379 vim9script
1380 def Func()
1381 var x = 'hello'
1382 var Closure = {-> x}
1383 g:Myclosure = {-> Closure()}
1384 enddef
1385 Func()
1386 assert_equal('hello', g:Myclosure())
1387 END
1388 CheckScriptSuccess(lines)
1389enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001390
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001391def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001392 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001393 vim9script
1394 def FuncA()
1395 FuncB(0)
1396 enddef
1397 def FuncB(n: number): list<string>
1398 return map([0], {_, v -> n})
1399 enddef
1400 FuncA()
1401 END
1402 CheckScriptFailure(lines, 'E1012:')
1403enddef
1404
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001405def Test_nested_lambda()
1406 var lines =<< trim END
1407 vim9script
1408 def Func()
1409 var x = 4
1410 var Lambda1 = {-> 7}
1411 var Lambda2 = {-> [Lambda1(), x]}
1412 var res = Lambda2()
1413 assert_equal([7, 4], res)
1414 enddef
1415 Func()
1416 END
1417 CheckScriptSuccess(lines)
1418enddef
1419
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001420def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001421 var path: string = empty(dir)
1422 \ ? 'empty'
1423 \ : 'full'
1424 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001425enddef
1426
1427def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001428 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001429enddef
1430
Bram Moolenaar5e654232020-09-16 15:22:00 +02001431def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001432 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001433 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001434 ->toupper()})
1435 ->reverse()
1436 return x
1437enddef
1438
1439def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001440 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001441enddef
1442
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001443func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001444 CheckScreendump
1445
1446 let lines =<< trim END
1447 vim9script
1448 def EchoNothing()
1449 silent echo ''
1450 enddef
1451 defcompile
1452 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001453 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001454
1455 " Check that the balloon shows up after a mouse move
1456 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001457 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001458 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1459
1460 " clean up
1461 call StopVimInTerminal(buf)
1462 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001463endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001464
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001465def Fibonacci(n: number): number
1466 if n < 2
1467 return n
1468 else
1469 return Fibonacci(n - 1) + Fibonacci(n - 2)
1470 endif
1471enddef
1472
Bram Moolenaar985116a2020-07-12 17:31:09 +02001473def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001474 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001475enddef
1476
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001477def TreeWalk(dir: string): list<any>
1478 return readdir(dir)->map({_, val ->
1479 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001480 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001481 : val
1482 })
1483enddef
1484
1485def Test_closure_in_map()
1486 mkdir('XclosureDir/tdir', 'p')
1487 writefile(['111'], 'XclosureDir/file1')
1488 writefile(['222'], 'XclosureDir/file2')
1489 writefile(['333'], 'XclosureDir/tdir/file3')
1490
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001491 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001492
1493 delete('XclosureDir', 'rf')
1494enddef
1495
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001496def Test_invalid_function_name()
1497 var lines =<< trim END
1498 vim9script
1499 def s: list<string>
1500 END
1501 CheckScriptFailure(lines, 'E129:')
1502
1503 lines =<< trim END
1504 vim9script
1505 def g: list<string>
1506 END
1507 CheckScriptFailure(lines, 'E129:')
1508
1509 lines =<< trim END
1510 vim9script
1511 def <SID>: list<string>
1512 END
1513 CheckScriptFailure(lines, 'E884:')
1514
1515 lines =<< trim END
1516 vim9script
1517 def F list<string>
1518 END
1519 CheckScriptFailure(lines, 'E488:')
1520enddef
1521
Bram Moolenaara90afb92020-07-15 22:38:56 +02001522def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001523 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02001524 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001525 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001526
1527 Xsetlist = function('setloclist', [0, [], ' '])
1528 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001529 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001530
1531 Xsetlist = function('setqflist')
1532 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001533 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001534
1535 Xsetlist = function('setqflist', [[], ' '])
1536 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001537 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001538
1539 var Len: func: number = function('len', ['word'])
1540 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001541enddef
1542
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001543def Test_cmd_modifier()
1544 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001545 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001546enddef
1547
1548def Test_restore_modifiers()
1549 # check that when compiling a :def function command modifiers are not messed
1550 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001551 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001552 vim9script
1553 set eventignore=
1554 autocmd QuickFixCmdPost * copen
1555 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001556 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001557 enddef
1558 func Func()
1559 noautocmd call s:AutocmdsDisabled()
1560 let g:ei_after = &eventignore
1561 endfunc
1562 Func()
1563 END
1564 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001565 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001566enddef
1567
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001568def StackTop()
1569 eval 1
1570 eval 2
1571 # call not on fourth line
1572 StackBot()
1573enddef
1574
1575def StackBot()
1576 # throw an error
1577 eval [][0]
1578enddef
1579
1580def Test_callstack_def()
1581 try
1582 StackTop()
1583 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001584 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001585 endtry
1586enddef
1587
Bram Moolenaare8211a32020-10-09 22:04:29 +02001588" Re-using spot for variable used in block
1589def Test_block_scoped_var()
1590 var lines =<< trim END
1591 vim9script
1592 def Func()
1593 var x = ['a', 'b', 'c']
1594 if 1
1595 var y = 'x'
1596 map(x, {-> y})
1597 endif
1598 var z = x
1599 assert_equal(['x', 'x', 'x'], z)
1600 enddef
1601 Func()
1602 END
1603 CheckScriptSuccess(lines)
1604enddef
1605
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001606
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001607" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker