blob: 61e909bfc40954386a85cec71433df6fd7d32e28 [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 Moolenaar2d870f82020-12-05 13:41:01 +0100202 delfunc g:Func
Bram Moolenaar77072282020-09-16 17:55:40 +0200203 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100204 delfunc g:Func
Bram Moolenaar04b12692020-05-04 23:24:44 +0200205enddef
206
207def Test_nested_function()
208 def Nested(arg: string): string
209 return 'nested ' .. arg
210 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200211 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200212
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200213 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
214 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
215
Bram Moolenaar04b12692020-05-04 23:24:44 +0200216 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200217 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
218 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200219
Bram Moolenaar54021752020-12-06 18:50:36 +0100220 var lines =<< trim END
221 def Outer()
222 def Inner()
223 # comment
224 enddef
225 def Inner()
226 enddef
227 enddef
228 END
229 CheckDefFailure(lines, 'E1073:')
230
231 lines =<< trim END
232 def Outer()
233 def Inner()
234 # comment
235 enddef
236 def! Inner()
237 enddef
238 enddef
239 END
240 CheckDefFailure(lines, 'E1117:')
241
242 # nested function inside conditional
243 # TODO: should it work when "thecount" is inside the "if"?
244 lines =<< trim END
245 vim9script
246 var thecount = 0
247 if true
248 def Test(): number
249 def TheFunc(): number
250 thecount += 1
251 return thecount
252 enddef
253 return TheFunc()
254 enddef
255 endif
256 defcompile
257 assert_equal(1, Test())
258 assert_equal(2, Test())
259 END
260 CheckScriptSuccess(lines)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200261enddef
262
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200263func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200264 call MyDefaultArgs()->assert_equal('string')
265 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200266 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200267endfunc
268
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200269def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200270 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200271 vim9script
272 def Outer()
273 def g:Inner(): string
274 return 'inner'
275 enddef
276 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200277 defcompile
278 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200279 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200280 delfunc g:Inner
281 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200282 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200283 delfunc g:Inner
284 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200285 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200286 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200287 END
288 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200289
290 lines =<< trim END
291 vim9script
292 def Outer()
293 def g:Inner(): string
294 return 'inner'
295 enddef
296 enddef
297 defcompile
298 Outer()
299 Outer()
300 END
301 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200302
303 lines =<< trim END
304 vim9script
305 def Func()
306 echo 'script'
307 enddef
308 def Outer()
309 def Func()
310 echo 'inner'
311 enddef
312 enddef
313 defcompile
314 END
315 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200316enddef
317
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100318def DefListAll()
319 def
320enddef
321
322def DefListOne()
323 def DefListOne
324enddef
325
326def DefListMatches()
327 def /DefList
328enddef
329
330def Test_nested_def_list()
331 var funcs = split(execute('call DefListAll()'), "\n")
332 assert_true(len(funcs) > 10)
333 assert_true(funcs->index('def DefListAll()') >= 0)
334
335 funcs = split(execute('call DefListOne()'), "\n")
336 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
337
338 funcs = split(execute('call DefListMatches()'), "\n")
339 assert_true(len(funcs) >= 3)
340 assert_true(funcs->index('def DefListAll()') >= 0)
341 assert_true(funcs->index('def DefListOne()') >= 0)
342 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +0100343
344 var lines =<< trim END
345 vim9script
346 def Func()
347 def +Func+
348 enddef
349 defcompile
350 END
351 CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100352enddef
353
Bram Moolenaar333894b2020-08-01 18:53:07 +0200354def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200355 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200356 vim9script
357 def g:Func(): string
358 return 'global'
359 enddef
360 def Func(): string
361 return 'local'
362 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200363 g:Func()->assert_equal('global')
364 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100365 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +0200366 END
367 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200368
369 lines =<< trim END
370 vim9script
371 def g:Funcy()
372 echo 'funcy'
373 enddef
374 s:Funcy()
375 END
376 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200377enddef
378
Bram Moolenaar0f769812020-09-12 18:32:34 +0200379def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200380 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200381 vim9script
382 def g:Gfunc(): string
383 return 'global'
384 enddef
385 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200386 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200387 return Gfunc('testing')
388 enddef
389 g:Gfunc()->assert_equal('global')
390 AnotherFunc()->assert_equal(7)
391 delfunc g:Gfunc
392 END
393 CheckScriptSuccess(lines)
394
395 lines =<< trim END
396 vim9script
397 def g:Func(): string
398 return 'global'
399 enddef
400 def AnotherFunc()
401 g:Func = function('len')
402 enddef
403 AnotherFunc()
404 END
405 CheckScriptFailure(lines, 'E705:')
406 delfunc g:Func
407enddef
408
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200409func TakesOneArg(arg)
410 echo a:arg
411endfunc
412
413def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200414 CheckDefFailure(['TakesOneArg()'], 'E119:')
415 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
416 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
417 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200418
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200419 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200420 vim9script
421 def Func(s: string)
422 echo s
423 enddef
424 Func([])
425 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200426 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200427
428 lines =<< trim END
429 vim9script
430 def FuncOne(nr: number)
431 echo nr
432 enddef
433 def FuncTwo()
434 FuncOne()
435 enddef
436 defcompile
437 END
438 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200439 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200440 try
441 source Xscript
442 catch
443 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
444 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
445 didCatch = true
446 endtry
447 assert_true(didCatch)
448
449 lines =<< trim END
450 vim9script
451 def FuncOne(nr: number)
452 echo nr
453 enddef
454 def FuncTwo()
455 FuncOne(1, 2)
456 enddef
457 defcompile
458 END
459 writefile(lines, 'Xscript')
460 didCatch = false
461 try
462 source Xscript
463 catch
464 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
465 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
466 didCatch = true
467 endtry
468 assert_true(didCatch)
469
470 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200471enddef
472
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100473def Test_call_lambda_args()
474 CheckDefFailure(['echo {i -> 0}()'],
475 'E119: Not enough arguments for function: {i -> 0}()')
476
477 var lines =<< trim END
478 var Ref = {x: number, y: number -> x + y}
479 echo Ref(1, 'x')
480 END
481 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
482enddef
483
Bram Moolenaar709664c2020-12-12 14:33:41 +0100484def Test_lambda_uses_assigned_var()
485 CheckDefSuccess([
486 'var x: any = "aaa"'
487 'x = filter(["bbb"], {_, v -> v =~ x})'])
488enddef
489
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200490" Default arg and varargs
491def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200492 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200493 for s in rest
494 res ..= ',' .. s
495 endfor
496 return res
497enddef
498
499def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200500 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200501 MyDefVarargs('one')->assert_equal('one,foo')
502 MyDefVarargs('one', 'two')->assert_equal('one,two')
503 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200504 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200505 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200506 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200507 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200508
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200509 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200510 vim9script
511 def Func(...l: list<string>)
512 echo l
513 enddef
514 Func('a', 'b', 'c')
515 END
516 CheckScriptSuccess(lines)
517
518 lines =<< trim END
519 vim9script
520 def Func(...l: list<string>)
521 echo l
522 enddef
523 Func()
524 END
525 CheckScriptSuccess(lines)
526
527 lines =<< trim END
528 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200529 def Func(...l: any)
530 echo l
531 enddef
532 Func(0)
533 END
534 CheckScriptSuccess(lines)
535
536 lines =<< trim END
537 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200538 def Func(..._l: list<string>)
539 echo _l
540 enddef
541 Func('a', 'b', 'c')
542 END
543 CheckScriptSuccess(lines)
544
545 lines =<< trim END
546 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200547 def Func(...l: list<string>)
548 echo l
549 enddef
550 Func(1, 2, 3)
551 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200552 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200553
554 lines =<< trim END
555 vim9script
556 def Func(...l: list<string>)
557 echo l
558 enddef
559 Func('a', 9)
560 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200561 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200562
563 lines =<< trim END
564 vim9script
565 def Func(...l: list<string>)
566 echo l
567 enddef
568 Func(1, 'a')
569 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200570 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200571enddef
572
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200573let s:value = ''
574
575def FuncOneDefArg(opt = 'text')
576 s:value = opt
577enddef
578
579def FuncTwoDefArg(nr = 123, opt = 'text'): string
580 return nr .. opt
581enddef
582
583def FuncVarargs(...arg: list<string>): string
584 return join(arg, ',')
585enddef
586
587def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200588 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200589 RefDefArg = FuncOneDefArg
590 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200591 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200592 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200593 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200594
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200595 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200596 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200597 RefDef2Arg()->assert_equal('123text')
598 RefDef2Arg(99)->assert_equal('99text')
599 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200600
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200601 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
602 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200603
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200604 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200605 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200606 RefVarargs()->assert_equal('')
607 RefVarargs('one')->assert_equal('one')
608 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200609
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200610 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
611 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200612enddef
613
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200614" Only varargs
615def MyVarargsOnly(...args: list<string>): string
616 return join(args, ',')
617enddef
618
619def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200620 MyVarargsOnly()->assert_equal('')
621 MyVarargsOnly('one')->assert_equal('one')
622 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200623 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
624 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200625enddef
626
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200627def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200628 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200629 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200630 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200631enddef
632
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200633def DictArg(arg: dict<string>)
634 arg['key'] = 'value'
635enddef
636
637def ListArg(arg: list<string>)
638 arg[0] = 'value'
639enddef
640
641def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200642 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200643 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200644 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200645 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200646 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200647 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200648 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200649
Bram Moolenaard2c61702020-09-06 15:58:36 +0200650 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100651 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200652enddef
653
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200654" These argument names are reserved in legacy functions.
655def WithReservedNames(firstline: string, lastline: string): string
656 return firstline .. lastline
657enddef
658
659def Test_argument_names()
660 assert_equal('OK', WithReservedNames('O', 'K'))
661enddef
662
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200663def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200664 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200665 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200666enddef
667
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200668func DefinedLater(arg)
669 return a:arg
670endfunc
671
672def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200673 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200674 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
675 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200676
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200677 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200678 vim9script
679 def RetNumber(): number
680 return 123
681 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200682 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200683 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200684 END
685 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200686
687 lines =<< trim END
688 vim9script
689 def RetNumber(): number
690 return 123
691 enddef
692 def Bar(F: func: number): number
693 return F()
694 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200695 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200696 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200697 END
698 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200699
700 lines =<< trim END
701 vim9script
702 def UseNumber(nr: number)
703 echo nr
704 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200705 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200706 Funcref(123)
707 END
708 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200709
710 lines =<< trim END
711 vim9script
712 def UseNumber(nr: number)
713 echo nr
714 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200715 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200716 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200717 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200718
719 lines =<< trim END
720 vim9script
721 def EchoNr(nr = 34)
722 g:echo = nr
723 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200724 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200725 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200726 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200727 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200728 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200729 END
730 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200731
732 lines =<< trim END
733 vim9script
734 def EchoList(...l: list<number>)
735 g:echo = l
736 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200737 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200738 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200739 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200740 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200741 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200742 END
743 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200744
745 lines =<< trim END
746 vim9script
747 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
748 g:optarg = opt
749 g:listarg = l
750 return nr
751 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200752 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200753 Funcref(10)->assert_equal(10)
754 g:optarg->assert_equal(12)
755 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200756
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200757 Funcref(11, 22)->assert_equal(11)
758 g:optarg->assert_equal(22)
759 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200760
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200761 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
762 g:optarg->assert_equal(18)
763 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200764 END
765 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200766enddef
767
768let SomeFunc = function('len')
769let NotAFunc = 'text'
770
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200771def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200772 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200773 var Ref1: func(bool): string
774 var Ref2: func(bool): number
775 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200776 Ref3 = g:cond ? Ref1 : Ref2
777
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200778 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200779 var Refa1: func(bool): number
780 var Refa2: func(bool, number): number
781 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200782 Refa3 = g:cond ? Refa1 : Refa2
783
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200784 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200785 var Refb1: func(bool, string): number
786 var Refb2: func(string, number): number
787 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200788 Refb3 = g:cond ? Refb1 : Refb2
789enddef
790
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200791def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200792 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200793enddef
794
795def DefinedEvenLater(arg: string): string
796 return arg
797enddef
798
799def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200800 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200801 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200802enddef
803
804def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200805 CheckScriptFailure([
806 'def Func(): number',
807 'return "a"',
808 'enddef',
809 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100810 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200811 CheckScriptFailure([
812 'def Func(): string',
813 'return 1',
814 'enddef',
815 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100816 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200817 CheckScriptFailure([
818 'def Func(): void',
819 'return "a"',
820 'enddef',
821 'defcompile'],
822 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100823 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200824 CheckScriptFailure([
825 'def Func()',
826 'return "a"',
827 'enddef',
828 'defcompile'],
829 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100830 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200831
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200832 CheckScriptFailure([
833 'def Func(): number',
834 'return',
835 'enddef',
836 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100837 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200838
839 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100840 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200841 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100842 delfunc! g:Func
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200843 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100844 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200845
846 CheckScriptFailure([
847 'vim9script',
848 'def FuncB()',
849 ' return 123',
850 'enddef',
851 'def FuncA()',
852 ' FuncB()',
853 'enddef',
854 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200855enddef
856
857def Test_arg_type_wrong()
858 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200859 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200860 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200861 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200862enddef
863
864def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200865 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200866 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200867 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200868 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200869 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200870 enddef
871 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200872 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200873
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200874 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200875 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200876 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200877
Bram Moolenaar67979662020-06-20 22:50:47 +0200878 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200879 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200880 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200881
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200882 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200883 def ListFunc(arg: list<number>)
884 listvar = arg
885 enddef
886 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200887 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200888
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200889 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200890 def DictFunc(arg: dict<number>)
891 dictvar = arg
892 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +0100893 {a: 1, b: 2}->DictFunc()
894 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200895 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100896 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200897 enddef
898 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100899 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200900
Bram Moolenaare0de1712020-12-02 17:36:54 +0100901 {a: 3, b: 4}->DictFunc()
902 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200903
904 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200905 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200906 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200907 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200908
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200909 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200910 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200911 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200912 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200913 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200914 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200915
916 def UseString()
917 'xyork'->MyFunc()
918 enddef
919 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200920 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200921
Bram Moolenaar10409562020-07-29 20:00:38 +0200922 def UseString2()
923 "knife"->MyFunc()
924 enddef
925 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200926 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200927
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200928 # prepending a colon makes it a mark
929 new
930 setline(1, ['aaa', 'bbb', 'ccc'])
931 normal! 3Gmt1G
932 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200933 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200934 bwipe!
935
Bram Moolenaare6b53242020-07-01 17:28:33 +0200936 MyFunc(
937 'continued'
938 )
939 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200940 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200941 )
942
943 call MyFunc(
944 'more'
945 ..
946 'lines'
947 )
948 assert_equal(
949 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200950 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200951 END
952 writefile(lines, 'Xcall.vim')
953 source Xcall.vim
954 delete('Xcall.vim')
955enddef
956
957def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200958 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200959 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200960 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200961 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200962 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200963 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200964 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200965 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200966 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200967enddef
968
Bram Moolenaar65b95452020-07-19 14:03:09 +0200969def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200970 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200971 vim9script
972 def MyFunc(arg: string)
973 echo arg
974 enddef
975 MyFunc(1234)
976 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200977 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200978enddef
979
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200980def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200981 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200982 vim9script
983 const var = ''
984 def MyFunc(arg: string)
985 var = 'asdf'
986 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200987 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200988 END
989 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200990 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200991 delete('Xcall_const.vim')
992enddef
993
994" Test that inside :function a Python function can be defined, :def is not
995" recognized.
996func Test_function_python()
997 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200998 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200999 execute py "<< EOF"
1000def do_something():
1001 return 1
1002EOF
1003endfunc
1004
1005def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001006 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001007 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001008 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001009 echo 'hello'
1010 enddef
1011
1012 def CallGoneSoon()
1013 GoneSoon()
1014 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001015 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001016
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001017 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001018 CallGoneSoon()
1019 END
1020 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001021 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
1022 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001023
1024 delete('XToDelFunc')
1025enddef
1026
1027def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02001028 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001029 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001030 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001031 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001032 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001033 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02001034 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001035 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001036 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001037
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001038 g:Func0()->assert_equal(0)
1039 g:Func1()->assert_equal('Func1')
1040 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001041
1042 delfunc! Func0
1043 delfunc! Func1
1044 delfunc! Func2
1045enddef
1046
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001047def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001048 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001049 vim9script
1050 func Func(arg)
1051 echo a:arg
1052 endfunc
1053 Func('text')
1054 END
1055 writefile(lines, 'XVim9Func')
1056 so XVim9Func
1057
1058 delete('XVim9Func')
1059enddef
1060
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001061let s:funcResult = 0
1062
1063def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001064 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001065enddef
1066
1067def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001068 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001069 return 1234
1070enddef
1071
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001072def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001073 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001074 return 'text'
1075enddef
1076
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001077def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001078 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001079enddef
1080
1081def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001082 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001083 return arg
1084enddef
1085
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001086def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001087 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001088enddef
1089
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001090def FuncOneArgRetString(arg: string): string
1091 return arg
1092enddef
1093
Bram Moolenaar89228602020-04-05 22:14:54 +02001094def FuncOneArgRetAny(arg: any): any
1095 return arg
1096enddef
1097
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001098def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001099 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001100 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001101 Ref1 = FuncNoArgNoRet
1102 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001103 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001104
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001105 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001106 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001107 Ref2 = FuncNoArgNoRet
1108 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001109 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001110
Bram Moolenaar53900992020-08-22 19:02:02 +02001111 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001112 Ref2 = FuncOneArgNoRet
1113 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001114 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001115
Bram Moolenaar53900992020-08-22 19:02:02 +02001116 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001117 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001118 Ref2()->assert_equal(1234)
1119 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001120
Bram Moolenaar53900992020-08-22 19:02:02 +02001121 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001122 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001123 Ref2(13)->assert_equal(13)
1124 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001125enddef
1126
Bram Moolenaar9978d472020-07-05 16:01:56 +02001127def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001128 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001129 for n in repeat([1], 3)
1130 res += n
1131 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001132 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001133
1134 res = 0
1135 for n in add([1, 2], 3)
1136 res += n
1137 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001138 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001139enddef
1140
Bram Moolenaar846178a2020-07-05 17:04:13 +02001141def Test_argv_return_type()
1142 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001143 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001144 for name in argv()
1145 res ..= name
1146 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001147 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001148enddef
1149
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001150def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001151 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001152 RefVoid = FuncNoArgNoRet
1153 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001154 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1155 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001156
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001157 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001158 RefAny = FuncNoArgRetNumber
1159 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001160 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1161 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001162
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001163 var RefAnyNoArgs: func: any = RefAny
1164
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001165 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001166 RefNr = FuncNoArgRetNumber
1167 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001168 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1169 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001170
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001171 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001172 RefStr = FuncNoArgRetString
1173 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001174 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1175 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001176enddef
1177
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001178def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001179 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001180
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001181 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1182 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1183 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1184 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1185 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1186 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 +02001187
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001188 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1189 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1190 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:')
1191 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001192enddef
1193
Bram Moolenaar89228602020-04-05 22:14:54 +02001194def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001195 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001196 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001197 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001198
1199 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001200 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001201
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001202 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001203 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001204 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001205
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001206 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001207enddef
1208
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001209def Test_func_common_type()
1210 def FuncOne(n: number): number
1211 return n
1212 enddef
1213 def FuncTwo(s: string): number
1214 return len(s)
1215 enddef
1216 def FuncThree(n: number, s: string): number
1217 return n + len(s)
1218 enddef
1219 var list = [FuncOne, FuncTwo, FuncThree]
1220 assert_equal(8, list[0](8))
1221 assert_equal(4, list[1]('word'))
1222 assert_equal(7, list[2](3, 'word'))
1223enddef
1224
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001225def MultiLine(
1226 arg1: string,
1227 arg2 = 1234,
1228 ...rest: list<string>
1229 ): string
1230 return arg1 .. arg2 .. join(rest, '-')
1231enddef
1232
Bram Moolenaar2c330432020-04-13 14:41:35 +02001233def MultiLineComment(
1234 arg1: string, # comment
1235 arg2 = 1234, # comment
1236 ...rest: list<string> # comment
1237 ): string # comment
1238 return arg1 .. arg2 .. join(rest, '-')
1239enddef
1240
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001241def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001242 MultiLine('text')->assert_equal('text1234')
1243 MultiLine('text', 777)->assert_equal('text777')
1244 MultiLine('text', 777, 'one')->assert_equal('text777one')
1245 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001246enddef
1247
Bram Moolenaar23e03252020-04-12 22:22:31 +02001248func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001249 call MultiLine('text')->assert_equal('text1234')
1250 call MultiLine('text', 777)->assert_equal('text777')
1251 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1252 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001253endfunc
1254
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001255
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001256" When using CheckScriptFailure() for the below test, E1010 is generated instead
1257" of E1056.
1258func Test_E1056_1059()
1259 let caught_1056 = 0
1260 try
1261 def F():
1262 return 1
1263 enddef
1264 catch /E1056:/
1265 let caught_1056 = 1
1266 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001267 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001268
1269 let caught_1059 = 0
1270 try
1271 def F5(items : list)
1272 echo 'a'
1273 enddef
1274 catch /E1059:/
1275 let caught_1059 = 1
1276 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001277 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001278endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001279
Bram Moolenaar015f4262020-05-05 21:25:22 +02001280func DelMe()
1281 echo 'DelMe'
1282endfunc
1283
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001284def Test_error_reporting()
1285 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001286 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001287 " comment
1288 def Func()
1289 # comment
1290 # comment
1291 invalid
1292 enddef
1293 defcompile
1294 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001295 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001296 try
1297 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001298 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001299 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001300 v:exception->assert_match('Invalid command: invalid')
1301 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001302 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001303 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001304
1305 # comment lines after the start of the function
1306 lines =<< trim END
1307 " comment
1308 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001309 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001310 # comment
1311 # comment
1312 invalid
1313 enddef
1314 defcompile
1315 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001316 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001317 try
1318 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001319 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001320 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001321 v:exception->assert_match('Invalid command: invalid')
1322 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001323 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001324 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001325
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001326 lines =<< trim END
1327 vim9script
1328 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001329 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001330 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001331 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001332 enddef
1333 defcompile
1334 Func()
1335 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001336 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001337 try
1338 source Xdef
1339 assert_report('should have failed')
1340 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001341 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001342 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001343 delfunc! g:Func
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001344
Bram Moolenaar08052222020-09-14 17:04:31 +02001345 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001346enddef
1347
Bram Moolenaar015f4262020-05-05 21:25:22 +02001348def Test_deleted_function()
1349 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001350 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001351 'delfunc g:DelMe',
1352 'echo RefMe()'], 'E117:')
1353enddef
1354
1355def Test_unknown_function()
1356 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001357 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001358 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001359enddef
1360
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001361def RefFunc(Ref: func(string): string): string
1362 return Ref('more')
1363enddef
1364
1365def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001366 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001367 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001368enddef
1369
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001370def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001371 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001372 g:Ref = {s -> local .. s}
1373enddef
1374
1375def Test_closure_ref_after_return()
1376 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001377 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001378 unlet g:Ref
1379enddef
1380
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001381def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001382 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001383 g:Extend = {s -> local->add(s)}
1384 g:Read = {-> local}
1385enddef
1386
1387def Test_closure_two_refs()
1388 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001389 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001390 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001391 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001392 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001393 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001394
1395 unlet g:Extend
1396 unlet g:Read
1397enddef
1398
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001399def ReadRef(Ref: func(): list<string>): string
1400 return join(Ref(), ' ')
1401enddef
1402
Bram Moolenaar5e654232020-09-16 15:22:00 +02001403def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001404 Ref(add)
1405enddef
1406
1407def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001408 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001409 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001410 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001411 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001412 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001413 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001414
1415 unlet g:Extend
1416 unlet g:Read
1417enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001418
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001419def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001420 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001421 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1422enddef
1423
1424def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001425 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001426 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1427enddef
1428
1429def Test_closure_using_argument()
1430 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001431 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001432
1433 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001434 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001435
1436 unlet g:UseArg
1437 unlet g:UseVararg
1438enddef
1439
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001440def MakeGetAndAppendRefs()
1441 var local = 'a'
1442
1443 def Append(arg: string)
1444 local ..= arg
1445 enddef
1446 g:Append = Append
1447
1448 def Get(): string
1449 return local
1450 enddef
1451 g:Get = Get
1452enddef
1453
1454def Test_closure_append_get()
1455 MakeGetAndAppendRefs()
1456 g:Get()->assert_equal('a')
1457 g:Append('-b')
1458 g:Get()->assert_equal('a-b')
1459 g:Append('-c')
1460 g:Get()->assert_equal('a-b-c')
1461
1462 unlet g:Append
1463 unlet g:Get
1464enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001465
Bram Moolenaar04b12692020-05-04 23:24:44 +02001466def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001467 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001468 def Closure(arg: string): string
1469 return local .. arg
1470 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001471 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001472enddef
1473
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001474func GetResult(Ref)
1475 return a:Ref('some')
1476endfunc
1477
1478def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001479 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001480 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001481 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001482enddef
1483
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001484def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001485 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001486 vim9script
1487 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001488 var name = 0
1489 for i in range(2)
1490 timer_start(0, {-> name})
1491 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001492 enddef
1493 Func()
1494 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001495 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001496enddef
1497
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001498def Test_nested_closure_used()
1499 var lines =<< trim END
1500 vim9script
1501 def Func()
1502 var x = 'hello'
1503 var Closure = {-> x}
1504 g:Myclosure = {-> Closure()}
1505 enddef
1506 Func()
1507 assert_equal('hello', g:Myclosure())
1508 END
1509 CheckScriptSuccess(lines)
1510enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001511
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001512def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001513 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001514 vim9script
1515 def FuncA()
1516 FuncB(0)
1517 enddef
1518 def FuncB(n: number): list<string>
1519 return map([0], {_, v -> n})
1520 enddef
1521 FuncA()
1522 END
1523 CheckScriptFailure(lines, 'E1012:')
1524enddef
1525
Bram Moolenaarf112f302020-12-20 17:47:52 +01001526def Test_global_closure()
1527 var lines =<< trim END
1528 vim9script
1529 def ReverseEveryNLines(n: number, line1: number, line2: number)
1530 var mods = 'sil keepj keepp lockm '
1531 var range = ':' .. line1 .. ',' .. line2
1532 def g:Offset(): number
1533 var offset = (line('.') - line1 + 1) % n
1534 return offset != 0 ? offset : n
1535 enddef
1536 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
1537 enddef
1538
1539 new
1540 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
1541 ReverseEveryNLines(3, 1, 9)
1542 END
1543 CheckScriptSuccess(lines)
1544 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
1545 assert_equal(expected, getline(1, 9))
1546 bwipe!
1547enddef
1548
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01001549def Test_failure_in_called_function()
1550 # this was using the frame index as the return value
1551 var lines =<< trim END
1552 vim9script
1553 au TerminalWinOpen * eval [][0]
1554 def PopupTerm(a: any)
1555 # make sure typvals on stack are string
1556 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1557 FireEvent()
1558 enddef
1559 def FireEvent()
1560 do TerminalWinOpen
1561 enddef
1562 # use try/catch to make eval fail
1563 try
1564 call PopupTerm(0)
1565 catch
1566 endtry
1567 au! TerminalWinOpen
1568 END
1569 CheckScriptSuccess(lines)
1570enddef
1571
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001572def Test_nested_lambda()
1573 var lines =<< trim END
1574 vim9script
1575 def Func()
1576 var x = 4
1577 var Lambda1 = {-> 7}
1578 var Lambda2 = {-> [Lambda1(), x]}
1579 var res = Lambda2()
1580 assert_equal([7, 4], res)
1581 enddef
1582 Func()
1583 END
1584 CheckScriptSuccess(lines)
1585enddef
1586
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001587def Shadowed(): list<number>
1588 var FuncList: list<func: number> = [{ -> 42}]
1589 return FuncList->map({_, Shadowed -> Shadowed()})
1590enddef
1591
1592def Test_lambda_arg_shadows_func()
1593 assert_equal([42], Shadowed())
1594enddef
1595
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001596def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001597 var path: string = empty(dir)
1598 \ ? 'empty'
1599 \ : 'full'
1600 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001601enddef
1602
1603def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001604 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001605enddef
1606
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001607def Test_script_var_in_lambda()
1608 var lines =<< trim END
1609 vim9script
1610 var script = 'test'
1611 assert_equal(['test'], map(['one'], {-> script}))
1612 END
1613 CheckScriptSuccess(lines)
1614enddef
1615
Bram Moolenaar5e654232020-09-16 15:22:00 +02001616def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001617 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001618 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001619 ->toupper()})
1620 ->reverse()
1621 return x
1622enddef
1623
1624def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001625 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001626enddef
1627
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001628func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001629 CheckScreendump
1630
1631 let lines =<< trim END
1632 vim9script
1633 def EchoNothing()
1634 silent echo ''
1635 enddef
1636 defcompile
1637 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001638 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001639
1640 " Check that the balloon shows up after a mouse move
1641 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001642 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001643 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1644
1645 " clean up
1646 call StopVimInTerminal(buf)
1647 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001648endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001649
Bram Moolenaar171fb922020-10-28 16:54:47 +01001650def SilentlyError()
1651 execute('silent! invalid')
1652 g:did_it = 'yes'
1653enddef
1654
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001655func UserError()
1656 silent! invalid
1657endfunc
1658
1659def SilentlyUserError()
1660 UserError()
1661 g:did_it = 'yes'
1662enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001663
1664" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001665func Test_ignore_silent_error()
1666 let g:did_it = 'no'
1667 call SilentlyError()
1668 call assert_equal('yes', g:did_it)
1669
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001670 let g:did_it = 'no'
1671 call SilentlyUserError()
1672 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001673
1674 unlet g:did_it
1675endfunc
1676
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001677def Test_ignore_silent_error_in_filter()
1678 var lines =<< trim END
1679 vim9script
1680 def Filter(winid: number, key: string): bool
1681 if key == 'o'
1682 silent! eval [][0]
1683 return true
1684 endif
1685 return popup_filter_menu(winid, key)
1686 enddef
1687
Bram Moolenaare0de1712020-12-02 17:36:54 +01001688 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001689 feedkeys("o\r", 'xnt')
1690 END
1691 CheckScriptSuccess(lines)
1692enddef
1693
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001694def Fibonacci(n: number): number
1695 if n < 2
1696 return n
1697 else
1698 return Fibonacci(n - 1) + Fibonacci(n - 2)
1699 endif
1700enddef
1701
Bram Moolenaar985116a2020-07-12 17:31:09 +02001702def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001703 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001704enddef
1705
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001706def TreeWalk(dir: string): list<any>
1707 return readdir(dir)->map({_, val ->
1708 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001709 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001710 : val
1711 })
1712enddef
1713
1714def Test_closure_in_map()
1715 mkdir('XclosureDir/tdir', 'p')
1716 writefile(['111'], 'XclosureDir/file1')
1717 writefile(['222'], 'XclosureDir/file2')
1718 writefile(['333'], 'XclosureDir/tdir/file3')
1719
Bram Moolenaare0de1712020-12-02 17:36:54 +01001720 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001721
1722 delete('XclosureDir', 'rf')
1723enddef
1724
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001725def Test_invalid_function_name()
1726 var lines =<< trim END
1727 vim9script
1728 def s: list<string>
1729 END
1730 CheckScriptFailure(lines, 'E129:')
1731
1732 lines =<< trim END
1733 vim9script
1734 def g: list<string>
1735 END
1736 CheckScriptFailure(lines, 'E129:')
1737
1738 lines =<< trim END
1739 vim9script
1740 def <SID>: list<string>
1741 END
1742 CheckScriptFailure(lines, 'E884:')
1743
1744 lines =<< trim END
1745 vim9script
1746 def F list<string>
1747 END
1748 CheckScriptFailure(lines, 'E488:')
1749enddef
1750
Bram Moolenaara90afb92020-07-15 22:38:56 +02001751def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001752 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001753 Xsetlist([], ' ', {title: 'test'})
1754 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001755
1756 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001757 Xsetlist({title: 'test'})
1758 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001759
1760 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001761 Xsetlist([], ' ', {title: 'test'})
1762 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001763
1764 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001765 Xsetlist({title: 'test'})
1766 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001767
1768 var Len: func: number = function('len', ['word'])
1769 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001770enddef
1771
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001772def Test_cmd_modifier()
1773 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001774 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001775enddef
1776
1777def Test_restore_modifiers()
1778 # check that when compiling a :def function command modifiers are not messed
1779 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001780 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001781 vim9script
1782 set eventignore=
1783 autocmd QuickFixCmdPost * copen
1784 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001785 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001786 enddef
1787 func Func()
1788 noautocmd call s:AutocmdsDisabled()
1789 let g:ei_after = &eventignore
1790 endfunc
1791 Func()
1792 END
1793 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001794 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001795enddef
1796
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001797def StackTop()
1798 eval 1
1799 eval 2
1800 # call not on fourth line
1801 StackBot()
1802enddef
1803
1804def StackBot()
1805 # throw an error
1806 eval [][0]
1807enddef
1808
1809def Test_callstack_def()
1810 try
1811 StackTop()
1812 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001813 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001814 endtry
1815enddef
1816
Bram Moolenaare8211a32020-10-09 22:04:29 +02001817" Re-using spot for variable used in block
1818def Test_block_scoped_var()
1819 var lines =<< trim END
1820 vim9script
1821 def Func()
1822 var x = ['a', 'b', 'c']
1823 if 1
1824 var y = 'x'
1825 map(x, {-> y})
1826 endif
1827 var z = x
1828 assert_equal(['x', 'x', 'x'], z)
1829 enddef
1830 Func()
1831 END
1832 CheckScriptSuccess(lines)
1833enddef
1834
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001835def Test_reset_did_emsg()
1836 var lines =<< trim END
1837 @s = 'blah'
1838 au BufWinLeave * #
1839 def Func()
1840 var winid = popup_create('popup', {})
1841 exe '*s'
1842 popup_close(winid)
1843 enddef
1844 Func()
1845 END
1846 CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001847 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001848enddef
1849
Bram Moolenaar57f799e2020-12-12 20:42:19 +01001850def Test_did_emsg_reset()
1851 # executing an autocommand resets did_emsg, this should not result in a
1852 # builtin function considered failing
1853 var lines =<< trim END
1854 vim9script
1855 au BufWinLeave * #
1856 def Func()
1857 popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
1858 eval [][0]
1859 enddef
1860 nno <F3> <cmd>call <sid>Func()<cr>
1861 feedkeys("\<F3>\e", 'xt')
1862 END
1863 writefile(lines, 'XemsgReset')
1864 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
1865 delete('XemsgReset')
1866 nunmap <F3>
1867 au! BufWinLeave
1868enddef
1869
Bram Moolenaar56602ba2020-12-05 21:22:08 +01001870def Test_abort_with_silent_call()
1871 var lines =<< trim END
1872 vim9script
1873 g:result = 'none'
1874 def Func()
1875 g:result += 3
1876 g:result = 'yes'
1877 enddef
1878 # error is silenced, but function aborts on error
1879 silent! Func()
1880 assert_equal('none', g:result)
1881 unlet g:result
1882 END
1883 CheckScriptSuccess(lines)
1884enddef
1885
Bram Moolenaarf665e972020-12-05 19:17:16 +01001886def Test_continues_with_silent_error()
1887 var lines =<< trim END
1888 vim9script
1889 g:result = 'none'
1890 def Func()
1891 silent! g:result += 3
1892 g:result = 'yes'
1893 enddef
1894 # error is silenced, function does not abort
1895 Func()
1896 assert_equal('yes', g:result)
1897 unlet g:result
1898 END
1899 CheckScriptSuccess(lines)
1900enddef
1901
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001902def Test_abort_even_with_silent()
1903 var lines =<< trim END
1904 vim9script
1905 g:result = 'none'
1906 def Func()
1907 eval {-> ''}() .. '' .. {}['X']
1908 g:result = 'yes'
1909 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01001910 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001911 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001912 unlet g:result
1913 END
1914 CheckScriptSuccess(lines)
1915enddef
1916
Bram Moolenaarf665e972020-12-05 19:17:16 +01001917def Test_cmdmod_silent_restored()
1918 var lines =<< trim END
1919 vim9script
1920 def Func()
1921 g:result = 'none'
1922 silent! g:result += 3
1923 g:result = 'none'
1924 g:result += 3
1925 enddef
1926 Func()
1927 END
1928 # can't use CheckScriptFailure, it ignores the :silent!
1929 var fname = 'Xdefsilent'
1930 writefile(lines, fname)
1931 var caught = 'no'
1932 try
1933 exe 'source ' .. fname
1934 catch /E1030:/
1935 caught = 'yes'
1936 assert_match('Func, line 4', v:throwpoint)
1937 endtry
1938 assert_equal('yes', caught)
1939 delete(fname)
1940enddef
1941
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001942def Test_dict_member_with_silent()
1943 var lines =<< trim END
1944 vim9script
1945 g:result = 'none'
1946 var d: dict<any>
1947 def Func()
1948 try
1949 g:result = map([], {_, v -> {}[v]})->join() .. d['']
1950 catch
1951 endtry
1952 enddef
1953 silent! Func()
1954 assert_equal('0', g:result)
1955 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001956 END
1957 CheckScriptSuccess(lines)
1958enddef
1959
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001960
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001961" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker