blob: 86b57f3c13a715c23834b374e36ae3320f8e52ba [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',
Bram Moolenaare0de1712020-12-02 17:36:54 +010033 {rows: 10, wait_for_ruler: 0})
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020034 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
Bram Moolenaar18dc3552020-11-22 14:24:00 +010040 if text =~ 'Variable not found: nothing'
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020041 break
42 endif
43 sleep 20m
44 endfor
45 assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text)
46
47 # clean up
48 call StopVimInTerminal(buf)
49 call delete('XTest_compile_error')
50enddef
51
Bram Moolenaar0ba48e82020-11-17 18:23:19 +010052def CallRecursive(n: number): number
53 return CallRecursive(n + 1)
54enddef
55
56def CallMapRecursive(l: list<number>): number
57 return map(l, {_, v -> CallMapRecursive([v])})[0]
58enddef
59
60def Test_funcdepth_error()
61 set maxfuncdepth=10
62
63 var caught = false
64 try
65 CallRecursive(1)
66 catch /E132:/
67 caught = true
68 endtry
69 assert_true(caught)
70
71 caught = false
72 try
73 CallMapRecursive([1])
74 catch /E132:/
75 caught = true
76 endtry
77 assert_true(caught)
78
79 set maxfuncdepth&
80enddef
81
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020082def ReturnString(): string
83 return 'string'
84enddef
85
86def ReturnNumber(): number
87 return 123
88enddef
89
90let g:notNumber = 'string'
91
92def ReturnGlobal(): number
93 return g:notNumber
94enddef
95
96def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020097 ReturnString()->assert_equal('string')
98 ReturnNumber()->assert_equal(123)
Bram Moolenaar5e654232020-09-16 15:22:00 +020099 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200100enddef
101
Bram Moolenaarefd88552020-06-18 20:50:10 +0200102def Test_missing_return()
103 CheckDefFailure(['def Missing(): number',
104 ' if g:cond',
105 ' echo "no return"',
106 ' else',
107 ' return 0',
108 ' endif'
109 'enddef'], 'E1027:')
110 CheckDefFailure(['def Missing(): number',
111 ' if g:cond',
112 ' return 1',
113 ' else',
114 ' echo "no return"',
115 ' endif'
116 'enddef'], 'E1027:')
117 CheckDefFailure(['def Missing(): number',
118 ' if g:cond',
119 ' return 1',
120 ' else',
121 ' return 2',
122 ' endif'
123 ' return 3'
124 'enddef'], 'E1095:')
125enddef
126
Bram Moolenaar403dc312020-10-17 19:29:51 +0200127def Test_return_bool()
128 var lines =<< trim END
129 vim9script
130 def MenuFilter(id: number, key: string): bool
131 return popup_filter_menu(id, key)
132 enddef
133 def YesnoFilter(id: number, key: string): bool
134 return popup_filter_yesno(id, key)
135 enddef
136 defcompile
137 END
138 CheckScriptSuccess(lines)
139enddef
140
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200141let s:nothing = 0
142def ReturnNothing()
143 s:nothing = 1
144 if true
145 return
146 endif
147 s:nothing = 2
148enddef
149
150def Test_return_nothing()
151 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200152 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200153enddef
154
155func Increment()
156 let g:counter += 1
157endfunc
158
159def Test_call_ufunc_count()
160 g:counter = 1
161 Increment()
162 Increment()
163 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200164 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200165 g:counter->assert_equal(4)
166 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200167 unlet g:counter
168enddef
169
170def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200171 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200172 for s in rest
173 res ..= ',' .. s
174 endfor
175 return res
176enddef
177
178def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200179 MyVarargs('one')->assert_equal('one')
180 MyVarargs('one', 'two')->assert_equal('one,two')
181 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200182enddef
183
184def MyDefaultArgs(name = 'string'): string
185 return name
186enddef
187
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200188def MyDefaultSecond(name: string, second: bool = true): string
189 return second ? name : 'none'
190enddef
191
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200192def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200193 MyDefaultArgs()->assert_equal('string')
194 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200195 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200196
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200197 MyDefaultSecond('test')->assert_equal('test')
198 MyDefaultSecond('test', true)->assert_equal('test')
199 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200200
Bram Moolenaar822ba242020-05-24 23:00:18 +0200201 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar77072282020-09-16 17:55:40 +0200202 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200203enddef
204
205def Test_nested_function()
206 def Nested(arg: string): string
207 return 'nested ' .. arg
208 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200209 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200210
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200211 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
212 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
213
Bram Moolenaar04b12692020-05-04 23:24:44 +0200214 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200215 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
216 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200217
218 CheckDefFailure([
219 'def Outer()',
220 ' def Inner()',
221 ' # comment',
222 ' enddef',
223 ' def Inner()',
224 ' enddef',
225 'enddef'], 'E1073:')
226 CheckDefFailure([
227 'def Outer()',
228 ' def Inner()',
229 ' # comment',
230 ' enddef',
231 ' def! Inner()',
232 ' enddef',
233 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200234enddef
235
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200236func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200237 call MyDefaultArgs()->assert_equal('string')
238 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200239 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200240endfunc
241
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200242def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200243 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200244 vim9script
245 def Outer()
246 def g:Inner(): string
247 return 'inner'
248 enddef
249 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200250 defcompile
251 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200252 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200253 delfunc g:Inner
254 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200255 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200256 delfunc g:Inner
257 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200258 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200259 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200260 END
261 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200262
263 lines =<< trim END
264 vim9script
265 def Outer()
266 def g:Inner(): string
267 return 'inner'
268 enddef
269 enddef
270 defcompile
271 Outer()
272 Outer()
273 END
274 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200275
276 lines =<< trim END
277 vim9script
278 def Func()
279 echo 'script'
280 enddef
281 def Outer()
282 def Func()
283 echo 'inner'
284 enddef
285 enddef
286 defcompile
287 END
288 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200289enddef
290
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100291def DefListAll()
292 def
293enddef
294
295def DefListOne()
296 def DefListOne
297enddef
298
299def DefListMatches()
300 def /DefList
301enddef
302
303def Test_nested_def_list()
304 var funcs = split(execute('call DefListAll()'), "\n")
305 assert_true(len(funcs) > 10)
306 assert_true(funcs->index('def DefListAll()') >= 0)
307
308 funcs = split(execute('call DefListOne()'), "\n")
309 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
310
311 funcs = split(execute('call DefListMatches()'), "\n")
312 assert_true(len(funcs) >= 3)
313 assert_true(funcs->index('def DefListAll()') >= 0)
314 assert_true(funcs->index('def DefListOne()') >= 0)
315 assert_true(funcs->index('def DefListMatches()') >= 0)
316enddef
317
Bram Moolenaar333894b2020-08-01 18:53:07 +0200318def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200319 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200320 vim9script
321 def g:Func(): string
322 return 'global'
323 enddef
324 def Func(): string
325 return 'local'
326 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200327 g:Func()->assert_equal('global')
328 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200329 END
330 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200331
332 lines =<< trim END
333 vim9script
334 def g:Funcy()
335 echo 'funcy'
336 enddef
337 s:Funcy()
338 END
339 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200340enddef
341
Bram Moolenaar0f769812020-09-12 18:32:34 +0200342def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200343 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200344 vim9script
345 def g:Gfunc(): string
346 return 'global'
347 enddef
348 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200349 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200350 return Gfunc('testing')
351 enddef
352 g:Gfunc()->assert_equal('global')
353 AnotherFunc()->assert_equal(7)
354 delfunc g:Gfunc
355 END
356 CheckScriptSuccess(lines)
357
358 lines =<< trim END
359 vim9script
360 def g:Func(): string
361 return 'global'
362 enddef
363 def AnotherFunc()
364 g:Func = function('len')
365 enddef
366 AnotherFunc()
367 END
368 CheckScriptFailure(lines, 'E705:')
369 delfunc g:Func
370enddef
371
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200372func TakesOneArg(arg)
373 echo a:arg
374endfunc
375
376def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200377 CheckDefFailure(['TakesOneArg()'], 'E119:')
378 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
379 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
380 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200381
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200382 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200383 vim9script
384 def Func(s: string)
385 echo s
386 enddef
387 Func([])
388 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200389 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200390
391 lines =<< trim END
392 vim9script
393 def FuncOne(nr: number)
394 echo nr
395 enddef
396 def FuncTwo()
397 FuncOne()
398 enddef
399 defcompile
400 END
401 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200402 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200403 try
404 source Xscript
405 catch
406 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
407 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
408 didCatch = true
409 endtry
410 assert_true(didCatch)
411
412 lines =<< trim END
413 vim9script
414 def FuncOne(nr: number)
415 echo nr
416 enddef
417 def FuncTwo()
418 FuncOne(1, 2)
419 enddef
420 defcompile
421 END
422 writefile(lines, 'Xscript')
423 didCatch = false
424 try
425 source Xscript
426 catch
427 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
428 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
429 didCatch = true
430 endtry
431 assert_true(didCatch)
432
433 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200434enddef
435
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100436def Test_call_lambda_args()
437 CheckDefFailure(['echo {i -> 0}()'],
438 'E119: Not enough arguments for function: {i -> 0}()')
439
440 var lines =<< trim END
441 var Ref = {x: number, y: number -> x + y}
442 echo Ref(1, 'x')
443 END
444 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
445enddef
446
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200447" Default arg and varargs
448def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200449 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200450 for s in rest
451 res ..= ',' .. s
452 endfor
453 return res
454enddef
455
456def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200457 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200458 MyDefVarargs('one')->assert_equal('one,foo')
459 MyDefVarargs('one', 'two')->assert_equal('one,two')
460 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200461 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200462 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200463 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200464 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200465
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200466 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200467 vim9script
468 def Func(...l: list<string>)
469 echo l
470 enddef
471 Func('a', 'b', 'c')
472 END
473 CheckScriptSuccess(lines)
474
475 lines =<< trim END
476 vim9script
477 def Func(...l: list<string>)
478 echo l
479 enddef
480 Func()
481 END
482 CheckScriptSuccess(lines)
483
484 lines =<< trim END
485 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200486 def Func(...l: any)
487 echo l
488 enddef
489 Func(0)
490 END
491 CheckScriptSuccess(lines)
492
493 lines =<< trim END
494 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200495 def Func(..._l: list<string>)
496 echo _l
497 enddef
498 Func('a', 'b', 'c')
499 END
500 CheckScriptSuccess(lines)
501
502 lines =<< trim END
503 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200504 def Func(...l: list<string>)
505 echo l
506 enddef
507 Func(1, 2, 3)
508 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200509 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200510
511 lines =<< trim END
512 vim9script
513 def Func(...l: list<string>)
514 echo l
515 enddef
516 Func('a', 9)
517 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200518 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200519
520 lines =<< trim END
521 vim9script
522 def Func(...l: list<string>)
523 echo l
524 enddef
525 Func(1, 'a')
526 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200527 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200528enddef
529
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200530let s:value = ''
531
532def FuncOneDefArg(opt = 'text')
533 s:value = opt
534enddef
535
536def FuncTwoDefArg(nr = 123, opt = 'text'): string
537 return nr .. opt
538enddef
539
540def FuncVarargs(...arg: list<string>): string
541 return join(arg, ',')
542enddef
543
544def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200545 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200546 RefDefArg = FuncOneDefArg
547 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200548 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200549 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200550 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200551
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200552 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200553 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200554 RefDef2Arg()->assert_equal('123text')
555 RefDef2Arg(99)->assert_equal('99text')
556 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200557
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200558 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
559 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200560
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200561 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200562 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200563 RefVarargs()->assert_equal('')
564 RefVarargs('one')->assert_equal('one')
565 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200566
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200567 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
568 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200569enddef
570
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200571" Only varargs
572def MyVarargsOnly(...args: list<string>): string
573 return join(args, ',')
574enddef
575
576def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200577 MyVarargsOnly()->assert_equal('')
578 MyVarargsOnly('one')->assert_equal('one')
579 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200580 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
581 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200582enddef
583
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200584def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200585 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200586 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200587 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200588enddef
589
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200590def DictArg(arg: dict<string>)
591 arg['key'] = 'value'
592enddef
593
594def ListArg(arg: list<string>)
595 arg[0] = 'value'
596enddef
597
598def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200599 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200600 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200601 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200602 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200603 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200604 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200605 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200606
Bram Moolenaard2c61702020-09-06 15:58:36 +0200607 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200608enddef
609
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200610" These argument names are reserved in legacy functions.
611def WithReservedNames(firstline: string, lastline: string): string
612 return firstline .. lastline
613enddef
614
615def Test_argument_names()
616 assert_equal('OK', WithReservedNames('O', 'K'))
617enddef
618
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200619def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200620 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200621 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200622enddef
623
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200624func DefinedLater(arg)
625 return a:arg
626endfunc
627
628def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200629 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200630 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
631 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200632
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200633 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200634 vim9script
635 def RetNumber(): number
636 return 123
637 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200638 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200639 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200640 END
641 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200642
643 lines =<< trim END
644 vim9script
645 def RetNumber(): number
646 return 123
647 enddef
648 def Bar(F: func: number): number
649 return F()
650 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200651 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200652 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200653 END
654 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200655
656 lines =<< trim END
657 vim9script
658 def UseNumber(nr: number)
659 echo nr
660 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200661 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200662 Funcref(123)
663 END
664 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200665
666 lines =<< trim END
667 vim9script
668 def UseNumber(nr: number)
669 echo nr
670 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200671 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200672 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200673 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200674
675 lines =<< trim END
676 vim9script
677 def EchoNr(nr = 34)
678 g:echo = nr
679 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200680 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200681 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200682 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200683 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200684 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200685 END
686 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200687
688 lines =<< trim END
689 vim9script
690 def EchoList(...l: list<number>)
691 g:echo = l
692 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200693 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200694 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200695 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200696 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200697 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200698 END
699 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200700
701 lines =<< trim END
702 vim9script
703 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
704 g:optarg = opt
705 g:listarg = l
706 return nr
707 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200708 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200709 Funcref(10)->assert_equal(10)
710 g:optarg->assert_equal(12)
711 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200712
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200713 Funcref(11, 22)->assert_equal(11)
714 g:optarg->assert_equal(22)
715 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200716
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200717 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
718 g:optarg->assert_equal(18)
719 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200720 END
721 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200722enddef
723
724let SomeFunc = function('len')
725let NotAFunc = 'text'
726
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200727def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200728 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200729 var Ref1: func(bool): string
730 var Ref2: func(bool): number
731 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200732 Ref3 = g:cond ? Ref1 : Ref2
733
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200734 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200735 var Refa1: func(bool): number
736 var Refa2: func(bool, number): number
737 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200738 Refa3 = g:cond ? Refa1 : Refa2
739
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200740 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200741 var Refb1: func(bool, string): number
742 var Refb2: func(string, number): number
743 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200744 Refb3 = g:cond ? Refb1 : Refb2
745enddef
746
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200747def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200748 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200749enddef
750
751def DefinedEvenLater(arg: string): string
752 return arg
753enddef
754
755def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200756 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200757 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200758enddef
759
760def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200761 CheckScriptFailure([
762 'def Func(): number',
763 'return "a"',
764 'enddef',
765 'defcompile'], 'expected number but got string')
766 CheckScriptFailure([
767 'def Func(): string',
768 'return 1',
769 'enddef',
770 'defcompile'], 'expected string but got number')
771 CheckScriptFailure([
772 'def Func(): void',
773 'return "a"',
774 'enddef',
775 'defcompile'],
776 'E1096: Returning a value in a function without a return type')
777 CheckScriptFailure([
778 'def Func()',
779 'return "a"',
780 'enddef',
781 'defcompile'],
782 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200783
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200784 CheckScriptFailure([
785 'def Func(): number',
786 'return',
787 'enddef',
788 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200789
790 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
791 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200792 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200793
794 CheckScriptFailure([
795 'vim9script',
796 'def FuncB()',
797 ' return 123',
798 'enddef',
799 'def FuncA()',
800 ' FuncB()',
801 'enddef',
802 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200803enddef
804
805def Test_arg_type_wrong()
806 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200807 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200808 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200809 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200810enddef
811
812def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200813 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200814 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200815 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200816 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200817 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200818 enddef
819 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200820 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200821
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200822 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200823 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200824 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200825
Bram Moolenaar67979662020-06-20 22:50:47 +0200826 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200827 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200828 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200829
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200830 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200831 def ListFunc(arg: list<number>)
832 listvar = arg
833 enddef
834 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200835 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200836
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200837 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200838 def DictFunc(arg: dict<number>)
839 dictvar = arg
840 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +0100841 {a: 1, b: 2}->DictFunc()
842 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200843 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100844 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200845 enddef
846 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100847 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200848
Bram Moolenaare0de1712020-12-02 17:36:54 +0100849 {a: 3, b: 4}->DictFunc()
850 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200851
852 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200853 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200854 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200855 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200856
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200857 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200858 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200859 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200860 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200861 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200862 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200863
864 def UseString()
865 'xyork'->MyFunc()
866 enddef
867 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200868 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200869
Bram Moolenaar10409562020-07-29 20:00:38 +0200870 def UseString2()
871 "knife"->MyFunc()
872 enddef
873 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200874 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200875
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200876 # prepending a colon makes it a mark
877 new
878 setline(1, ['aaa', 'bbb', 'ccc'])
879 normal! 3Gmt1G
880 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200881 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200882 bwipe!
883
Bram Moolenaare6b53242020-07-01 17:28:33 +0200884 MyFunc(
885 'continued'
886 )
887 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200888 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200889 )
890
891 call MyFunc(
892 'more'
893 ..
894 'lines'
895 )
896 assert_equal(
897 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200898 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200899 END
900 writefile(lines, 'Xcall.vim')
901 source Xcall.vim
902 delete('Xcall.vim')
903enddef
904
905def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200906 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200907 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200908 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200910 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200911 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200912 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200913 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200914 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200915enddef
916
Bram Moolenaar65b95452020-07-19 14:03:09 +0200917def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200918 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200919 vim9script
920 def MyFunc(arg: string)
921 echo arg
922 enddef
923 MyFunc(1234)
924 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200925 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200926enddef
927
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200928def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200929 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200930 vim9script
931 const var = ''
932 def MyFunc(arg: string)
933 var = 'asdf'
934 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200935 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200936 END
937 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200938 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200939 delete('Xcall_const.vim')
940enddef
941
942" Test that inside :function a Python function can be defined, :def is not
943" recognized.
944func Test_function_python()
945 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200946 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200947 execute py "<< EOF"
948def do_something():
949 return 1
950EOF
951endfunc
952
953def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200954 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200955 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200956 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200957 echo 'hello'
958 enddef
959
960 def CallGoneSoon()
961 GoneSoon()
962 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200963 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200964
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200965 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200966 CallGoneSoon()
967 END
968 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200969 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
970 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200971
972 delete('XToDelFunc')
973enddef
974
975def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200976 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200977 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200978 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200979 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200980 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200981 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200982 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200983 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200984 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200985
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200986 g:Func0()->assert_equal(0)
987 g:Func1()->assert_equal('Func1')
988 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200989
990 delfunc! Func0
991 delfunc! Func1
992 delfunc! Func2
993enddef
994
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200995def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200996 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200997 vim9script
998 func Func(arg)
999 echo a:arg
1000 endfunc
1001 Func('text')
1002 END
1003 writefile(lines, 'XVim9Func')
1004 so XVim9Func
1005
1006 delete('XVim9Func')
1007enddef
1008
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001009let s:funcResult = 0
1010
1011def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001012 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001013enddef
1014
1015def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001016 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001017 return 1234
1018enddef
1019
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001020def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001021 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001022 return 'text'
1023enddef
1024
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001025def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001026 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001027enddef
1028
1029def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001030 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001031 return arg
1032enddef
1033
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001034def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001035 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001036enddef
1037
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001038def FuncOneArgRetString(arg: string): string
1039 return arg
1040enddef
1041
Bram Moolenaar89228602020-04-05 22:14:54 +02001042def FuncOneArgRetAny(arg: any): any
1043 return arg
1044enddef
1045
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001046def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001047 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001048 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001049 Ref1 = FuncNoArgNoRet
1050 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001051 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001052
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001053 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001054 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001055 Ref2 = FuncNoArgNoRet
1056 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001057 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001058
Bram Moolenaar53900992020-08-22 19:02:02 +02001059 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001060 Ref2 = FuncOneArgNoRet
1061 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001062 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001063
Bram Moolenaar53900992020-08-22 19:02:02 +02001064 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001065 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001066 Ref2()->assert_equal(1234)
1067 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001068
Bram Moolenaar53900992020-08-22 19:02:02 +02001069 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001070 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001071 Ref2(13)->assert_equal(13)
1072 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001073enddef
1074
Bram Moolenaar9978d472020-07-05 16:01:56 +02001075def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001076 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001077 for n in repeat([1], 3)
1078 res += n
1079 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001080 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001081
1082 res = 0
1083 for n in add([1, 2], 3)
1084 res += n
1085 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001086 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001087enddef
1088
Bram Moolenaar846178a2020-07-05 17:04:13 +02001089def Test_argv_return_type()
1090 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001091 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001092 for name in argv()
1093 res ..= name
1094 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001095 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001096enddef
1097
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001098def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001099 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001100 RefVoid = FuncNoArgNoRet
1101 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001102 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1103 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001104
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001105 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001106 RefAny = FuncNoArgRetNumber
1107 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001108 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1109 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001110
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001111 var RefAnyNoArgs: func: any = RefAny
1112
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001113 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001114 RefNr = FuncNoArgRetNumber
1115 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001116 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1117 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001118
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001119 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001120 RefStr = FuncNoArgRetString
1121 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001122 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1123 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001124enddef
1125
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001126def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001127 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001128
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001129 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1130 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1131 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1132 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1133 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1134 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 +02001135
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001136 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1137 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1138 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:')
1139 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001140enddef
1141
Bram Moolenaar89228602020-04-05 22:14:54 +02001142def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001143 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001144 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001145 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001146
1147 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001148 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001149
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001150 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001151 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001152 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001153
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001154 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001155enddef
1156
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001157def Test_func_common_type()
1158 def FuncOne(n: number): number
1159 return n
1160 enddef
1161 def FuncTwo(s: string): number
1162 return len(s)
1163 enddef
1164 def FuncThree(n: number, s: string): number
1165 return n + len(s)
1166 enddef
1167 var list = [FuncOne, FuncTwo, FuncThree]
1168 assert_equal(8, list[0](8))
1169 assert_equal(4, list[1]('word'))
1170 assert_equal(7, list[2](3, 'word'))
1171enddef
1172
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001173def MultiLine(
1174 arg1: string,
1175 arg2 = 1234,
1176 ...rest: list<string>
1177 ): string
1178 return arg1 .. arg2 .. join(rest, '-')
1179enddef
1180
Bram Moolenaar2c330432020-04-13 14:41:35 +02001181def MultiLineComment(
1182 arg1: string, # comment
1183 arg2 = 1234, # comment
1184 ...rest: list<string> # comment
1185 ): string # comment
1186 return arg1 .. arg2 .. join(rest, '-')
1187enddef
1188
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001189def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001190 MultiLine('text')->assert_equal('text1234')
1191 MultiLine('text', 777)->assert_equal('text777')
1192 MultiLine('text', 777, 'one')->assert_equal('text777one')
1193 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001194enddef
1195
Bram Moolenaar23e03252020-04-12 22:22:31 +02001196func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001197 call MultiLine('text')->assert_equal('text1234')
1198 call MultiLine('text', 777)->assert_equal('text777')
1199 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1200 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001201endfunc
1202
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001203
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001204" When using CheckScriptFailure() for the below test, E1010 is generated instead
1205" of E1056.
1206func Test_E1056_1059()
1207 let caught_1056 = 0
1208 try
1209 def F():
1210 return 1
1211 enddef
1212 catch /E1056:/
1213 let caught_1056 = 1
1214 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001215 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001216
1217 let caught_1059 = 0
1218 try
1219 def F5(items : list)
1220 echo 'a'
1221 enddef
1222 catch /E1059:/
1223 let caught_1059 = 1
1224 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001225 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001226endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001227
Bram Moolenaar015f4262020-05-05 21:25:22 +02001228func DelMe()
1229 echo 'DelMe'
1230endfunc
1231
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001232def Test_error_reporting()
1233 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001234 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001235 " comment
1236 def Func()
1237 # comment
1238 # comment
1239 invalid
1240 enddef
1241 defcompile
1242 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001243 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001244 try
1245 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001246 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001247 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001248 v:exception->assert_match('Invalid command: invalid')
1249 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001250 endtry
1251
1252 # comment lines after the start of the function
1253 lines =<< trim END
1254 " comment
1255 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001256 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001257 # comment
1258 # comment
1259 invalid
1260 enddef
1261 defcompile
1262 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001263 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001264 try
1265 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001266 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001267 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001268 v:exception->assert_match('Invalid command: invalid')
1269 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001270 endtry
1271
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001272 lines =<< trim END
1273 vim9script
1274 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001275 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001276 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001277 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001278 enddef
1279 defcompile
1280 Func()
1281 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001282 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001283 try
1284 source Xdef
1285 assert_report('should have failed')
1286 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001287 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001288 endtry
1289
Bram Moolenaar08052222020-09-14 17:04:31 +02001290 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001291enddef
1292
Bram Moolenaar015f4262020-05-05 21:25:22 +02001293def Test_deleted_function()
1294 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001295 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001296 'delfunc g:DelMe',
1297 'echo RefMe()'], 'E117:')
1298enddef
1299
1300def Test_unknown_function()
1301 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001302 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001303 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001304enddef
1305
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001306def RefFunc(Ref: func(string): string): string
1307 return Ref('more')
1308enddef
1309
1310def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001311 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001312 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001313enddef
1314
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001315def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001316 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001317 g:Ref = {s -> local .. s}
1318enddef
1319
1320def Test_closure_ref_after_return()
1321 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001322 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001323 unlet g:Ref
1324enddef
1325
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001326def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001327 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001328 g:Extend = {s -> local->add(s)}
1329 g:Read = {-> local}
1330enddef
1331
1332def Test_closure_two_refs()
1333 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001334 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001335 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001336 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001337 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001338 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001339
1340 unlet g:Extend
1341 unlet g:Read
1342enddef
1343
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001344def ReadRef(Ref: func(): list<string>): string
1345 return join(Ref(), ' ')
1346enddef
1347
Bram Moolenaar5e654232020-09-16 15:22:00 +02001348def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001349 Ref(add)
1350enddef
1351
1352def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001353 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001354 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001355 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001356 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001357 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001358 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001359
1360 unlet g:Extend
1361 unlet g:Read
1362enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001363
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001364def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001365 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001366 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1367enddef
1368
1369def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001370 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001371 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1372enddef
1373
1374def Test_closure_using_argument()
1375 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001376 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001377
1378 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001379 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001380
1381 unlet g:UseArg
1382 unlet g:UseVararg
1383enddef
1384
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001385def MakeGetAndAppendRefs()
1386 var local = 'a'
1387
1388 def Append(arg: string)
1389 local ..= arg
1390 enddef
1391 g:Append = Append
1392
1393 def Get(): string
1394 return local
1395 enddef
1396 g:Get = Get
1397enddef
1398
1399def Test_closure_append_get()
1400 MakeGetAndAppendRefs()
1401 g:Get()->assert_equal('a')
1402 g:Append('-b')
1403 g:Get()->assert_equal('a-b')
1404 g:Append('-c')
1405 g:Get()->assert_equal('a-b-c')
1406
1407 unlet g:Append
1408 unlet g:Get
1409enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001410
Bram Moolenaar04b12692020-05-04 23:24:44 +02001411def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001412 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001413 def Closure(arg: string): string
1414 return local .. arg
1415 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001416 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001417enddef
1418
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001419func GetResult(Ref)
1420 return a:Ref('some')
1421endfunc
1422
1423def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001424 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001425 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001426 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001427enddef
1428
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001429def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001430 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001431 vim9script
1432 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001433 var name = 0
1434 for i in range(2)
1435 timer_start(0, {-> name})
1436 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001437 enddef
1438 Func()
1439 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001440 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001441enddef
1442
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001443def Test_nested_closure_used()
1444 var lines =<< trim END
1445 vim9script
1446 def Func()
1447 var x = 'hello'
1448 var Closure = {-> x}
1449 g:Myclosure = {-> Closure()}
1450 enddef
1451 Func()
1452 assert_equal('hello', g:Myclosure())
1453 END
1454 CheckScriptSuccess(lines)
1455enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001456
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001457def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001458 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001459 vim9script
1460 def FuncA()
1461 FuncB(0)
1462 enddef
1463 def FuncB(n: number): list<string>
1464 return map([0], {_, v -> n})
1465 enddef
1466 FuncA()
1467 END
1468 CheckScriptFailure(lines, 'E1012:')
1469enddef
1470
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01001471def Test_failure_in_called_function()
1472 # this was using the frame index as the return value
1473 var lines =<< trim END
1474 vim9script
1475 au TerminalWinOpen * eval [][0]
1476 def PopupTerm(a: any)
1477 # make sure typvals on stack are string
1478 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1479 FireEvent()
1480 enddef
1481 def FireEvent()
1482 do TerminalWinOpen
1483 enddef
1484 # use try/catch to make eval fail
1485 try
1486 call PopupTerm(0)
1487 catch
1488 endtry
1489 au! TerminalWinOpen
1490 END
1491 CheckScriptSuccess(lines)
1492enddef
1493
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001494def Test_nested_lambda()
1495 var lines =<< trim END
1496 vim9script
1497 def Func()
1498 var x = 4
1499 var Lambda1 = {-> 7}
1500 var Lambda2 = {-> [Lambda1(), x]}
1501 var res = Lambda2()
1502 assert_equal([7, 4], res)
1503 enddef
1504 Func()
1505 END
1506 CheckScriptSuccess(lines)
1507enddef
1508
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001509def Shadowed(): list<number>
1510 var FuncList: list<func: number> = [{ -> 42}]
1511 return FuncList->map({_, Shadowed -> Shadowed()})
1512enddef
1513
1514def Test_lambda_arg_shadows_func()
1515 assert_equal([42], Shadowed())
1516enddef
1517
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001518def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001519 var path: string = empty(dir)
1520 \ ? 'empty'
1521 \ : 'full'
1522 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001523enddef
1524
1525def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001526 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001527enddef
1528
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001529def Test_script_var_in_lambda()
1530 var lines =<< trim END
1531 vim9script
1532 var script = 'test'
1533 assert_equal(['test'], map(['one'], {-> script}))
1534 END
1535 CheckScriptSuccess(lines)
1536enddef
1537
Bram Moolenaar5e654232020-09-16 15:22:00 +02001538def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001539 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001540 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001541 ->toupper()})
1542 ->reverse()
1543 return x
1544enddef
1545
1546def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001547 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001548enddef
1549
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001550func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001551 CheckScreendump
1552
1553 let lines =<< trim END
1554 vim9script
1555 def EchoNothing()
1556 silent echo ''
1557 enddef
1558 defcompile
1559 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001560 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001561
1562 " Check that the balloon shows up after a mouse move
1563 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001564 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001565 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1566
1567 " clean up
1568 call StopVimInTerminal(buf)
1569 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001570endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001571
Bram Moolenaar171fb922020-10-28 16:54:47 +01001572def SilentlyError()
1573 execute('silent! invalid')
1574 g:did_it = 'yes'
1575enddef
1576
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001577func UserError()
1578 silent! invalid
1579endfunc
1580
1581def SilentlyUserError()
1582 UserError()
1583 g:did_it = 'yes'
1584enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001585
1586" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001587func Test_ignore_silent_error()
1588 let g:did_it = 'no'
1589 call SilentlyError()
1590 call assert_equal('yes', g:did_it)
1591
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001592 let g:did_it = 'no'
1593 call SilentlyUserError()
1594 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001595
1596 unlet g:did_it
1597endfunc
1598
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001599def Test_ignore_silent_error_in_filter()
1600 var lines =<< trim END
1601 vim9script
1602 def Filter(winid: number, key: string): bool
1603 if key == 'o'
1604 silent! eval [][0]
1605 return true
1606 endif
1607 return popup_filter_menu(winid, key)
1608 enddef
1609
Bram Moolenaare0de1712020-12-02 17:36:54 +01001610 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001611 feedkeys("o\r", 'xnt')
1612 END
1613 CheckScriptSuccess(lines)
1614enddef
1615
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001616def Fibonacci(n: number): number
1617 if n < 2
1618 return n
1619 else
1620 return Fibonacci(n - 1) + Fibonacci(n - 2)
1621 endif
1622enddef
1623
Bram Moolenaar985116a2020-07-12 17:31:09 +02001624def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001625 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001626enddef
1627
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001628def TreeWalk(dir: string): list<any>
1629 return readdir(dir)->map({_, val ->
1630 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001631 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001632 : val
1633 })
1634enddef
1635
1636def Test_closure_in_map()
1637 mkdir('XclosureDir/tdir', 'p')
1638 writefile(['111'], 'XclosureDir/file1')
1639 writefile(['222'], 'XclosureDir/file2')
1640 writefile(['333'], 'XclosureDir/tdir/file3')
1641
Bram Moolenaare0de1712020-12-02 17:36:54 +01001642 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001643
1644 delete('XclosureDir', 'rf')
1645enddef
1646
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001647def Test_invalid_function_name()
1648 var lines =<< trim END
1649 vim9script
1650 def s: list<string>
1651 END
1652 CheckScriptFailure(lines, 'E129:')
1653
1654 lines =<< trim END
1655 vim9script
1656 def g: list<string>
1657 END
1658 CheckScriptFailure(lines, 'E129:')
1659
1660 lines =<< trim END
1661 vim9script
1662 def <SID>: list<string>
1663 END
1664 CheckScriptFailure(lines, 'E884:')
1665
1666 lines =<< trim END
1667 vim9script
1668 def F list<string>
1669 END
1670 CheckScriptFailure(lines, 'E488:')
1671enddef
1672
Bram Moolenaara90afb92020-07-15 22:38:56 +02001673def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001674 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001675 Xsetlist([], ' ', {title: 'test'})
1676 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001677
1678 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001679 Xsetlist({title: 'test'})
1680 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001681
1682 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001683 Xsetlist([], ' ', {title: 'test'})
1684 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001685
1686 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001687 Xsetlist({title: 'test'})
1688 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001689
1690 var Len: func: number = function('len', ['word'])
1691 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001692enddef
1693
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001694def Test_cmd_modifier()
1695 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001696 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001697enddef
1698
1699def Test_restore_modifiers()
1700 # check that when compiling a :def function command modifiers are not messed
1701 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001702 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001703 vim9script
1704 set eventignore=
1705 autocmd QuickFixCmdPost * copen
1706 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001707 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001708 enddef
1709 func Func()
1710 noautocmd call s:AutocmdsDisabled()
1711 let g:ei_after = &eventignore
1712 endfunc
1713 Func()
1714 END
1715 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001716 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001717enddef
1718
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001719def StackTop()
1720 eval 1
1721 eval 2
1722 # call not on fourth line
1723 StackBot()
1724enddef
1725
1726def StackBot()
1727 # throw an error
1728 eval [][0]
1729enddef
1730
1731def Test_callstack_def()
1732 try
1733 StackTop()
1734 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001735 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001736 endtry
1737enddef
1738
Bram Moolenaare8211a32020-10-09 22:04:29 +02001739" Re-using spot for variable used in block
1740def Test_block_scoped_var()
1741 var lines =<< trim END
1742 vim9script
1743 def Func()
1744 var x = ['a', 'b', 'c']
1745 if 1
1746 var y = 'x'
1747 map(x, {-> y})
1748 endif
1749 var z = x
1750 assert_equal(['x', 'x', 'x'], z)
1751 enddef
1752 Func()
1753 END
1754 CheckScriptSuccess(lines)
1755enddef
1756
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001757def Test_reset_did_emsg()
1758 var lines =<< trim END
1759 @s = 'blah'
1760 au BufWinLeave * #
1761 def Func()
1762 var winid = popup_create('popup', {})
1763 exe '*s'
1764 popup_close(winid)
1765 enddef
1766 Func()
1767 END
1768 CheckScriptFailure(lines, 'E492:', 8)
1769enddef
1770
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001771def Test_abort_even_with_silent()
1772 var lines =<< trim END
1773 vim9script
1774 g:result = 'none'
1775 def Func()
1776 eval {-> ''}() .. '' .. {}['X']
1777 g:result = 'yes'
1778 enddef
1779 sil! Func()
1780 assert_equal('none', g:result)
1781 END
1782 CheckScriptSuccess(lines)
1783enddef
1784
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001785
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001786" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker