blob: 4e8ee888dae0ef285a0f47f5e1618b1524d8831c [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
220 CheckDefFailure([
221 'def Outer()',
222 ' def Inner()',
223 ' # comment',
224 ' enddef',
225 ' def Inner()',
226 ' enddef',
227 'enddef'], 'E1073:')
228 CheckDefFailure([
229 'def Outer()',
230 ' def Inner()',
231 ' # comment',
232 ' enddef',
233 ' def! Inner()',
234 ' enddef',
235 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200236enddef
237
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200238func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200239 call MyDefaultArgs()->assert_equal('string')
240 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200241 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200242endfunc
243
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200244def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200245 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200246 vim9script
247 def Outer()
248 def g:Inner(): string
249 return 'inner'
250 enddef
251 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200252 defcompile
253 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200254 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200255 delfunc g:Inner
256 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200257 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200258 delfunc g:Inner
259 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200260 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200261 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200262 END
263 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200264
265 lines =<< trim END
266 vim9script
267 def Outer()
268 def g:Inner(): string
269 return 'inner'
270 enddef
271 enddef
272 defcompile
273 Outer()
274 Outer()
275 END
276 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200277
278 lines =<< trim END
279 vim9script
280 def Func()
281 echo 'script'
282 enddef
283 def Outer()
284 def Func()
285 echo 'inner'
286 enddef
287 enddef
288 defcompile
289 END
290 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200291enddef
292
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100293def DefListAll()
294 def
295enddef
296
297def DefListOne()
298 def DefListOne
299enddef
300
301def DefListMatches()
302 def /DefList
303enddef
304
305def Test_nested_def_list()
306 var funcs = split(execute('call DefListAll()'), "\n")
307 assert_true(len(funcs) > 10)
308 assert_true(funcs->index('def DefListAll()') >= 0)
309
310 funcs = split(execute('call DefListOne()'), "\n")
311 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
312
313 funcs = split(execute('call DefListMatches()'), "\n")
314 assert_true(len(funcs) >= 3)
315 assert_true(funcs->index('def DefListAll()') >= 0)
316 assert_true(funcs->index('def DefListOne()') >= 0)
317 assert_true(funcs->index('def DefListMatches()') >= 0)
318enddef
319
Bram Moolenaar333894b2020-08-01 18:53:07 +0200320def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200321 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200322 vim9script
323 def g:Func(): string
324 return 'global'
325 enddef
326 def Func(): string
327 return 'local'
328 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200329 g:Func()->assert_equal('global')
330 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100331 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +0200332 END
333 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200334
335 lines =<< trim END
336 vim9script
337 def g:Funcy()
338 echo 'funcy'
339 enddef
340 s:Funcy()
341 END
342 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200343enddef
344
Bram Moolenaar0f769812020-09-12 18:32:34 +0200345def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200346 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200347 vim9script
348 def g:Gfunc(): string
349 return 'global'
350 enddef
351 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200352 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200353 return Gfunc('testing')
354 enddef
355 g:Gfunc()->assert_equal('global')
356 AnotherFunc()->assert_equal(7)
357 delfunc g:Gfunc
358 END
359 CheckScriptSuccess(lines)
360
361 lines =<< trim END
362 vim9script
363 def g:Func(): string
364 return 'global'
365 enddef
366 def AnotherFunc()
367 g:Func = function('len')
368 enddef
369 AnotherFunc()
370 END
371 CheckScriptFailure(lines, 'E705:')
372 delfunc g:Func
373enddef
374
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200375func TakesOneArg(arg)
376 echo a:arg
377endfunc
378
379def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200380 CheckDefFailure(['TakesOneArg()'], 'E119:')
381 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
382 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
383 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200384
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200385 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200386 vim9script
387 def Func(s: string)
388 echo s
389 enddef
390 Func([])
391 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200392 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200393
394 lines =<< trim END
395 vim9script
396 def FuncOne(nr: number)
397 echo nr
398 enddef
399 def FuncTwo()
400 FuncOne()
401 enddef
402 defcompile
403 END
404 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200405 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200406 try
407 source Xscript
408 catch
409 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
410 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
411 didCatch = true
412 endtry
413 assert_true(didCatch)
414
415 lines =<< trim END
416 vim9script
417 def FuncOne(nr: number)
418 echo nr
419 enddef
420 def FuncTwo()
421 FuncOne(1, 2)
422 enddef
423 defcompile
424 END
425 writefile(lines, 'Xscript')
426 didCatch = false
427 try
428 source Xscript
429 catch
430 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
431 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
432 didCatch = true
433 endtry
434 assert_true(didCatch)
435
436 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200437enddef
438
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100439def Test_call_lambda_args()
440 CheckDefFailure(['echo {i -> 0}()'],
441 'E119: Not enough arguments for function: {i -> 0}()')
442
443 var lines =<< trim END
444 var Ref = {x: number, y: number -> x + y}
445 echo Ref(1, 'x')
446 END
447 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
448enddef
449
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200450" Default arg and varargs
451def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200452 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200453 for s in rest
454 res ..= ',' .. s
455 endfor
456 return res
457enddef
458
459def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200460 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200461 MyDefVarargs('one')->assert_equal('one,foo')
462 MyDefVarargs('one', 'two')->assert_equal('one,two')
463 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200464 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200465 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200466 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200467 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200468
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200469 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200470 vim9script
471 def Func(...l: list<string>)
472 echo l
473 enddef
474 Func('a', 'b', 'c')
475 END
476 CheckScriptSuccess(lines)
477
478 lines =<< trim END
479 vim9script
480 def Func(...l: list<string>)
481 echo l
482 enddef
483 Func()
484 END
485 CheckScriptSuccess(lines)
486
487 lines =<< trim END
488 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200489 def Func(...l: any)
490 echo l
491 enddef
492 Func(0)
493 END
494 CheckScriptSuccess(lines)
495
496 lines =<< trim END
497 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200498 def Func(..._l: list<string>)
499 echo _l
500 enddef
501 Func('a', 'b', 'c')
502 END
503 CheckScriptSuccess(lines)
504
505 lines =<< trim END
506 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200507 def Func(...l: list<string>)
508 echo l
509 enddef
510 Func(1, 2, 3)
511 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200512 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200513
514 lines =<< trim END
515 vim9script
516 def Func(...l: list<string>)
517 echo l
518 enddef
519 Func('a', 9)
520 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200521 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200522
523 lines =<< trim END
524 vim9script
525 def Func(...l: list<string>)
526 echo l
527 enddef
528 Func(1, 'a')
529 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200530 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200531enddef
532
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200533let s:value = ''
534
535def FuncOneDefArg(opt = 'text')
536 s:value = opt
537enddef
538
539def FuncTwoDefArg(nr = 123, opt = 'text'): string
540 return nr .. opt
541enddef
542
543def FuncVarargs(...arg: list<string>): string
544 return join(arg, ',')
545enddef
546
547def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200548 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200549 RefDefArg = FuncOneDefArg
550 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200551 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200552 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200553 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200554
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200555 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200556 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200557 RefDef2Arg()->assert_equal('123text')
558 RefDef2Arg(99)->assert_equal('99text')
559 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200560
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200561 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
562 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200563
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200564 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200565 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200566 RefVarargs()->assert_equal('')
567 RefVarargs('one')->assert_equal('one')
568 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200569
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200570 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
571 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200572enddef
573
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200574" Only varargs
575def MyVarargsOnly(...args: list<string>): string
576 return join(args, ',')
577enddef
578
579def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200580 MyVarargsOnly()->assert_equal('')
581 MyVarargsOnly('one')->assert_equal('one')
582 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200583 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
584 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200585enddef
586
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200587def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200588 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200589 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200590 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200591enddef
592
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200593def DictArg(arg: dict<string>)
594 arg['key'] = 'value'
595enddef
596
597def ListArg(arg: list<string>)
598 arg[0] = 'value'
599enddef
600
601def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200602 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200603 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200604 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200605 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200606 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200607 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200608 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200609
Bram Moolenaard2c61702020-09-06 15:58:36 +0200610 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100611 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200612enddef
613
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200614" These argument names are reserved in legacy functions.
615def WithReservedNames(firstline: string, lastline: string): string
616 return firstline .. lastline
617enddef
618
619def Test_argument_names()
620 assert_equal('OK', WithReservedNames('O', 'K'))
621enddef
622
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200623def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200624 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200625 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200626enddef
627
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200628func DefinedLater(arg)
629 return a:arg
630endfunc
631
632def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200633 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200634 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
635 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200636
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200637 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200638 vim9script
639 def RetNumber(): number
640 return 123
641 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200642 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200643 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200644 END
645 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200646
647 lines =<< trim END
648 vim9script
649 def RetNumber(): number
650 return 123
651 enddef
652 def Bar(F: func: number): number
653 return F()
654 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200655 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200656 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200657 END
658 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200659
660 lines =<< trim END
661 vim9script
662 def UseNumber(nr: number)
663 echo nr
664 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200665 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200666 Funcref(123)
667 END
668 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200669
670 lines =<< trim END
671 vim9script
672 def UseNumber(nr: number)
673 echo nr
674 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200675 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200676 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200677 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200678
679 lines =<< trim END
680 vim9script
681 def EchoNr(nr = 34)
682 g:echo = nr
683 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200684 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200685 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200686 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200687 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200688 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200689 END
690 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200691
692 lines =<< trim END
693 vim9script
694 def EchoList(...l: list<number>)
695 g:echo = l
696 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200697 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200698 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200699 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200700 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200701 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200702 END
703 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200704
705 lines =<< trim END
706 vim9script
707 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
708 g:optarg = opt
709 g:listarg = l
710 return nr
711 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200712 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200713 Funcref(10)->assert_equal(10)
714 g:optarg->assert_equal(12)
715 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200716
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200717 Funcref(11, 22)->assert_equal(11)
718 g:optarg->assert_equal(22)
719 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200720
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200721 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
722 g:optarg->assert_equal(18)
723 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200724 END
725 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200726enddef
727
728let SomeFunc = function('len')
729let NotAFunc = 'text'
730
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200731def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200732 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200733 var Ref1: func(bool): string
734 var Ref2: func(bool): number
735 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200736 Ref3 = g:cond ? Ref1 : Ref2
737
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200738 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200739 var Refa1: func(bool): number
740 var Refa2: func(bool, number): number
741 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200742 Refa3 = g:cond ? Refa1 : Refa2
743
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200744 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200745 var Refb1: func(bool, string): number
746 var Refb2: func(string, number): number
747 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200748 Refb3 = g:cond ? Refb1 : Refb2
749enddef
750
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200751def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200752 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753enddef
754
755def DefinedEvenLater(arg: string): string
756 return arg
757enddef
758
759def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200760 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200761 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200762enddef
763
764def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200765 CheckScriptFailure([
766 'def Func(): number',
767 'return "a"',
768 'enddef',
769 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100770 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200771 CheckScriptFailure([
772 'def Func(): string',
773 'return 1',
774 'enddef',
775 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100776 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200777 CheckScriptFailure([
778 'def Func(): void',
779 'return "a"',
780 'enddef',
781 'defcompile'],
782 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100783 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200784 CheckScriptFailure([
785 'def Func()',
786 'return "a"',
787 'enddef',
788 'defcompile'],
789 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100790 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200791
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200792 CheckScriptFailure([
793 'def Func(): number',
794 'return',
795 'enddef',
796 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100797 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200798
799 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100800 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200801 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100802 delfunc! g:Func
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200803 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100804 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200805
806 CheckScriptFailure([
807 'vim9script',
808 'def FuncB()',
809 ' return 123',
810 'enddef',
811 'def FuncA()',
812 ' FuncB()',
813 'enddef',
814 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200815enddef
816
817def Test_arg_type_wrong()
818 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200819 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200820 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200821 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200822enddef
823
824def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200825 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200826 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200827 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200828 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200829 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200830 enddef
831 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200832 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200833
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200834 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200835 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200836 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200837
Bram Moolenaar67979662020-06-20 22:50:47 +0200838 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200839 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200840 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200841
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200842 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200843 def ListFunc(arg: list<number>)
844 listvar = arg
845 enddef
846 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200847 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200848
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200849 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200850 def DictFunc(arg: dict<number>)
851 dictvar = arg
852 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +0100853 {a: 1, b: 2}->DictFunc()
854 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200855 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100856 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200857 enddef
858 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100859 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200860
Bram Moolenaare0de1712020-12-02 17:36:54 +0100861 {a: 3, b: 4}->DictFunc()
862 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200863
864 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200865 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200866 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200867 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200868
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200869 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200870 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200871 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200872 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200873 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200874 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200875
876 def UseString()
877 'xyork'->MyFunc()
878 enddef
879 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200880 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200881
Bram Moolenaar10409562020-07-29 20:00:38 +0200882 def UseString2()
883 "knife"->MyFunc()
884 enddef
885 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200886 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200887
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200888 # prepending a colon makes it a mark
889 new
890 setline(1, ['aaa', 'bbb', 'ccc'])
891 normal! 3Gmt1G
892 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200893 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200894 bwipe!
895
Bram Moolenaare6b53242020-07-01 17:28:33 +0200896 MyFunc(
897 'continued'
898 )
899 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200900 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200901 )
902
903 call MyFunc(
904 'more'
905 ..
906 'lines'
907 )
908 assert_equal(
909 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200910 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200911 END
912 writefile(lines, 'Xcall.vim')
913 source Xcall.vim
914 delete('Xcall.vim')
915enddef
916
917def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200918 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200919 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200920 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200921 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200922 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200923 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200924 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200925 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200926 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200927enddef
928
Bram Moolenaar65b95452020-07-19 14:03:09 +0200929def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200930 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200931 vim9script
932 def MyFunc(arg: string)
933 echo arg
934 enddef
935 MyFunc(1234)
936 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200937 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200938enddef
939
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200940def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200941 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200942 vim9script
943 const var = ''
944 def MyFunc(arg: string)
945 var = 'asdf'
946 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200947 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200948 END
949 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200950 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200951 delete('Xcall_const.vim')
952enddef
953
954" Test that inside :function a Python function can be defined, :def is not
955" recognized.
956func Test_function_python()
957 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200958 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200959 execute py "<< EOF"
960def do_something():
961 return 1
962EOF
963endfunc
964
965def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200966 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200967 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200968 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200969 echo 'hello'
970 enddef
971
972 def CallGoneSoon()
973 GoneSoon()
974 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200975 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200976
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200977 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200978 CallGoneSoon()
979 END
980 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200981 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
982 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200983
984 delete('XToDelFunc')
985enddef
986
987def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200988 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200989 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200990 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200991 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200992 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200993 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200994 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200995 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200996 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200997
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200998 g:Func0()->assert_equal(0)
999 g:Func1()->assert_equal('Func1')
1000 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001001
1002 delfunc! Func0
1003 delfunc! Func1
1004 delfunc! Func2
1005enddef
1006
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001007def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001008 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001009 vim9script
1010 func Func(arg)
1011 echo a:arg
1012 endfunc
1013 Func('text')
1014 END
1015 writefile(lines, 'XVim9Func')
1016 so XVim9Func
1017
1018 delete('XVim9Func')
1019enddef
1020
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001021let s:funcResult = 0
1022
1023def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001024 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001025enddef
1026
1027def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001028 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001029 return 1234
1030enddef
1031
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001032def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001033 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001034 return 'text'
1035enddef
1036
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001037def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001038 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001039enddef
1040
1041def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001042 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001043 return arg
1044enddef
1045
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001046def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001047 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001048enddef
1049
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001050def FuncOneArgRetString(arg: string): string
1051 return arg
1052enddef
1053
Bram Moolenaar89228602020-04-05 22:14:54 +02001054def FuncOneArgRetAny(arg: any): any
1055 return arg
1056enddef
1057
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001058def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001059 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001060 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001061 Ref1 = FuncNoArgNoRet
1062 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001063 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001064
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001065 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001066 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001067 Ref2 = FuncNoArgNoRet
1068 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001069 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001070
Bram Moolenaar53900992020-08-22 19:02:02 +02001071 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001072 Ref2 = FuncOneArgNoRet
1073 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001074 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001075
Bram Moolenaar53900992020-08-22 19:02:02 +02001076 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001077 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001078 Ref2()->assert_equal(1234)
1079 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001080
Bram Moolenaar53900992020-08-22 19:02:02 +02001081 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001082 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001083 Ref2(13)->assert_equal(13)
1084 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001085enddef
1086
Bram Moolenaar9978d472020-07-05 16:01:56 +02001087def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001088 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001089 for n in repeat([1], 3)
1090 res += n
1091 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001092 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001093
1094 res = 0
1095 for n in add([1, 2], 3)
1096 res += n
1097 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001098 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001099enddef
1100
Bram Moolenaar846178a2020-07-05 17:04:13 +02001101def Test_argv_return_type()
1102 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001103 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001104 for name in argv()
1105 res ..= name
1106 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001107 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001108enddef
1109
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001110def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001111 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001112 RefVoid = FuncNoArgNoRet
1113 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001114 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1115 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001116
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001117 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001118 RefAny = FuncNoArgRetNumber
1119 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001120 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1121 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001122
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001123 var RefAnyNoArgs: func: any = RefAny
1124
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001125 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001126 RefNr = FuncNoArgRetNumber
1127 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001128 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1129 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001130
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001131 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001132 RefStr = FuncNoArgRetString
1133 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001134 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1135 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001136enddef
1137
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001138def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001139 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001140
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001141 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1142 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1143 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1144 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1145 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1146 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 +02001147
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001148 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1149 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1150 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:')
1151 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001152enddef
1153
Bram Moolenaar89228602020-04-05 22:14:54 +02001154def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001155 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001156 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001157 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001158
1159 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001160 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001161
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001162 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001163 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001164 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001165
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001166 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001167enddef
1168
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001169def Test_func_common_type()
1170 def FuncOne(n: number): number
1171 return n
1172 enddef
1173 def FuncTwo(s: string): number
1174 return len(s)
1175 enddef
1176 def FuncThree(n: number, s: string): number
1177 return n + len(s)
1178 enddef
1179 var list = [FuncOne, FuncTwo, FuncThree]
1180 assert_equal(8, list[0](8))
1181 assert_equal(4, list[1]('word'))
1182 assert_equal(7, list[2](3, 'word'))
1183enddef
1184
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001185def MultiLine(
1186 arg1: string,
1187 arg2 = 1234,
1188 ...rest: list<string>
1189 ): string
1190 return arg1 .. arg2 .. join(rest, '-')
1191enddef
1192
Bram Moolenaar2c330432020-04-13 14:41:35 +02001193def MultiLineComment(
1194 arg1: string, # comment
1195 arg2 = 1234, # comment
1196 ...rest: list<string> # comment
1197 ): string # comment
1198 return arg1 .. arg2 .. join(rest, '-')
1199enddef
1200
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001201def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001202 MultiLine('text')->assert_equal('text1234')
1203 MultiLine('text', 777)->assert_equal('text777')
1204 MultiLine('text', 777, 'one')->assert_equal('text777one')
1205 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001206enddef
1207
Bram Moolenaar23e03252020-04-12 22:22:31 +02001208func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001209 call MultiLine('text')->assert_equal('text1234')
1210 call MultiLine('text', 777)->assert_equal('text777')
1211 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1212 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001213endfunc
1214
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001215
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001216" When using CheckScriptFailure() for the below test, E1010 is generated instead
1217" of E1056.
1218func Test_E1056_1059()
1219 let caught_1056 = 0
1220 try
1221 def F():
1222 return 1
1223 enddef
1224 catch /E1056:/
1225 let caught_1056 = 1
1226 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001227 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001228
1229 let caught_1059 = 0
1230 try
1231 def F5(items : list)
1232 echo 'a'
1233 enddef
1234 catch /E1059:/
1235 let caught_1059 = 1
1236 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001237 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001238endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001239
Bram Moolenaar015f4262020-05-05 21:25:22 +02001240func DelMe()
1241 echo 'DelMe'
1242endfunc
1243
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001244def Test_error_reporting()
1245 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001246 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001247 " comment
1248 def Func()
1249 # comment
1250 # comment
1251 invalid
1252 enddef
1253 defcompile
1254 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001255 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001256 try
1257 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001258 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001259 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001260 v:exception->assert_match('Invalid command: invalid')
1261 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001262 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001263 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001264
1265 # comment lines after the start of the function
1266 lines =<< trim END
1267 " comment
1268 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001269 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001270 # comment
1271 # comment
1272 invalid
1273 enddef
1274 defcompile
1275 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001276 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001277 try
1278 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001279 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001280 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001281 v:exception->assert_match('Invalid command: invalid')
1282 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001283 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001284 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001285
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001286 lines =<< trim END
1287 vim9script
1288 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001289 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001290 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001291 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001292 enddef
1293 defcompile
1294 Func()
1295 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001296 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001297 try
1298 source Xdef
1299 assert_report('should have failed')
1300 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001301 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001302 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001303 delfunc! g:Func
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001304
Bram Moolenaar08052222020-09-14 17:04:31 +02001305 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001306enddef
1307
Bram Moolenaar015f4262020-05-05 21:25:22 +02001308def Test_deleted_function()
1309 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001310 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001311 'delfunc g:DelMe',
1312 'echo RefMe()'], 'E117:')
1313enddef
1314
1315def Test_unknown_function()
1316 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001317 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001318 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001319enddef
1320
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001321def RefFunc(Ref: func(string): string): string
1322 return Ref('more')
1323enddef
1324
1325def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001326 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001327 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001328enddef
1329
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001330def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001331 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001332 g:Ref = {s -> local .. s}
1333enddef
1334
1335def Test_closure_ref_after_return()
1336 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001337 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001338 unlet g:Ref
1339enddef
1340
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001341def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001342 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001343 g:Extend = {s -> local->add(s)}
1344 g:Read = {-> local}
1345enddef
1346
1347def Test_closure_two_refs()
1348 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001349 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001350 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001351 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001352 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001353 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001354
1355 unlet g:Extend
1356 unlet g:Read
1357enddef
1358
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001359def ReadRef(Ref: func(): list<string>): string
1360 return join(Ref(), ' ')
1361enddef
1362
Bram Moolenaar5e654232020-09-16 15:22:00 +02001363def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001364 Ref(add)
1365enddef
1366
1367def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001368 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001369 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001370 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001371 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001372 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001373 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001374
1375 unlet g:Extend
1376 unlet g:Read
1377enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001378
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001379def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001380 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001381 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1382enddef
1383
1384def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001385 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001386 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1387enddef
1388
1389def Test_closure_using_argument()
1390 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001391 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001392
1393 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001394 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001395
1396 unlet g:UseArg
1397 unlet g:UseVararg
1398enddef
1399
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001400def MakeGetAndAppendRefs()
1401 var local = 'a'
1402
1403 def Append(arg: string)
1404 local ..= arg
1405 enddef
1406 g:Append = Append
1407
1408 def Get(): string
1409 return local
1410 enddef
1411 g:Get = Get
1412enddef
1413
1414def Test_closure_append_get()
1415 MakeGetAndAppendRefs()
1416 g:Get()->assert_equal('a')
1417 g:Append('-b')
1418 g:Get()->assert_equal('a-b')
1419 g:Append('-c')
1420 g:Get()->assert_equal('a-b-c')
1421
1422 unlet g:Append
1423 unlet g:Get
1424enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001425
Bram Moolenaar04b12692020-05-04 23:24:44 +02001426def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001427 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001428 def Closure(arg: string): string
1429 return local .. arg
1430 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001431 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001432enddef
1433
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001434func GetResult(Ref)
1435 return a:Ref('some')
1436endfunc
1437
1438def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001439 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001440 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001441 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001442enddef
1443
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001444def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001445 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001446 vim9script
1447 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001448 var name = 0
1449 for i in range(2)
1450 timer_start(0, {-> name})
1451 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001452 enddef
1453 Func()
1454 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001455 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001456enddef
1457
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001458def Test_nested_closure_used()
1459 var lines =<< trim END
1460 vim9script
1461 def Func()
1462 var x = 'hello'
1463 var Closure = {-> x}
1464 g:Myclosure = {-> Closure()}
1465 enddef
1466 Func()
1467 assert_equal('hello', g:Myclosure())
1468 END
1469 CheckScriptSuccess(lines)
1470enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001471
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001472def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001473 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001474 vim9script
1475 def FuncA()
1476 FuncB(0)
1477 enddef
1478 def FuncB(n: number): list<string>
1479 return map([0], {_, v -> n})
1480 enddef
1481 FuncA()
1482 END
1483 CheckScriptFailure(lines, 'E1012:')
1484enddef
1485
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01001486def Test_failure_in_called_function()
1487 # this was using the frame index as the return value
1488 var lines =<< trim END
1489 vim9script
1490 au TerminalWinOpen * eval [][0]
1491 def PopupTerm(a: any)
1492 # make sure typvals on stack are string
1493 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1494 FireEvent()
1495 enddef
1496 def FireEvent()
1497 do TerminalWinOpen
1498 enddef
1499 # use try/catch to make eval fail
1500 try
1501 call PopupTerm(0)
1502 catch
1503 endtry
1504 au! TerminalWinOpen
1505 END
1506 CheckScriptSuccess(lines)
1507enddef
1508
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001509def Test_nested_lambda()
1510 var lines =<< trim END
1511 vim9script
1512 def Func()
1513 var x = 4
1514 var Lambda1 = {-> 7}
1515 var Lambda2 = {-> [Lambda1(), x]}
1516 var res = Lambda2()
1517 assert_equal([7, 4], res)
1518 enddef
1519 Func()
1520 END
1521 CheckScriptSuccess(lines)
1522enddef
1523
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001524def Shadowed(): list<number>
1525 var FuncList: list<func: number> = [{ -> 42}]
1526 return FuncList->map({_, Shadowed -> Shadowed()})
1527enddef
1528
1529def Test_lambda_arg_shadows_func()
1530 assert_equal([42], Shadowed())
1531enddef
1532
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001533def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001534 var path: string = empty(dir)
1535 \ ? 'empty'
1536 \ : 'full'
1537 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001538enddef
1539
1540def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001541 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001542enddef
1543
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001544def Test_script_var_in_lambda()
1545 var lines =<< trim END
1546 vim9script
1547 var script = 'test'
1548 assert_equal(['test'], map(['one'], {-> script}))
1549 END
1550 CheckScriptSuccess(lines)
1551enddef
1552
Bram Moolenaar5e654232020-09-16 15:22:00 +02001553def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001554 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001555 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001556 ->toupper()})
1557 ->reverse()
1558 return x
1559enddef
1560
1561def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001562 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001563enddef
1564
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001565func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001566 CheckScreendump
1567
1568 let lines =<< trim END
1569 vim9script
1570 def EchoNothing()
1571 silent echo ''
1572 enddef
1573 defcompile
1574 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001575 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001576
1577 " Check that the balloon shows up after a mouse move
1578 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001579 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001580 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1581
1582 " clean up
1583 call StopVimInTerminal(buf)
1584 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001585endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001586
Bram Moolenaar171fb922020-10-28 16:54:47 +01001587def SilentlyError()
1588 execute('silent! invalid')
1589 g:did_it = 'yes'
1590enddef
1591
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001592func UserError()
1593 silent! invalid
1594endfunc
1595
1596def SilentlyUserError()
1597 UserError()
1598 g:did_it = 'yes'
1599enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001600
1601" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001602func Test_ignore_silent_error()
1603 let g:did_it = 'no'
1604 call SilentlyError()
1605 call assert_equal('yes', g:did_it)
1606
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001607 let g:did_it = 'no'
1608 call SilentlyUserError()
1609 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001610
1611 unlet g:did_it
1612endfunc
1613
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001614def Test_ignore_silent_error_in_filter()
1615 var lines =<< trim END
1616 vim9script
1617 def Filter(winid: number, key: string): bool
1618 if key == 'o'
1619 silent! eval [][0]
1620 return true
1621 endif
1622 return popup_filter_menu(winid, key)
1623 enddef
1624
Bram Moolenaare0de1712020-12-02 17:36:54 +01001625 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001626 feedkeys("o\r", 'xnt')
1627 END
1628 CheckScriptSuccess(lines)
1629enddef
1630
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001631def Fibonacci(n: number): number
1632 if n < 2
1633 return n
1634 else
1635 return Fibonacci(n - 1) + Fibonacci(n - 2)
1636 endif
1637enddef
1638
Bram Moolenaar985116a2020-07-12 17:31:09 +02001639def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001640 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001641enddef
1642
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001643def TreeWalk(dir: string): list<any>
1644 return readdir(dir)->map({_, val ->
1645 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001646 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001647 : val
1648 })
1649enddef
1650
1651def Test_closure_in_map()
1652 mkdir('XclosureDir/tdir', 'p')
1653 writefile(['111'], 'XclosureDir/file1')
1654 writefile(['222'], 'XclosureDir/file2')
1655 writefile(['333'], 'XclosureDir/tdir/file3')
1656
Bram Moolenaare0de1712020-12-02 17:36:54 +01001657 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001658
1659 delete('XclosureDir', 'rf')
1660enddef
1661
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001662def Test_invalid_function_name()
1663 var lines =<< trim END
1664 vim9script
1665 def s: list<string>
1666 END
1667 CheckScriptFailure(lines, 'E129:')
1668
1669 lines =<< trim END
1670 vim9script
1671 def g: list<string>
1672 END
1673 CheckScriptFailure(lines, 'E129:')
1674
1675 lines =<< trim END
1676 vim9script
1677 def <SID>: list<string>
1678 END
1679 CheckScriptFailure(lines, 'E884:')
1680
1681 lines =<< trim END
1682 vim9script
1683 def F list<string>
1684 END
1685 CheckScriptFailure(lines, 'E488:')
1686enddef
1687
Bram Moolenaara90afb92020-07-15 22:38:56 +02001688def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001689 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001690 Xsetlist([], ' ', {title: 'test'})
1691 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001692
1693 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001694 Xsetlist({title: 'test'})
1695 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001696
1697 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001698 Xsetlist([], ' ', {title: 'test'})
1699 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001700
1701 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001702 Xsetlist({title: 'test'})
1703 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001704
1705 var Len: func: number = function('len', ['word'])
1706 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001707enddef
1708
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001709def Test_cmd_modifier()
1710 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001711 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001712enddef
1713
1714def Test_restore_modifiers()
1715 # check that when compiling a :def function command modifiers are not messed
1716 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001717 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001718 vim9script
1719 set eventignore=
1720 autocmd QuickFixCmdPost * copen
1721 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001722 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001723 enddef
1724 func Func()
1725 noautocmd call s:AutocmdsDisabled()
1726 let g:ei_after = &eventignore
1727 endfunc
1728 Func()
1729 END
1730 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001731 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001732enddef
1733
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001734def StackTop()
1735 eval 1
1736 eval 2
1737 # call not on fourth line
1738 StackBot()
1739enddef
1740
1741def StackBot()
1742 # throw an error
1743 eval [][0]
1744enddef
1745
1746def Test_callstack_def()
1747 try
1748 StackTop()
1749 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001750 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001751 endtry
1752enddef
1753
Bram Moolenaare8211a32020-10-09 22:04:29 +02001754" Re-using spot for variable used in block
1755def Test_block_scoped_var()
1756 var lines =<< trim END
1757 vim9script
1758 def Func()
1759 var x = ['a', 'b', 'c']
1760 if 1
1761 var y = 'x'
1762 map(x, {-> y})
1763 endif
1764 var z = x
1765 assert_equal(['x', 'x', 'x'], z)
1766 enddef
1767 Func()
1768 END
1769 CheckScriptSuccess(lines)
1770enddef
1771
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001772def Test_reset_did_emsg()
1773 var lines =<< trim END
1774 @s = 'blah'
1775 au BufWinLeave * #
1776 def Func()
1777 var winid = popup_create('popup', {})
1778 exe '*s'
1779 popup_close(winid)
1780 enddef
1781 Func()
1782 END
1783 CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001784 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001785enddef
1786
Bram Moolenaarf665e972020-12-05 19:17:16 +01001787def Test_continues_with_silent_error()
1788 var lines =<< trim END
1789 vim9script
1790 g:result = 'none'
1791 def Func()
1792 silent! g:result += 3
1793 g:result = 'yes'
1794 enddef
1795 # error is silenced, function does not abort
1796 Func()
1797 assert_equal('yes', g:result)
1798 unlet g:result
1799 END
1800 CheckScriptSuccess(lines)
1801enddef
1802
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001803def Test_abort_even_with_silent()
1804 var lines =<< trim END
1805 vim9script
1806 g:result = 'none'
1807 def Func()
1808 eval {-> ''}() .. '' .. {}['X']
1809 g:result = 'yes'
1810 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01001811 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001812 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001813 unlet g:result
1814 END
1815 CheckScriptSuccess(lines)
1816enddef
1817
Bram Moolenaarf665e972020-12-05 19:17:16 +01001818def Test_cmdmod_silent_restored()
1819 var lines =<< trim END
1820 vim9script
1821 def Func()
1822 g:result = 'none'
1823 silent! g:result += 3
1824 g:result = 'none'
1825 g:result += 3
1826 enddef
1827 Func()
1828 END
1829 # can't use CheckScriptFailure, it ignores the :silent!
1830 var fname = 'Xdefsilent'
1831 writefile(lines, fname)
1832 var caught = 'no'
1833 try
1834 exe 'source ' .. fname
1835 catch /E1030:/
1836 caught = 'yes'
1837 assert_match('Func, line 4', v:throwpoint)
1838 endtry
1839 assert_equal('yes', caught)
1840 delete(fname)
1841enddef
1842
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001843def Test_dict_member_with_silent()
1844 var lines =<< trim END
1845 vim9script
1846 g:result = 'none'
1847 var d: dict<any>
1848 def Func()
1849 try
1850 g:result = map([], {_, v -> {}[v]})->join() .. d['']
1851 catch
1852 endtry
1853 enddef
1854 silent! Func()
1855 assert_equal('0', g:result)
1856 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001857 END
1858 CheckScriptSuccess(lines)
1859enddef
1860
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001861
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001862" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker