blob: 0a07e8de8ecd56e2b1cb1f3ddb842ed0028f26c7 [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 Moolenaar34c54eb2020-11-25 19:15:19 +01001526def Test_failure_in_called_function()
1527 # this was using the frame index as the return value
1528 var lines =<< trim END
1529 vim9script
1530 au TerminalWinOpen * eval [][0]
1531 def PopupTerm(a: any)
1532 # make sure typvals on stack are string
1533 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1534 FireEvent()
1535 enddef
1536 def FireEvent()
1537 do TerminalWinOpen
1538 enddef
1539 # use try/catch to make eval fail
1540 try
1541 call PopupTerm(0)
1542 catch
1543 endtry
1544 au! TerminalWinOpen
1545 END
1546 CheckScriptSuccess(lines)
1547enddef
1548
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001549def Test_nested_lambda()
1550 var lines =<< trim END
1551 vim9script
1552 def Func()
1553 var x = 4
1554 var Lambda1 = {-> 7}
1555 var Lambda2 = {-> [Lambda1(), x]}
1556 var res = Lambda2()
1557 assert_equal([7, 4], res)
1558 enddef
1559 Func()
1560 END
1561 CheckScriptSuccess(lines)
1562enddef
1563
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001564def Shadowed(): list<number>
1565 var FuncList: list<func: number> = [{ -> 42}]
1566 return FuncList->map({_, Shadowed -> Shadowed()})
1567enddef
1568
1569def Test_lambda_arg_shadows_func()
1570 assert_equal([42], Shadowed())
1571enddef
1572
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001573def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001574 var path: string = empty(dir)
1575 \ ? 'empty'
1576 \ : 'full'
1577 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001578enddef
1579
1580def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001581 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001582enddef
1583
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001584def Test_script_var_in_lambda()
1585 var lines =<< trim END
1586 vim9script
1587 var script = 'test'
1588 assert_equal(['test'], map(['one'], {-> script}))
1589 END
1590 CheckScriptSuccess(lines)
1591enddef
1592
Bram Moolenaar5e654232020-09-16 15:22:00 +02001593def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001594 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001595 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001596 ->toupper()})
1597 ->reverse()
1598 return x
1599enddef
1600
1601def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001602 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001603enddef
1604
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001605func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001606 CheckScreendump
1607
1608 let lines =<< trim END
1609 vim9script
1610 def EchoNothing()
1611 silent echo ''
1612 enddef
1613 defcompile
1614 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001615 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001616
1617 " Check that the balloon shows up after a mouse move
1618 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001619 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001620 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1621
1622 " clean up
1623 call StopVimInTerminal(buf)
1624 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001625endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001626
Bram Moolenaar171fb922020-10-28 16:54:47 +01001627def SilentlyError()
1628 execute('silent! invalid')
1629 g:did_it = 'yes'
1630enddef
1631
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001632func UserError()
1633 silent! invalid
1634endfunc
1635
1636def SilentlyUserError()
1637 UserError()
1638 g:did_it = 'yes'
1639enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001640
1641" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001642func Test_ignore_silent_error()
1643 let g:did_it = 'no'
1644 call SilentlyError()
1645 call assert_equal('yes', g:did_it)
1646
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001647 let g:did_it = 'no'
1648 call SilentlyUserError()
1649 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001650
1651 unlet g:did_it
1652endfunc
1653
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001654def Test_ignore_silent_error_in_filter()
1655 var lines =<< trim END
1656 vim9script
1657 def Filter(winid: number, key: string): bool
1658 if key == 'o'
1659 silent! eval [][0]
1660 return true
1661 endif
1662 return popup_filter_menu(winid, key)
1663 enddef
1664
Bram Moolenaare0de1712020-12-02 17:36:54 +01001665 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001666 feedkeys("o\r", 'xnt')
1667 END
1668 CheckScriptSuccess(lines)
1669enddef
1670
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001671def Fibonacci(n: number): number
1672 if n < 2
1673 return n
1674 else
1675 return Fibonacci(n - 1) + Fibonacci(n - 2)
1676 endif
1677enddef
1678
Bram Moolenaar985116a2020-07-12 17:31:09 +02001679def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001680 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001681enddef
1682
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001683def TreeWalk(dir: string): list<any>
1684 return readdir(dir)->map({_, val ->
1685 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001686 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001687 : val
1688 })
1689enddef
1690
1691def Test_closure_in_map()
1692 mkdir('XclosureDir/tdir', 'p')
1693 writefile(['111'], 'XclosureDir/file1')
1694 writefile(['222'], 'XclosureDir/file2')
1695 writefile(['333'], 'XclosureDir/tdir/file3')
1696
Bram Moolenaare0de1712020-12-02 17:36:54 +01001697 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001698
1699 delete('XclosureDir', 'rf')
1700enddef
1701
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001702def Test_invalid_function_name()
1703 var lines =<< trim END
1704 vim9script
1705 def s: list<string>
1706 END
1707 CheckScriptFailure(lines, 'E129:')
1708
1709 lines =<< trim END
1710 vim9script
1711 def g: list<string>
1712 END
1713 CheckScriptFailure(lines, 'E129:')
1714
1715 lines =<< trim END
1716 vim9script
1717 def <SID>: list<string>
1718 END
1719 CheckScriptFailure(lines, 'E884:')
1720
1721 lines =<< trim END
1722 vim9script
1723 def F list<string>
1724 END
1725 CheckScriptFailure(lines, 'E488:')
1726enddef
1727
Bram Moolenaara90afb92020-07-15 22:38:56 +02001728def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001729 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001730 Xsetlist([], ' ', {title: 'test'})
1731 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001732
1733 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001734 Xsetlist({title: 'test'})
1735 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001736
1737 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001738 Xsetlist([], ' ', {title: 'test'})
1739 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001740
1741 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001742 Xsetlist({title: 'test'})
1743 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001744
1745 var Len: func: number = function('len', ['word'])
1746 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001747enddef
1748
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001749def Test_cmd_modifier()
1750 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001751 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001752enddef
1753
1754def Test_restore_modifiers()
1755 # check that when compiling a :def function command modifiers are not messed
1756 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001757 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001758 vim9script
1759 set eventignore=
1760 autocmd QuickFixCmdPost * copen
1761 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001762 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001763 enddef
1764 func Func()
1765 noautocmd call s:AutocmdsDisabled()
1766 let g:ei_after = &eventignore
1767 endfunc
1768 Func()
1769 END
1770 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001771 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001772enddef
1773
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001774def StackTop()
1775 eval 1
1776 eval 2
1777 # call not on fourth line
1778 StackBot()
1779enddef
1780
1781def StackBot()
1782 # throw an error
1783 eval [][0]
1784enddef
1785
1786def Test_callstack_def()
1787 try
1788 StackTop()
1789 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001790 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001791 endtry
1792enddef
1793
Bram Moolenaare8211a32020-10-09 22:04:29 +02001794" Re-using spot for variable used in block
1795def Test_block_scoped_var()
1796 var lines =<< trim END
1797 vim9script
1798 def Func()
1799 var x = ['a', 'b', 'c']
1800 if 1
1801 var y = 'x'
1802 map(x, {-> y})
1803 endif
1804 var z = x
1805 assert_equal(['x', 'x', 'x'], z)
1806 enddef
1807 Func()
1808 END
1809 CheckScriptSuccess(lines)
1810enddef
1811
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001812def Test_reset_did_emsg()
1813 var lines =<< trim END
1814 @s = 'blah'
1815 au BufWinLeave * #
1816 def Func()
1817 var winid = popup_create('popup', {})
1818 exe '*s'
1819 popup_close(winid)
1820 enddef
1821 Func()
1822 END
1823 CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001824 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001825enddef
1826
Bram Moolenaar57f799e2020-12-12 20:42:19 +01001827def Test_did_emsg_reset()
1828 # executing an autocommand resets did_emsg, this should not result in a
1829 # builtin function considered failing
1830 var lines =<< trim END
1831 vim9script
1832 au BufWinLeave * #
1833 def Func()
1834 popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
1835 eval [][0]
1836 enddef
1837 nno <F3> <cmd>call <sid>Func()<cr>
1838 feedkeys("\<F3>\e", 'xt')
1839 END
1840 writefile(lines, 'XemsgReset')
1841 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
1842 delete('XemsgReset')
1843 nunmap <F3>
1844 au! BufWinLeave
1845enddef
1846
Bram Moolenaar56602ba2020-12-05 21:22:08 +01001847def Test_abort_with_silent_call()
1848 var lines =<< trim END
1849 vim9script
1850 g:result = 'none'
1851 def Func()
1852 g:result += 3
1853 g:result = 'yes'
1854 enddef
1855 # error is silenced, but function aborts on error
1856 silent! Func()
1857 assert_equal('none', g:result)
1858 unlet g:result
1859 END
1860 CheckScriptSuccess(lines)
1861enddef
1862
Bram Moolenaarf665e972020-12-05 19:17:16 +01001863def Test_continues_with_silent_error()
1864 var lines =<< trim END
1865 vim9script
1866 g:result = 'none'
1867 def Func()
1868 silent! g:result += 3
1869 g:result = 'yes'
1870 enddef
1871 # error is silenced, function does not abort
1872 Func()
1873 assert_equal('yes', g:result)
1874 unlet g:result
1875 END
1876 CheckScriptSuccess(lines)
1877enddef
1878
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001879def Test_abort_even_with_silent()
1880 var lines =<< trim END
1881 vim9script
1882 g:result = 'none'
1883 def Func()
1884 eval {-> ''}() .. '' .. {}['X']
1885 g:result = 'yes'
1886 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01001887 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001888 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001889 unlet g:result
1890 END
1891 CheckScriptSuccess(lines)
1892enddef
1893
Bram Moolenaarf665e972020-12-05 19:17:16 +01001894def Test_cmdmod_silent_restored()
1895 var lines =<< trim END
1896 vim9script
1897 def Func()
1898 g:result = 'none'
1899 silent! g:result += 3
1900 g:result = 'none'
1901 g:result += 3
1902 enddef
1903 Func()
1904 END
1905 # can't use CheckScriptFailure, it ignores the :silent!
1906 var fname = 'Xdefsilent'
1907 writefile(lines, fname)
1908 var caught = 'no'
1909 try
1910 exe 'source ' .. fname
1911 catch /E1030:/
1912 caught = 'yes'
1913 assert_match('Func, line 4', v:throwpoint)
1914 endtry
1915 assert_equal('yes', caught)
1916 delete(fname)
1917enddef
1918
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001919def Test_dict_member_with_silent()
1920 var lines =<< trim END
1921 vim9script
1922 g:result = 'none'
1923 var d: dict<any>
1924 def Func()
1925 try
1926 g:result = map([], {_, v -> {}[v]})->join() .. d['']
1927 catch
1928 endtry
1929 enddef
1930 silent! Func()
1931 assert_equal('0', g:result)
1932 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001933 END
1934 CheckScriptSuccess(lines)
1935enddef
1936
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001937
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001938" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker