blob: fcfe41f2f47b4ba178f65cc35ba462afa5f34f40 [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 Moolenaar50824712020-12-20 21:10:17 +0100473def Test_call_funcref_wrong_args()
474 var head =<< trim END
475 vim9script
476 def Func3(a1: string, a2: number, a3: list<number>)
477 echo a1 .. a2 .. a3[0]
478 enddef
479 def Testme()
480 var funcMap: dict<func> = {func: Func3}
481 END
482 var tail =<< trim END
483 enddef
484 Testme()
485 END
486 CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
487
488 CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
489 CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
490enddef
491
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100492def Test_call_lambda_args()
493 CheckDefFailure(['echo {i -> 0}()'],
494 'E119: Not enough arguments for function: {i -> 0}()')
495
496 var lines =<< trim END
497 var Ref = {x: number, y: number -> x + y}
498 echo Ref(1, 'x')
499 END
500 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
501enddef
502
Bram Moolenaar709664c2020-12-12 14:33:41 +0100503def Test_lambda_uses_assigned_var()
504 CheckDefSuccess([
505 'var x: any = "aaa"'
506 'x = filter(["bbb"], {_, v -> v =~ x})'])
507enddef
508
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200509" Default arg and varargs
510def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200511 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200512 for s in rest
513 res ..= ',' .. s
514 endfor
515 return res
516enddef
517
518def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200519 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200520 MyDefVarargs('one')->assert_equal('one,foo')
521 MyDefVarargs('one', 'two')->assert_equal('one,two')
522 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200523 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200524 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200525 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200526 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200527
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200528 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200529 vim9script
530 def Func(...l: list<string>)
531 echo l
532 enddef
533 Func('a', 'b', 'c')
534 END
535 CheckScriptSuccess(lines)
536
537 lines =<< trim END
538 vim9script
539 def Func(...l: list<string>)
540 echo l
541 enddef
542 Func()
543 END
544 CheckScriptSuccess(lines)
545
546 lines =<< trim END
547 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200548 def Func(...l: any)
549 echo l
550 enddef
551 Func(0)
552 END
553 CheckScriptSuccess(lines)
554
555 lines =<< trim END
556 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200557 def Func(..._l: list<string>)
558 echo _l
559 enddef
560 Func('a', 'b', 'c')
561 END
562 CheckScriptSuccess(lines)
563
564 lines =<< trim END
565 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200566 def Func(...l: list<string>)
567 echo l
568 enddef
569 Func(1, 2, 3)
570 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200571 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200572
573 lines =<< trim END
574 vim9script
575 def Func(...l: list<string>)
576 echo l
577 enddef
578 Func('a', 9)
579 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200580 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200581
582 lines =<< trim END
583 vim9script
584 def Func(...l: list<string>)
585 echo l
586 enddef
587 Func(1, 'a')
588 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200589 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200590enddef
591
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200592let s:value = ''
593
594def FuncOneDefArg(opt = 'text')
595 s:value = opt
596enddef
597
598def FuncTwoDefArg(nr = 123, opt = 'text'): string
599 return nr .. opt
600enddef
601
602def FuncVarargs(...arg: list<string>): string
603 return join(arg, ',')
604enddef
605
606def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200607 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200608 RefDefArg = FuncOneDefArg
609 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200610 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200611 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200612 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200613
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200614 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200615 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200616 RefDef2Arg()->assert_equal('123text')
617 RefDef2Arg(99)->assert_equal('99text')
618 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200619
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200620 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
621 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200622
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200623 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200624 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200625 RefVarargs()->assert_equal('')
626 RefVarargs('one')->assert_equal('one')
627 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200628
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200629 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
630 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200631enddef
632
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200633" Only varargs
634def MyVarargsOnly(...args: list<string>): string
635 return join(args, ',')
636enddef
637
638def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200639 MyVarargsOnly()->assert_equal('')
640 MyVarargsOnly('one')->assert_equal('one')
641 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200642 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
643 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200644enddef
645
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200646def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200647 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200648 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200649 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200650enddef
651
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200652def DictArg(arg: dict<string>)
653 arg['key'] = 'value'
654enddef
655
656def ListArg(arg: list<string>)
657 arg[0] = 'value'
658enddef
659
660def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200661 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200662 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200663 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200664 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200665 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200666 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200667 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200668
Bram Moolenaard2c61702020-09-06 15:58:36 +0200669 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100670 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200671enddef
672
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200673" These argument names are reserved in legacy functions.
674def WithReservedNames(firstline: string, lastline: string): string
675 return firstline .. lastline
676enddef
677
678def Test_argument_names()
679 assert_equal('OK', WithReservedNames('O', 'K'))
680enddef
681
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200682def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200683 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200684 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200685enddef
686
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200687func DefinedLater(arg)
688 return a:arg
689endfunc
690
691def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200692 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200693 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
694 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200695
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200696 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200697 vim9script
698 def RetNumber(): number
699 return 123
700 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200701 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200702 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200703 END
704 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200705
706 lines =<< trim END
707 vim9script
708 def RetNumber(): number
709 return 123
710 enddef
711 def Bar(F: func: number): number
712 return F()
713 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200714 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200715 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200716 END
717 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200718
719 lines =<< trim END
720 vim9script
721 def UseNumber(nr: number)
722 echo nr
723 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200724 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200725 Funcref(123)
726 END
727 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200728
729 lines =<< trim END
730 vim9script
731 def UseNumber(nr: number)
732 echo nr
733 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200734 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200735 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200736 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200737
738 lines =<< trim END
739 vim9script
740 def EchoNr(nr = 34)
741 g:echo = nr
742 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200743 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200744 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200745 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200746 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200747 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200748 END
749 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200750
751 lines =<< trim END
752 vim9script
753 def EchoList(...l: list<number>)
754 g:echo = l
755 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200756 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200757 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200758 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200759 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200760 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200761 END
762 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200763
764 lines =<< trim END
765 vim9script
766 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
767 g:optarg = opt
768 g:listarg = l
769 return nr
770 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200771 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200772 Funcref(10)->assert_equal(10)
773 g:optarg->assert_equal(12)
774 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200775
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200776 Funcref(11, 22)->assert_equal(11)
777 g:optarg->assert_equal(22)
778 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200779
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200780 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
781 g:optarg->assert_equal(18)
782 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200783 END
784 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200785enddef
786
787let SomeFunc = function('len')
788let NotAFunc = 'text'
789
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200790def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200791 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200792 var Ref1: func(bool): string
793 var Ref2: func(bool): number
794 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200795 Ref3 = g:cond ? Ref1 : Ref2
796
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200797 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200798 var Refa1: func(bool): number
799 var Refa2: func(bool, number): number
800 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200801 Refa3 = g:cond ? Refa1 : Refa2
802
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200803 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200804 var Refb1: func(bool, string): number
805 var Refb2: func(string, number): number
806 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200807 Refb3 = g:cond ? Refb1 : Refb2
808enddef
809
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200810def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200811 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200812enddef
813
814def DefinedEvenLater(arg: string): string
815 return arg
816enddef
817
818def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200819 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200820 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200821enddef
822
823def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200824 CheckScriptFailure([
825 'def Func(): number',
826 'return "a"',
827 'enddef',
828 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100829 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200830 CheckScriptFailure([
831 'def Func(): string',
832 'return 1',
833 'enddef',
834 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100835 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200836 CheckScriptFailure([
837 'def Func(): void',
838 'return "a"',
839 'enddef',
840 'defcompile'],
841 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100842 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200843 CheckScriptFailure([
844 'def Func()',
845 'return "a"',
846 'enddef',
847 'defcompile'],
848 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100849 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200850
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200851 CheckScriptFailure([
852 'def Func(): number',
853 'return',
854 'enddef',
855 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100856 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200857
858 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100859 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200860 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100861 delfunc! g:Func
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200862 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100863 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200864
865 CheckScriptFailure([
866 'vim9script',
867 'def FuncB()',
868 ' return 123',
869 'enddef',
870 'def FuncA()',
871 ' FuncB()',
872 'enddef',
873 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200874enddef
875
876def Test_arg_type_wrong()
877 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200878 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200879 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200880 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200881enddef
882
883def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200884 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200885 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200886 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200887 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200888 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200889 enddef
890 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200891 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200892
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200893 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200894 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200895 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200896
Bram Moolenaar67979662020-06-20 22:50:47 +0200897 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200898 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200899 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200900
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200901 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200902 def ListFunc(arg: list<number>)
903 listvar = arg
904 enddef
905 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200906 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200907
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200908 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909 def DictFunc(arg: dict<number>)
910 dictvar = arg
911 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +0100912 {a: 1, b: 2}->DictFunc()
913 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200914 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100915 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200916 enddef
917 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100918 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200919
Bram Moolenaare0de1712020-12-02 17:36:54 +0100920 {a: 3, b: 4}->DictFunc()
921 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200922
923 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200924 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200925 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200926 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200927
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200928 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200929 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200930 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200931 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200932 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200933 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200934
935 def UseString()
936 'xyork'->MyFunc()
937 enddef
938 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200939 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200940
Bram Moolenaar10409562020-07-29 20:00:38 +0200941 def UseString2()
942 "knife"->MyFunc()
943 enddef
944 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200945 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200946
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200947 # prepending a colon makes it a mark
948 new
949 setline(1, ['aaa', 'bbb', 'ccc'])
950 normal! 3Gmt1G
951 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200952 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200953 bwipe!
954
Bram Moolenaare6b53242020-07-01 17:28:33 +0200955 MyFunc(
956 'continued'
957 )
958 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200959 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200960 )
961
962 call MyFunc(
963 'more'
964 ..
965 'lines'
966 )
967 assert_equal(
968 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200969 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200970 END
971 writefile(lines, 'Xcall.vim')
972 source Xcall.vim
973 delete('Xcall.vim')
974enddef
975
976def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200977 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200978 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200979 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200980 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200981 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200982 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200983 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200984 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200985 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200986enddef
987
Bram Moolenaar65b95452020-07-19 14:03:09 +0200988def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200989 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200990 vim9script
991 def MyFunc(arg: string)
992 echo arg
993 enddef
994 MyFunc(1234)
995 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200996 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200997enddef
998
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200999def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001000 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001001 vim9script
1002 const var = ''
1003 def MyFunc(arg: string)
1004 var = 'asdf'
1005 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001006 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001007 END
1008 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001009 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001010 delete('Xcall_const.vim')
1011enddef
1012
1013" Test that inside :function a Python function can be defined, :def is not
1014" recognized.
1015func Test_function_python()
1016 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02001017 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001018 execute py "<< EOF"
1019def do_something():
1020 return 1
1021EOF
1022endfunc
1023
1024def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001025 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001026 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001027 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001028 echo 'hello'
1029 enddef
1030
1031 def CallGoneSoon()
1032 GoneSoon()
1033 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001034 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001035
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001036 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001037 CallGoneSoon()
1038 END
1039 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001040 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
1041 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001042
1043 delete('XToDelFunc')
1044enddef
1045
1046def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02001047 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001048 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001049 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001050 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001051 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001052 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02001053 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001054 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001055 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001056
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001057 g:Func0()->assert_equal(0)
1058 g:Func1()->assert_equal('Func1')
1059 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001060
1061 delfunc! Func0
1062 delfunc! Func1
1063 delfunc! Func2
1064enddef
1065
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001066def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001067 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001068 vim9script
1069 func Func(arg)
1070 echo a:arg
1071 endfunc
1072 Func('text')
1073 END
1074 writefile(lines, 'XVim9Func')
1075 so XVim9Func
1076
1077 delete('XVim9Func')
1078enddef
1079
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001080let s:funcResult = 0
1081
1082def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001083 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001084enddef
1085
1086def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001087 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001088 return 1234
1089enddef
1090
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001091def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001092 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001093 return 'text'
1094enddef
1095
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001096def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001097 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001098enddef
1099
1100def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001101 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001102 return arg
1103enddef
1104
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001105def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001106 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001107enddef
1108
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001109def FuncOneArgRetString(arg: string): string
1110 return arg
1111enddef
1112
Bram Moolenaar89228602020-04-05 22:14:54 +02001113def FuncOneArgRetAny(arg: any): any
1114 return arg
1115enddef
1116
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001117def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001118 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001119 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001120 Ref1 = FuncNoArgNoRet
1121 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001122 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001123
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001124 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001125 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001126 Ref2 = FuncNoArgNoRet
1127 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001128 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001129
Bram Moolenaar53900992020-08-22 19:02:02 +02001130 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001131 Ref2 = FuncOneArgNoRet
1132 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001133 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001134
Bram Moolenaar53900992020-08-22 19:02:02 +02001135 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001136 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001137 Ref2()->assert_equal(1234)
1138 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001139
Bram Moolenaar53900992020-08-22 19:02:02 +02001140 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001141 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001142 Ref2(13)->assert_equal(13)
1143 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001144enddef
1145
Bram Moolenaar9978d472020-07-05 16:01:56 +02001146def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001147 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001148 for n in repeat([1], 3)
1149 res += n
1150 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001151 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001152
1153 res = 0
1154 for n in add([1, 2], 3)
1155 res += n
1156 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001157 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001158enddef
1159
Bram Moolenaar846178a2020-07-05 17:04:13 +02001160def Test_argv_return_type()
1161 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001162 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001163 for name in argv()
1164 res ..= name
1165 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001166 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001167enddef
1168
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001169def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001170 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001171 RefVoid = FuncNoArgNoRet
1172 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001173 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1174 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001175
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001176 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001177 RefAny = FuncNoArgRetNumber
1178 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001179 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1180 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001181
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001182 var RefAnyNoArgs: func: any = RefAny
1183
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001184 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001185 RefNr = FuncNoArgRetNumber
1186 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001187 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1188 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001189
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001190 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001191 RefStr = FuncNoArgRetString
1192 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001193 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1194 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001195enddef
1196
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001197def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001198 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001199
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001200 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1201 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1202 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1203 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1204 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1205 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 +02001206
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001207 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1208 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1209 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:')
1210 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001211enddef
1212
Bram Moolenaar89228602020-04-05 22:14:54 +02001213def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001214 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001215 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001216 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001217
1218 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001219 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001220
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001221 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001222 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001223 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001224
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001225 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001226enddef
1227
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001228def Test_func_common_type()
1229 def FuncOne(n: number): number
1230 return n
1231 enddef
1232 def FuncTwo(s: string): number
1233 return len(s)
1234 enddef
1235 def FuncThree(n: number, s: string): number
1236 return n + len(s)
1237 enddef
1238 var list = [FuncOne, FuncTwo, FuncThree]
1239 assert_equal(8, list[0](8))
1240 assert_equal(4, list[1]('word'))
1241 assert_equal(7, list[2](3, 'word'))
1242enddef
1243
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001244def MultiLine(
1245 arg1: string,
1246 arg2 = 1234,
1247 ...rest: list<string>
1248 ): string
1249 return arg1 .. arg2 .. join(rest, '-')
1250enddef
1251
Bram Moolenaar2c330432020-04-13 14:41:35 +02001252def MultiLineComment(
1253 arg1: string, # comment
1254 arg2 = 1234, # comment
1255 ...rest: list<string> # comment
1256 ): string # comment
1257 return arg1 .. arg2 .. join(rest, '-')
1258enddef
1259
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001260def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001261 MultiLine('text')->assert_equal('text1234')
1262 MultiLine('text', 777)->assert_equal('text777')
1263 MultiLine('text', 777, 'one')->assert_equal('text777one')
1264 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001265enddef
1266
Bram Moolenaar23e03252020-04-12 22:22:31 +02001267func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001268 call MultiLine('text')->assert_equal('text1234')
1269 call MultiLine('text', 777)->assert_equal('text777')
1270 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1271 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001272endfunc
1273
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001274
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001275" When using CheckScriptFailure() for the below test, E1010 is generated instead
1276" of E1056.
1277func Test_E1056_1059()
1278 let caught_1056 = 0
1279 try
1280 def F():
1281 return 1
1282 enddef
1283 catch /E1056:/
1284 let caught_1056 = 1
1285 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001286 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001287
1288 let caught_1059 = 0
1289 try
1290 def F5(items : list)
1291 echo 'a'
1292 enddef
1293 catch /E1059:/
1294 let caught_1059 = 1
1295 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001296 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001297endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001298
Bram Moolenaar015f4262020-05-05 21:25:22 +02001299func DelMe()
1300 echo 'DelMe'
1301endfunc
1302
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001303def Test_error_reporting()
1304 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001305 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001306 " comment
1307 def Func()
1308 # comment
1309 # comment
1310 invalid
1311 enddef
1312 defcompile
1313 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001314 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001315 try
1316 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001317 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001318 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001319 v:exception->assert_match('Invalid command: invalid')
1320 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001321 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001322 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001323
1324 # comment lines after the start of the function
1325 lines =<< trim END
1326 " comment
1327 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001328 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001329 # comment
1330 # comment
1331 invalid
1332 enddef
1333 defcompile
1334 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001335 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001336 try
1337 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001338 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001339 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001340 v:exception->assert_match('Invalid command: invalid')
1341 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001342 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001343 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001344
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001345 lines =<< trim END
1346 vim9script
1347 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001348 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001349 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001350 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001351 enddef
1352 defcompile
1353 Func()
1354 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001355 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001356 try
1357 source Xdef
1358 assert_report('should have failed')
1359 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001360 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001361 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001362 delfunc! g:Func
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001363
Bram Moolenaar08052222020-09-14 17:04:31 +02001364 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001365enddef
1366
Bram Moolenaar015f4262020-05-05 21:25:22 +02001367def Test_deleted_function()
1368 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001369 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001370 'delfunc g:DelMe',
1371 'echo RefMe()'], 'E117:')
1372enddef
1373
1374def Test_unknown_function()
1375 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001376 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001377 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001378enddef
1379
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001380def RefFunc(Ref: func(string): string): string
1381 return Ref('more')
1382enddef
1383
1384def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001385 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001386 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001387enddef
1388
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001389def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001390 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001391 g:Ref = {s -> local .. s}
1392enddef
1393
1394def Test_closure_ref_after_return()
1395 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001396 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001397 unlet g:Ref
1398enddef
1399
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001400def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001401 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001402 g:Extend = {s -> local->add(s)}
1403 g:Read = {-> local}
1404enddef
1405
1406def Test_closure_two_refs()
1407 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001408 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001409 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001410 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001411 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001412 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001413
1414 unlet g:Extend
1415 unlet g:Read
1416enddef
1417
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001418def ReadRef(Ref: func(): list<string>): string
1419 return join(Ref(), ' ')
1420enddef
1421
Bram Moolenaar5e654232020-09-16 15:22:00 +02001422def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001423 Ref(add)
1424enddef
1425
1426def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001427 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001428 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001429 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001430 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001431 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001432 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001433
1434 unlet g:Extend
1435 unlet g:Read
1436enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001437
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001438def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001439 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001440 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1441enddef
1442
1443def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001444 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001445 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1446enddef
1447
1448def Test_closure_using_argument()
1449 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001450 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001451
1452 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001453 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001454
1455 unlet g:UseArg
1456 unlet g:UseVararg
1457enddef
1458
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001459def MakeGetAndAppendRefs()
1460 var local = 'a'
1461
1462 def Append(arg: string)
1463 local ..= arg
1464 enddef
1465 g:Append = Append
1466
1467 def Get(): string
1468 return local
1469 enddef
1470 g:Get = Get
1471enddef
1472
1473def Test_closure_append_get()
1474 MakeGetAndAppendRefs()
1475 g:Get()->assert_equal('a')
1476 g:Append('-b')
1477 g:Get()->assert_equal('a-b')
1478 g:Append('-c')
1479 g:Get()->assert_equal('a-b-c')
1480
1481 unlet g:Append
1482 unlet g:Get
1483enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001484
Bram Moolenaar04b12692020-05-04 23:24:44 +02001485def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001486 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001487 def Closure(arg: string): string
1488 return local .. arg
1489 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001490 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001491enddef
1492
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001493func GetResult(Ref)
1494 return a:Ref('some')
1495endfunc
1496
1497def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001498 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001499 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001500 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001501enddef
1502
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001503def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001504 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001505 vim9script
1506 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001507 var name = 0
1508 for i in range(2)
1509 timer_start(0, {-> name})
1510 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001511 enddef
1512 Func()
1513 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001514 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001515enddef
1516
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001517def Test_nested_closure_used()
1518 var lines =<< trim END
1519 vim9script
1520 def Func()
1521 var x = 'hello'
1522 var Closure = {-> x}
1523 g:Myclosure = {-> Closure()}
1524 enddef
1525 Func()
1526 assert_equal('hello', g:Myclosure())
1527 END
1528 CheckScriptSuccess(lines)
1529enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001530
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001531def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001532 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001533 vim9script
1534 def FuncA()
1535 FuncB(0)
1536 enddef
1537 def FuncB(n: number): list<string>
1538 return map([0], {_, v -> n})
1539 enddef
1540 FuncA()
1541 END
1542 CheckScriptFailure(lines, 'E1012:')
1543enddef
1544
Bram Moolenaarf112f302020-12-20 17:47:52 +01001545def Test_global_closure()
1546 var lines =<< trim END
1547 vim9script
1548 def ReverseEveryNLines(n: number, line1: number, line2: number)
1549 var mods = 'sil keepj keepp lockm '
1550 var range = ':' .. line1 .. ',' .. line2
1551 def g:Offset(): number
1552 var offset = (line('.') - line1 + 1) % n
1553 return offset != 0 ? offset : n
1554 enddef
1555 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
1556 enddef
1557
1558 new
1559 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
1560 ReverseEveryNLines(3, 1, 9)
1561 END
1562 CheckScriptSuccess(lines)
1563 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
1564 assert_equal(expected, getline(1, 9))
1565 bwipe!
1566enddef
1567
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01001568def Test_failure_in_called_function()
1569 # this was using the frame index as the return value
1570 var lines =<< trim END
1571 vim9script
1572 au TerminalWinOpen * eval [][0]
1573 def PopupTerm(a: any)
1574 # make sure typvals on stack are string
1575 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1576 FireEvent()
1577 enddef
1578 def FireEvent()
1579 do TerminalWinOpen
1580 enddef
1581 # use try/catch to make eval fail
1582 try
1583 call PopupTerm(0)
1584 catch
1585 endtry
1586 au! TerminalWinOpen
1587 END
1588 CheckScriptSuccess(lines)
1589enddef
1590
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001591def Test_nested_lambda()
1592 var lines =<< trim END
1593 vim9script
1594 def Func()
1595 var x = 4
1596 var Lambda1 = {-> 7}
1597 var Lambda2 = {-> [Lambda1(), x]}
1598 var res = Lambda2()
1599 assert_equal([7, 4], res)
1600 enddef
1601 Func()
1602 END
1603 CheckScriptSuccess(lines)
1604enddef
1605
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001606def Shadowed(): list<number>
1607 var FuncList: list<func: number> = [{ -> 42}]
1608 return FuncList->map({_, Shadowed -> Shadowed()})
1609enddef
1610
1611def Test_lambda_arg_shadows_func()
1612 assert_equal([42], Shadowed())
1613enddef
1614
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001615def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001616 var path: string = empty(dir)
1617 \ ? 'empty'
1618 \ : 'full'
1619 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001620enddef
1621
1622def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001623 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001624enddef
1625
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001626def Test_script_var_in_lambda()
1627 var lines =<< trim END
1628 vim9script
1629 var script = 'test'
1630 assert_equal(['test'], map(['one'], {-> script}))
1631 END
1632 CheckScriptSuccess(lines)
1633enddef
1634
Bram Moolenaar5e654232020-09-16 15:22:00 +02001635def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001636 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001637 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001638 ->toupper()})
1639 ->reverse()
1640 return x
1641enddef
1642
1643def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001644 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001645enddef
1646
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001647func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001648 CheckScreendump
1649
1650 let lines =<< trim END
1651 vim9script
1652 def EchoNothing()
1653 silent echo ''
1654 enddef
1655 defcompile
1656 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001657 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001658
1659 " Check that the balloon shows up after a mouse move
1660 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001661 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001662 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1663
1664 " clean up
1665 call StopVimInTerminal(buf)
1666 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001667endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001668
Bram Moolenaar171fb922020-10-28 16:54:47 +01001669def SilentlyError()
1670 execute('silent! invalid')
1671 g:did_it = 'yes'
1672enddef
1673
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001674func UserError()
1675 silent! invalid
1676endfunc
1677
1678def SilentlyUserError()
1679 UserError()
1680 g:did_it = 'yes'
1681enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001682
1683" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001684func Test_ignore_silent_error()
1685 let g:did_it = 'no'
1686 call SilentlyError()
1687 call assert_equal('yes', g:did_it)
1688
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001689 let g:did_it = 'no'
1690 call SilentlyUserError()
1691 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001692
1693 unlet g:did_it
1694endfunc
1695
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001696def Test_ignore_silent_error_in_filter()
1697 var lines =<< trim END
1698 vim9script
1699 def Filter(winid: number, key: string): bool
1700 if key == 'o'
1701 silent! eval [][0]
1702 return true
1703 endif
1704 return popup_filter_menu(winid, key)
1705 enddef
1706
Bram Moolenaare0de1712020-12-02 17:36:54 +01001707 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001708 feedkeys("o\r", 'xnt')
1709 END
1710 CheckScriptSuccess(lines)
1711enddef
1712
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001713def Fibonacci(n: number): number
1714 if n < 2
1715 return n
1716 else
1717 return Fibonacci(n - 1) + Fibonacci(n - 2)
1718 endif
1719enddef
1720
Bram Moolenaar985116a2020-07-12 17:31:09 +02001721def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001722 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001723enddef
1724
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001725def TreeWalk(dir: string): list<any>
1726 return readdir(dir)->map({_, val ->
1727 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001728 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001729 : val
1730 })
1731enddef
1732
1733def Test_closure_in_map()
1734 mkdir('XclosureDir/tdir', 'p')
1735 writefile(['111'], 'XclosureDir/file1')
1736 writefile(['222'], 'XclosureDir/file2')
1737 writefile(['333'], 'XclosureDir/tdir/file3')
1738
Bram Moolenaare0de1712020-12-02 17:36:54 +01001739 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001740
1741 delete('XclosureDir', 'rf')
1742enddef
1743
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001744def Test_invalid_function_name()
1745 var lines =<< trim END
1746 vim9script
1747 def s: list<string>
1748 END
1749 CheckScriptFailure(lines, 'E129:')
1750
1751 lines =<< trim END
1752 vim9script
1753 def g: list<string>
1754 END
1755 CheckScriptFailure(lines, 'E129:')
1756
1757 lines =<< trim END
1758 vim9script
1759 def <SID>: list<string>
1760 END
1761 CheckScriptFailure(lines, 'E884:')
1762
1763 lines =<< trim END
1764 vim9script
1765 def F list<string>
1766 END
1767 CheckScriptFailure(lines, 'E488:')
1768enddef
1769
Bram Moolenaara90afb92020-07-15 22:38:56 +02001770def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001771 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001772 Xsetlist([], ' ', {title: 'test'})
1773 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001774
1775 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001776 Xsetlist({title: 'test'})
1777 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001778
1779 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001780 Xsetlist([], ' ', {title: 'test'})
1781 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001782
1783 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001784 Xsetlist({title: 'test'})
1785 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001786
1787 var Len: func: number = function('len', ['word'])
1788 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001789enddef
1790
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001791def Test_cmd_modifier()
1792 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001793 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001794enddef
1795
1796def Test_restore_modifiers()
1797 # check that when compiling a :def function command modifiers are not messed
1798 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001799 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001800 vim9script
1801 set eventignore=
1802 autocmd QuickFixCmdPost * copen
1803 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001804 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001805 enddef
1806 func Func()
1807 noautocmd call s:AutocmdsDisabled()
1808 let g:ei_after = &eventignore
1809 endfunc
1810 Func()
1811 END
1812 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001813 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001814enddef
1815
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001816def StackTop()
1817 eval 1
1818 eval 2
1819 # call not on fourth line
1820 StackBot()
1821enddef
1822
1823def StackBot()
1824 # throw an error
1825 eval [][0]
1826enddef
1827
1828def Test_callstack_def()
1829 try
1830 StackTop()
1831 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001832 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001833 endtry
1834enddef
1835
Bram Moolenaare8211a32020-10-09 22:04:29 +02001836" Re-using spot for variable used in block
1837def Test_block_scoped_var()
1838 var lines =<< trim END
1839 vim9script
1840 def Func()
1841 var x = ['a', 'b', 'c']
1842 if 1
1843 var y = 'x'
1844 map(x, {-> y})
1845 endif
1846 var z = x
1847 assert_equal(['x', 'x', 'x'], z)
1848 enddef
1849 Func()
1850 END
1851 CheckScriptSuccess(lines)
1852enddef
1853
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001854def Test_reset_did_emsg()
1855 var lines =<< trim END
1856 @s = 'blah'
1857 au BufWinLeave * #
1858 def Func()
1859 var winid = popup_create('popup', {})
1860 exe '*s'
1861 popup_close(winid)
1862 enddef
1863 Func()
1864 END
1865 CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001866 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001867enddef
1868
Bram Moolenaar57f799e2020-12-12 20:42:19 +01001869def Test_did_emsg_reset()
1870 # executing an autocommand resets did_emsg, this should not result in a
1871 # builtin function considered failing
1872 var lines =<< trim END
1873 vim9script
1874 au BufWinLeave * #
1875 def Func()
1876 popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
1877 eval [][0]
1878 enddef
1879 nno <F3> <cmd>call <sid>Func()<cr>
1880 feedkeys("\<F3>\e", 'xt')
1881 END
1882 writefile(lines, 'XemsgReset')
1883 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
1884 delete('XemsgReset')
1885 nunmap <F3>
1886 au! BufWinLeave
1887enddef
1888
Bram Moolenaar56602ba2020-12-05 21:22:08 +01001889def Test_abort_with_silent_call()
1890 var lines =<< trim END
1891 vim9script
1892 g:result = 'none'
1893 def Func()
1894 g:result += 3
1895 g:result = 'yes'
1896 enddef
1897 # error is silenced, but function aborts on error
1898 silent! Func()
1899 assert_equal('none', g:result)
1900 unlet g:result
1901 END
1902 CheckScriptSuccess(lines)
1903enddef
1904
Bram Moolenaarf665e972020-12-05 19:17:16 +01001905def Test_continues_with_silent_error()
1906 var lines =<< trim END
1907 vim9script
1908 g:result = 'none'
1909 def Func()
1910 silent! g:result += 3
1911 g:result = 'yes'
1912 enddef
1913 # error is silenced, function does not abort
1914 Func()
1915 assert_equal('yes', g:result)
1916 unlet g:result
1917 END
1918 CheckScriptSuccess(lines)
1919enddef
1920
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001921def Test_abort_even_with_silent()
1922 var lines =<< trim END
1923 vim9script
1924 g:result = 'none'
1925 def Func()
1926 eval {-> ''}() .. '' .. {}['X']
1927 g:result = 'yes'
1928 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01001929 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001930 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001931 unlet g:result
1932 END
1933 CheckScriptSuccess(lines)
1934enddef
1935
Bram Moolenaarf665e972020-12-05 19:17:16 +01001936def Test_cmdmod_silent_restored()
1937 var lines =<< trim END
1938 vim9script
1939 def Func()
1940 g:result = 'none'
1941 silent! g:result += 3
1942 g:result = 'none'
1943 g:result += 3
1944 enddef
1945 Func()
1946 END
1947 # can't use CheckScriptFailure, it ignores the :silent!
1948 var fname = 'Xdefsilent'
1949 writefile(lines, fname)
1950 var caught = 'no'
1951 try
1952 exe 'source ' .. fname
1953 catch /E1030:/
1954 caught = 'yes'
1955 assert_match('Func, line 4', v:throwpoint)
1956 endtry
1957 assert_equal('yes', caught)
1958 delete(fname)
1959enddef
1960
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001961def Test_dict_member_with_silent()
1962 var lines =<< trim END
1963 vim9script
1964 g:result = 'none'
1965 var d: dict<any>
1966 def Func()
1967 try
1968 g:result = map([], {_, v -> {}[v]})->join() .. d['']
1969 catch
1970 endtry
1971 enddef
1972 silent! Func()
1973 assert_equal('0', g:result)
1974 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001975 END
1976 CheckScriptSuccess(lines)
1977enddef
1978
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01001979def Test_opfunc()
1980 nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
1981 def g:Opfunc(_: any): string
1982 setline(1, 'ASDF')
1983 return ''
1984 enddef
1985 new
1986 setline(1, 'asdf')
1987 feedkeys("\<F3>$", 'x')
1988 assert_equal('ASDF', getline(1))
1989
1990 bwipe!
1991 nunmap <F3>
1992enddef
1993
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001994
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001995" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker