blob: fb37401a22de7697f5dc7ffbf554f1a8aea61579 [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
Bram Moolenaar2949cfd2020-12-31 21:28:47 +010057 return map(l, (_, v) => CallMapRecursive([v]))[0]
Bram Moolenaar0ba48e82020-11-17 18:23:19 +010058enddef
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 Moolenaar5178b1b2021-01-01 18:43:51 +010082def Test_endfunc_enddef()
83 var lines =<< trim END
84 def Test()
85 echo 'test'
86 endfunc
87 enddef
88 END
89 CheckScriptFailure(lines, 'E1151:', 3)
90
91 lines =<< trim END
92 def Test()
93 func Nested()
94 echo 'test'
95 enddef
96 enddef
97 END
98 CheckScriptFailure(lines, 'E1152:', 4)
99enddef
100
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100101def Test_missing_endfunc_enddef()
102 var lines =<< trim END
103 vim9script
104 def Test()
105 echo 'test'
106 endef
107 END
108 CheckScriptFailure(lines, 'E1057:', 2)
109
110 lines =<< trim END
111 vim9script
112 func Some()
113 echo 'test'
114 enfffunc
115 END
116 CheckScriptFailure(lines, 'E126:', 2)
117enddef
118
Bram Moolenaar832ea892021-01-08 21:55:26 +0100119def Test_enddef_dict_key()
120 var d = {
121 enddef: 'x',
122 endfunc: 'y',
123 }
124 assert_equal({enddef: 'x', endfunc: 'y'}, d)
125enddef
126
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200127def ReturnString(): string
128 return 'string'
129enddef
130
131def ReturnNumber(): number
132 return 123
133enddef
134
135let g:notNumber = 'string'
136
137def ReturnGlobal(): number
138 return g:notNumber
139enddef
140
141def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200142 ReturnString()->assert_equal('string')
143 ReturnNumber()->assert_equal(123)
Bram Moolenaar5e654232020-09-16 15:22:00 +0200144 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200145enddef
146
Bram Moolenaarefd88552020-06-18 20:50:10 +0200147def Test_missing_return()
148 CheckDefFailure(['def Missing(): number',
149 ' if g:cond',
150 ' echo "no return"',
151 ' else',
152 ' return 0',
153 ' endif'
154 'enddef'], 'E1027:')
155 CheckDefFailure(['def Missing(): number',
156 ' if g:cond',
157 ' return 1',
158 ' else',
159 ' echo "no return"',
160 ' endif'
161 'enddef'], 'E1027:')
162 CheckDefFailure(['def Missing(): number',
163 ' if g:cond',
164 ' return 1',
165 ' else',
166 ' return 2',
167 ' endif'
168 ' return 3'
169 'enddef'], 'E1095:')
170enddef
171
Bram Moolenaar403dc312020-10-17 19:29:51 +0200172def Test_return_bool()
173 var lines =<< trim END
174 vim9script
175 def MenuFilter(id: number, key: string): bool
176 return popup_filter_menu(id, key)
177 enddef
178 def YesnoFilter(id: number, key: string): bool
179 return popup_filter_yesno(id, key)
180 enddef
181 defcompile
182 END
183 CheckScriptSuccess(lines)
184enddef
185
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200186let s:nothing = 0
187def ReturnNothing()
188 s:nothing = 1
189 if true
190 return
191 endif
192 s:nothing = 2
193enddef
194
195def Test_return_nothing()
196 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200197 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200198enddef
199
200func Increment()
201 let g:counter += 1
202endfunc
203
204def Test_call_ufunc_count()
205 g:counter = 1
206 Increment()
207 Increment()
208 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200209 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200210 g:counter->assert_equal(4)
211 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200212 unlet g:counter
213enddef
214
215def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200216 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200217 for s in rest
218 res ..= ',' .. s
219 endfor
220 return res
221enddef
222
223def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200224 MyVarargs('one')->assert_equal('one')
225 MyVarargs('one', 'two')->assert_equal('one,two')
226 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200227enddef
228
229def MyDefaultArgs(name = 'string'): string
230 return name
231enddef
232
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200233def MyDefaultSecond(name: string, second: bool = true): string
234 return second ? name : 'none'
235enddef
236
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200237def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200238 MyDefaultArgs()->assert_equal('string')
239 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200240 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200241
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200242 MyDefaultSecond('test')->assert_equal('test')
243 MyDefaultSecond('test', true)->assert_equal('test')
244 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200245
Bram Moolenaar822ba242020-05-24 23:00:18 +0200246 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100247 delfunc g:Func
Bram Moolenaar77072282020-09-16 17:55:40 +0200248 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 +0100249 delfunc g:Func
Bram Moolenaar04b12692020-05-04 23:24:44 +0200250enddef
251
Bram Moolenaarcef12702021-01-04 14:09:43 +0100252def FuncWithComment( # comment
253 a: number, #comment
254 b: bool, # comment
255 c: string) #comment
256 assert_equal(4, a)
257 assert_equal(true, b)
258 assert_equal('yes', c)
259enddef
260
261def Test_func_with_comments()
262 FuncWithComment(4, true, 'yes')
263
264 var lines =<< trim END
265 def Func(# comment
266 arg: string)
267 enddef
268 END
269 CheckScriptFailure(lines, 'E125:', 1)
270
271 lines =<< trim END
272 def Func(
273 arg: string# comment
274 )
275 enddef
276 END
277 CheckScriptFailure(lines, 'E475:', 2)
278
279 lines =<< trim END
280 def Func(
281 arg: string
282 )# comment
283 enddef
284 END
285 CheckScriptFailure(lines, 'E488:', 3)
286enddef
287
Bram Moolenaar04b12692020-05-04 23:24:44 +0200288def Test_nested_function()
289 def Nested(arg: string): string
290 return 'nested ' .. arg
291 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200292 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200293
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200294 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
295 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
296
Bram Moolenaar04b12692020-05-04 23:24:44 +0200297 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200298 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
299 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200300
Bram Moolenaar54021752020-12-06 18:50:36 +0100301 var lines =<< trim END
302 def Outer()
303 def Inner()
304 # comment
305 enddef
306 def Inner()
307 enddef
308 enddef
309 END
310 CheckDefFailure(lines, 'E1073:')
311
312 lines =<< trim END
313 def Outer()
314 def Inner()
315 # comment
316 enddef
317 def! Inner()
318 enddef
319 enddef
320 END
321 CheckDefFailure(lines, 'E1117:')
322
323 # nested function inside conditional
324 # TODO: should it work when "thecount" is inside the "if"?
325 lines =<< trim END
326 vim9script
327 var thecount = 0
328 if true
329 def Test(): number
330 def TheFunc(): number
331 thecount += 1
332 return thecount
333 enddef
334 return TheFunc()
335 enddef
336 endif
337 defcompile
338 assert_equal(1, Test())
339 assert_equal(2, Test())
340 END
341 CheckScriptSuccess(lines)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200342enddef
343
Bram Moolenaaradc8e442020-12-31 18:28:18 +0100344def Test_not_nested_function()
345 echo printf('%d',
346 function('len')('xxx'))
347enddef
348
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200349func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200350 call MyDefaultArgs()->assert_equal('string')
351 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200352 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200353endfunc
354
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200355def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200356 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200357 vim9script
358 def Outer()
359 def g:Inner(): string
360 return 'inner'
361 enddef
362 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200363 defcompile
364 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200365 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200366 delfunc g:Inner
367 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200368 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200369 delfunc g:Inner
370 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200371 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200372 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200373 END
374 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200375
376 lines =<< trim END
377 vim9script
378 def Outer()
379 def g:Inner(): string
380 return 'inner'
381 enddef
382 enddef
383 defcompile
384 Outer()
385 Outer()
386 END
387 CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +0100388 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +0200389
390 lines =<< trim END
391 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +0100392 def Outer()
393 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100394 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +0100395 enddef
396 g:Inner()
397 enddef
398 Outer()
399 END
400 CheckScriptSuccess(lines)
401 delfunc g:Inner
402
403 lines =<< trim END
404 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +0200405 def Func()
406 echo 'script'
407 enddef
408 def Outer()
409 def Func()
410 echo 'inner'
411 enddef
412 enddef
413 defcompile
414 END
415 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200416enddef
417
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100418def DefListAll()
419 def
420enddef
421
422def DefListOne()
423 def DefListOne
424enddef
425
426def DefListMatches()
427 def /DefList
428enddef
429
430def Test_nested_def_list()
431 var funcs = split(execute('call DefListAll()'), "\n")
432 assert_true(len(funcs) > 10)
433 assert_true(funcs->index('def DefListAll()') >= 0)
434
435 funcs = split(execute('call DefListOne()'), "\n")
436 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
437
438 funcs = split(execute('call DefListMatches()'), "\n")
439 assert_true(len(funcs) >= 3)
440 assert_true(funcs->index('def DefListAll()') >= 0)
441 assert_true(funcs->index('def DefListOne()') >= 0)
442 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +0100443
444 var lines =<< trim END
445 vim9script
446 def Func()
447 def +Func+
448 enddef
449 defcompile
450 END
451 CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100452enddef
453
Bram Moolenaar333894b2020-08-01 18:53:07 +0200454def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200455 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200456 vim9script
457 def g:Func(): string
458 return 'global'
459 enddef
460 def Func(): string
461 return 'local'
462 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200463 g:Func()->assert_equal('global')
464 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100465 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +0200466 END
467 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200468
469 lines =<< trim END
470 vim9script
471 def g:Funcy()
472 echo 'funcy'
473 enddef
474 s:Funcy()
475 END
476 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200477enddef
478
Bram Moolenaar0f769812020-09-12 18:32:34 +0200479def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200480 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200481 vim9script
482 def g:Gfunc(): string
483 return 'global'
484 enddef
485 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200486 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200487 return Gfunc('testing')
488 enddef
489 g:Gfunc()->assert_equal('global')
490 AnotherFunc()->assert_equal(7)
491 delfunc g:Gfunc
492 END
493 CheckScriptSuccess(lines)
494
495 lines =<< trim END
496 vim9script
497 def g:Func(): string
498 return 'global'
499 enddef
500 def AnotherFunc()
501 g:Func = function('len')
502 enddef
503 AnotherFunc()
504 END
505 CheckScriptFailure(lines, 'E705:')
506 delfunc g:Func
507enddef
508
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200509func TakesOneArg(arg)
510 echo a:arg
511endfunc
512
513def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200514 CheckDefFailure(['TakesOneArg()'], 'E119:')
515 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
516 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
517 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200518
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200519 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200520 vim9script
521 def Func(s: string)
522 echo s
523 enddef
524 Func([])
525 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200526 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200527
528 lines =<< trim END
529 vim9script
530 def FuncOne(nr: number)
531 echo nr
532 enddef
533 def FuncTwo()
534 FuncOne()
535 enddef
536 defcompile
537 END
538 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200539 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200540 try
541 source Xscript
542 catch
543 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
544 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
545 didCatch = true
546 endtry
547 assert_true(didCatch)
548
549 lines =<< trim END
550 vim9script
551 def FuncOne(nr: number)
552 echo nr
553 enddef
554 def FuncTwo()
555 FuncOne(1, 2)
556 enddef
557 defcompile
558 END
559 writefile(lines, 'Xscript')
560 didCatch = false
561 try
562 source Xscript
563 catch
564 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
565 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
566 didCatch = true
567 endtry
568 assert_true(didCatch)
569
570 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200571enddef
572
Bram Moolenaar50824712020-12-20 21:10:17 +0100573def Test_call_funcref_wrong_args()
574 var head =<< trim END
575 vim9script
576 def Func3(a1: string, a2: number, a3: list<number>)
577 echo a1 .. a2 .. a3[0]
578 enddef
579 def Testme()
580 var funcMap: dict<func> = {func: Func3}
581 END
582 var tail =<< trim END
583 enddef
584 Testme()
585 END
586 CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
587
588 CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
589 CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +0100590
591 var lines =<< trim END
592 vim9script
593 var Ref: func(number): any
594 Ref = (j) => !j
595 echo Ref(false)
596 END
597 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
598
599 lines =<< trim END
600 vim9script
601 var Ref: func(number): any
602 Ref = (j) => !j
603 call Ref(false)
604 END
605 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +0100606enddef
607
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100608def Test_call_lambda_args()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100609 CheckDefFailure(['echo ((i) => 0)()'],
610 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100611
612 var lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100613 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100614 echo Ref(1, 'x')
615 END
616 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +0100617
618 lines =<< trim END
619 var Ref: func(job, string, number)
620 Ref = (x, y) => 0
621 END
622 CheckDefAndScriptFailure(lines, 'E1012:')
623
624 lines =<< trim END
625 var Ref: func(job, string)
626 Ref = (x, y, z) => 0
627 END
628 CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100629enddef
630
Bram Moolenaar709664c2020-12-12 14:33:41 +0100631def Test_lambda_uses_assigned_var()
632 CheckDefSuccess([
633 'var x: any = "aaa"'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100634 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +0100635enddef
636
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200637" Default arg and varargs
638def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200639 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200640 for s in rest
641 res ..= ',' .. s
642 endfor
643 return res
644enddef
645
646def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200647 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200648 MyDefVarargs('one')->assert_equal('one,foo')
649 MyDefVarargs('one', 'two')->assert_equal('one,two')
650 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200651 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200652 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200653 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200654 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200655
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200656 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200657 vim9script
658 def Func(...l: list<string>)
659 echo l
660 enddef
661 Func('a', 'b', 'c')
662 END
663 CheckScriptSuccess(lines)
664
665 lines =<< trim END
666 vim9script
667 def Func(...l: list<string>)
668 echo l
669 enddef
670 Func()
671 END
672 CheckScriptSuccess(lines)
673
674 lines =<< trim END
675 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200676 def Func(...l: any)
677 echo l
678 enddef
679 Func(0)
680 END
681 CheckScriptSuccess(lines)
682
683 lines =<< trim END
684 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200685 def Func(..._l: list<string>)
686 echo _l
687 enddef
688 Func('a', 'b', 'c')
689 END
690 CheckScriptSuccess(lines)
691
692 lines =<< trim END
693 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200694 def Func(...l: list<string>)
695 echo l
696 enddef
697 Func(1, 2, 3)
698 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200699 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200700
701 lines =<< trim END
702 vim9script
703 def Func(...l: list<string>)
704 echo l
705 enddef
706 Func('a', 9)
707 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200708 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200709
710 lines =<< trim END
711 vim9script
712 def Func(...l: list<string>)
713 echo l
714 enddef
715 Func(1, 'a')
716 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200717 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200718enddef
719
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200720let s:value = ''
721
722def FuncOneDefArg(opt = 'text')
723 s:value = opt
724enddef
725
726def FuncTwoDefArg(nr = 123, opt = 'text'): string
727 return nr .. opt
728enddef
729
730def FuncVarargs(...arg: list<string>): string
731 return join(arg, ',')
732enddef
733
734def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200735 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200736 RefDefArg = FuncOneDefArg
737 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200738 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200739 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200740 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200741
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200742 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200743 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200744 RefDef2Arg()->assert_equal('123text')
745 RefDef2Arg(99)->assert_equal('99text')
746 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200747
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200748 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
749 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200750
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200751 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200752 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200753 RefVarargs()->assert_equal('')
754 RefVarargs('one')->assert_equal('one')
755 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200756
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200757 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
758 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200759enddef
760
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200761" Only varargs
762def MyVarargsOnly(...args: list<string>): string
763 return join(args, ',')
764enddef
765
766def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200767 MyVarargsOnly()->assert_equal('')
768 MyVarargsOnly('one')->assert_equal('one')
769 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200770 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
771 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200772enddef
773
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200774def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200775 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200776 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200777 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200778enddef
779
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200780def DictArg(arg: dict<string>)
781 arg['key'] = 'value'
782enddef
783
784def ListArg(arg: list<string>)
785 arg[0] = 'value'
786enddef
787
788def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200789 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200790 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200791 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200792 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200793 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200794 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200795 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200796
Bram Moolenaard2c61702020-09-06 15:58:36 +0200797 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100798 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200799enddef
800
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200801" These argument names are reserved in legacy functions.
802def WithReservedNames(firstline: string, lastline: string): string
803 return firstline .. lastline
804enddef
805
806def Test_argument_names()
807 assert_equal('OK', WithReservedNames('O', 'K'))
808enddef
809
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200810def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200811 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200812 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200813enddef
814
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200815func DefinedLater(arg)
816 return a:arg
817endfunc
818
819def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200820 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200821 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
822 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200823
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200824 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200825 vim9script
826 def RetNumber(): number
827 return 123
828 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200829 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200830 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200831 END
832 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200833
834 lines =<< trim END
835 vim9script
836 def RetNumber(): number
837 return 123
838 enddef
839 def Bar(F: func: number): number
840 return F()
841 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200842 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200843 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200844 END
845 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200846
847 lines =<< trim END
848 vim9script
849 def UseNumber(nr: number)
850 echo nr
851 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200852 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200853 Funcref(123)
854 END
855 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200856
857 lines =<< trim END
858 vim9script
859 def UseNumber(nr: number)
860 echo nr
861 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200862 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200863 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200864 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200865
866 lines =<< trim END
867 vim9script
868 def EchoNr(nr = 34)
869 g:echo = nr
870 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200871 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200872 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200873 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200874 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200875 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200876 END
877 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200878
879 lines =<< trim END
880 vim9script
881 def EchoList(...l: list<number>)
882 g:echo = l
883 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200884 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200885 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200886 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200887 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200888 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200889 END
890 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200891
892 lines =<< trim END
893 vim9script
894 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
895 g:optarg = opt
896 g:listarg = l
897 return nr
898 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200899 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200900 Funcref(10)->assert_equal(10)
901 g:optarg->assert_equal(12)
902 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200903
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200904 Funcref(11, 22)->assert_equal(11)
905 g:optarg->assert_equal(22)
906 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200907
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200908 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
909 g:optarg->assert_equal(18)
910 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200911 END
912 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200913enddef
914
915let SomeFunc = function('len')
916let NotAFunc = 'text'
917
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200918def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200919 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200920 var Ref1: func(bool): string
921 var Ref2: func(bool): number
922 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200923 Ref3 = g:cond ? Ref1 : Ref2
924
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200925 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200926 var Refa1: func(bool): number
927 var Refa2: func(bool, number): number
928 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200929 Refa3 = g:cond ? Refa1 : Refa2
930
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200931 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200932 var Refb1: func(bool, string): number
933 var Refb2: func(string, number): number
934 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200935 Refb3 = g:cond ? Refb1 : Refb2
936enddef
937
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200938def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200939 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200940enddef
941
942def DefinedEvenLater(arg: string): string
943 return arg
944enddef
945
946def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200947 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200948 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200949enddef
950
951def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200952 CheckScriptFailure([
953 'def Func(): number',
954 'return "a"',
955 'enddef',
956 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100957 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200958 CheckScriptFailure([
959 'def Func(): string',
960 'return 1',
961 'enddef',
962 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100963 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200964 CheckScriptFailure([
965 'def Func(): void',
966 'return "a"',
967 'enddef',
968 'defcompile'],
969 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100970 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200971 CheckScriptFailure([
972 'def Func()',
973 'return "a"',
974 'enddef',
975 'defcompile'],
976 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100977 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200978
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200979 CheckScriptFailure([
980 'def Func(): number',
981 'return',
982 'enddef',
983 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100984 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200985
986 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100987 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200988 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100989 delfunc! g:Func
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200990 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100991 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200992
993 CheckScriptFailure([
994 'vim9script',
995 'def FuncB()',
996 ' return 123',
997 'enddef',
998 'def FuncA()',
999 ' FuncB()',
1000 'enddef',
1001 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001002enddef
1003
1004def Test_arg_type_wrong()
1005 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001006 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001007 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +02001008 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001009enddef
1010
1011def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001012 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001013 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001014 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001015 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001016 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001017 enddef
1018 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001019 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001020
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001021 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001022 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001023 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001024
Bram Moolenaar67979662020-06-20 22:50:47 +02001025 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001026 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001027 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001028
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001029 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001030 def ListFunc(arg: list<number>)
1031 listvar = arg
1032 enddef
1033 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001034 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001035
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001036 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001037 def DictFunc(arg: dict<number>)
1038 dictvar = arg
1039 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01001040 {a: 1, b: 2}->DictFunc()
1041 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001042 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001043 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001044 enddef
1045 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001046 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001047
Bram Moolenaare0de1712020-12-02 17:36:54 +01001048 {a: 3, b: 4}->DictFunc()
1049 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001050
1051 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001052 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001053 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001054 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02001055
Bram Moolenaar13e12b82020-07-24 18:47:22 +02001056 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02001057 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02001058 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001059 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02001060 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001061 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02001062
1063 def UseString()
1064 'xyork'->MyFunc()
1065 enddef
1066 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001067 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02001068
Bram Moolenaar10409562020-07-29 20:00:38 +02001069 def UseString2()
1070 "knife"->MyFunc()
1071 enddef
1072 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001073 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02001074
Bram Moolenaar13e12b82020-07-24 18:47:22 +02001075 # prepending a colon makes it a mark
1076 new
1077 setline(1, ['aaa', 'bbb', 'ccc'])
1078 normal! 3Gmt1G
1079 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001080 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02001081 bwipe!
1082
Bram Moolenaare6b53242020-07-01 17:28:33 +02001083 MyFunc(
1084 'continued'
1085 )
1086 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001087 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02001088 )
1089
1090 call MyFunc(
1091 'more'
1092 ..
1093 'lines'
1094 )
1095 assert_equal(
1096 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001097 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001098 END
1099 writefile(lines, 'Xcall.vim')
1100 source Xcall.vim
1101 delete('Xcall.vim')
1102enddef
1103
1104def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001105 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001106 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001107 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001108 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001109 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001110 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001111 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001112 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +02001113 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001114enddef
1115
Bram Moolenaar65b95452020-07-19 14:03:09 +02001116def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001117 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02001118 vim9script
1119 def MyFunc(arg: string)
1120 echo arg
1121 enddef
1122 MyFunc(1234)
1123 END
Bram Moolenaar77072282020-09-16 17:55:40 +02001124 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02001125enddef
1126
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001127def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001128 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001129 vim9script
1130 const var = ''
1131 def MyFunc(arg: string)
1132 var = 'asdf'
1133 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001134 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001135 END
1136 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001137 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001138 delete('Xcall_const.vim')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01001139
1140 lines =<< trim END
1141 const g:Aconst = 77
1142 def Change()
1143 # comment
1144 g:Aconst = 99
1145 enddef
1146 call Change()
1147 unlet g:Aconst
1148 END
Bram Moolenaar1dcf55d2020-12-22 22:07:30 +01001149 CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001150enddef
1151
1152" Test that inside :function a Python function can be defined, :def is not
1153" recognized.
1154func Test_function_python()
1155 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02001156 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001157 execute py "<< EOF"
1158def do_something():
1159 return 1
1160EOF
1161endfunc
1162
1163def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001164 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001165 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001166 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001167 echo 'hello'
1168 enddef
1169
1170 def CallGoneSoon()
1171 GoneSoon()
1172 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001173 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001174
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001175 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001176 CallGoneSoon()
1177 END
1178 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001179 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
1180 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001181
1182 delete('XToDelFunc')
1183enddef
1184
1185def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02001186 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001187 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001188 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001189 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001190 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001191 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02001192 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001193 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001194 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001195
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001196 g:Func0()->assert_equal(0)
1197 g:Func1()->assert_equal('Func1')
1198 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001199
1200 delfunc! Func0
1201 delfunc! Func1
1202 delfunc! Func2
1203enddef
1204
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001205def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001206 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001207 vim9script
1208 func Func(arg)
1209 echo a:arg
1210 endfunc
1211 Func('text')
1212 END
1213 writefile(lines, 'XVim9Func')
1214 so XVim9Func
1215
1216 delete('XVim9Func')
1217enddef
1218
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001219let s:funcResult = 0
1220
1221def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001222 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001223enddef
1224
1225def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001226 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001227 return 1234
1228enddef
1229
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001230def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001231 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001232 return 'text'
1233enddef
1234
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001235def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001236 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001237enddef
1238
1239def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001240 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001241 return arg
1242enddef
1243
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001244def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001245 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001246enddef
1247
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001248def FuncOneArgRetString(arg: string): string
1249 return arg
1250enddef
1251
Bram Moolenaar89228602020-04-05 22:14:54 +02001252def FuncOneArgRetAny(arg: any): any
1253 return arg
1254enddef
1255
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001256def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001257 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001258 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001259 Ref1 = FuncNoArgNoRet
1260 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001261 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001262
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001263 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001264 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001265 Ref2 = FuncNoArgNoRet
1266 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001267 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001268
Bram Moolenaar53900992020-08-22 19:02:02 +02001269 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001270 Ref2 = FuncOneArgNoRet
1271 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001272 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001273
Bram Moolenaar53900992020-08-22 19:02:02 +02001274 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001275 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001276 Ref2()->assert_equal(1234)
1277 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001278
Bram Moolenaar53900992020-08-22 19:02:02 +02001279 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001280 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001281 Ref2(13)->assert_equal(13)
1282 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001283enddef
1284
Bram Moolenaar9978d472020-07-05 16:01:56 +02001285def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001286 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001287 for n in repeat([1], 3)
1288 res += n
1289 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001290 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001291
1292 res = 0
1293 for n in add([1, 2], 3)
1294 res += n
1295 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001296 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001297enddef
1298
Bram Moolenaar846178a2020-07-05 17:04:13 +02001299def Test_argv_return_type()
1300 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001301 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001302 for name in argv()
1303 res ..= name
1304 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001305 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001306enddef
1307
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001308def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001309 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001310 RefVoid = FuncNoArgNoRet
1311 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001312 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1313 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001314
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001315 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001316 RefAny = FuncNoArgRetNumber
1317 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001318 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1319 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001320
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001321 var RefAnyNoArgs: func: any = RefAny
1322
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001323 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001324 RefNr = FuncNoArgRetNumber
1325 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001326 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1327 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001328
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001329 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001330 RefStr = FuncNoArgRetString
1331 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001332 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1333 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001334enddef
1335
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001336def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001337 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001338
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001339 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1340 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1341 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1342 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1343 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1344 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 +02001345
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001346 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1347 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1348 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:')
1349 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001350enddef
1351
Bram Moolenaar89228602020-04-05 22:14:54 +02001352def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001353 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001354 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001355 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001356
1357 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001358 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001359
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001360 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001361 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001362 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001363
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001364 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001365enddef
1366
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001367def Test_func_common_type()
1368 def FuncOne(n: number): number
1369 return n
1370 enddef
1371 def FuncTwo(s: string): number
1372 return len(s)
1373 enddef
1374 def FuncThree(n: number, s: string): number
1375 return n + len(s)
1376 enddef
1377 var list = [FuncOne, FuncTwo, FuncThree]
1378 assert_equal(8, list[0](8))
1379 assert_equal(4, list[1]('word'))
1380 assert_equal(7, list[2](3, 'word'))
1381enddef
1382
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001383def MultiLine(
1384 arg1: string,
1385 arg2 = 1234,
1386 ...rest: list<string>
1387 ): string
1388 return arg1 .. arg2 .. join(rest, '-')
1389enddef
1390
Bram Moolenaar2c330432020-04-13 14:41:35 +02001391def MultiLineComment(
1392 arg1: string, # comment
1393 arg2 = 1234, # comment
1394 ...rest: list<string> # comment
1395 ): string # comment
1396 return arg1 .. arg2 .. join(rest, '-')
1397enddef
1398
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001399def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001400 MultiLine('text')->assert_equal('text1234')
1401 MultiLine('text', 777)->assert_equal('text777')
1402 MultiLine('text', 777, 'one')->assert_equal('text777one')
1403 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001404enddef
1405
Bram Moolenaar23e03252020-04-12 22:22:31 +02001406func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001407 call MultiLine('text')->assert_equal('text1234')
1408 call MultiLine('text', 777)->assert_equal('text777')
1409 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1410 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001411endfunc
1412
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001413
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001414" When using CheckScriptFailure() for the below test, E1010 is generated instead
1415" of E1056.
1416func Test_E1056_1059()
1417 let caught_1056 = 0
1418 try
1419 def F():
1420 return 1
1421 enddef
1422 catch /E1056:/
1423 let caught_1056 = 1
1424 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001425 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001426
1427 let caught_1059 = 0
1428 try
1429 def F5(items : list)
1430 echo 'a'
1431 enddef
1432 catch /E1059:/
1433 let caught_1059 = 1
1434 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001435 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001436endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001437
Bram Moolenaar015f4262020-05-05 21:25:22 +02001438func DelMe()
1439 echo 'DelMe'
1440endfunc
1441
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001442def Test_error_reporting()
1443 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001444 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001445 " comment
1446 def Func()
1447 # comment
1448 # comment
1449 invalid
1450 enddef
1451 defcompile
1452 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001453 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001454 try
1455 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001456 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001457 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001458 v:exception->assert_match('Invalid command: invalid')
1459 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001460 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001461 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001462
1463 # comment lines after the start of the function
1464 lines =<< trim END
1465 " comment
1466 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001467 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001468 # comment
1469 # comment
1470 invalid
1471 enddef
1472 defcompile
1473 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001474 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001475 try
1476 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001477 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001478 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001479 v:exception->assert_match('Invalid command: invalid')
1480 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001481 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001482 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001483
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001484 lines =<< trim END
1485 vim9script
1486 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001487 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001488 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001489 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001490 enddef
1491 defcompile
1492 Func()
1493 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001494 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001495 try
1496 source Xdef
1497 assert_report('should have failed')
1498 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001499 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001500 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001501 delfunc! g:Func
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001502
Bram Moolenaar08052222020-09-14 17:04:31 +02001503 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001504enddef
1505
Bram Moolenaar015f4262020-05-05 21:25:22 +02001506def Test_deleted_function()
1507 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001508 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001509 'delfunc g:DelMe',
1510 'echo RefMe()'], 'E117:')
1511enddef
1512
1513def Test_unknown_function()
1514 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001515 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001516 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001517enddef
1518
Bram Moolenaar328eac22021-01-07 19:23:08 +01001519def RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001520 return Ref('more')
1521enddef
1522
1523def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001524 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001525 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001526enddef
1527
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001528def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001529 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001530 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001531enddef
1532
1533def Test_closure_ref_after_return()
1534 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001535 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001536 unlet g:Ref
1537enddef
1538
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001539def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001540 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001541 g:Extend = (s) => local->add(s)
1542 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001543enddef
1544
1545def Test_closure_two_refs()
1546 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001547 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001548 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001549 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001550 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001551 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001552
1553 unlet g:Extend
1554 unlet g:Read
1555enddef
1556
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001557def ReadRef(Ref: func(): list<string>): string
1558 return join(Ref(), ' ')
1559enddef
1560
Bram Moolenaar5e654232020-09-16 15:22:00 +02001561def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001562 Ref(add)
1563enddef
1564
1565def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001566 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001567 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001568 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001569 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001570 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001571 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001572
1573 unlet g:Extend
1574 unlet g:Read
1575enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001576
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001577def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001578 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001579 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001580enddef
1581
1582def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001583 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001584 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001585enddef
1586
1587def Test_closure_using_argument()
1588 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001589 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001590
1591 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001592 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001593
1594 unlet g:UseArg
1595 unlet g:UseVararg
1596enddef
1597
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001598def MakeGetAndAppendRefs()
1599 var local = 'a'
1600
1601 def Append(arg: string)
1602 local ..= arg
1603 enddef
1604 g:Append = Append
1605
1606 def Get(): string
1607 return local
1608 enddef
1609 g:Get = Get
1610enddef
1611
1612def Test_closure_append_get()
1613 MakeGetAndAppendRefs()
1614 g:Get()->assert_equal('a')
1615 g:Append('-b')
1616 g:Get()->assert_equal('a-b')
1617 g:Append('-c')
1618 g:Get()->assert_equal('a-b-c')
1619
1620 unlet g:Append
1621 unlet g:Get
1622enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001623
Bram Moolenaar04b12692020-05-04 23:24:44 +02001624def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001625 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001626 def Closure(arg: string): string
1627 return local .. arg
1628 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001629 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001630enddef
1631
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001632func GetResult(Ref)
1633 return a:Ref('some')
1634endfunc
1635
1636def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001637 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001638 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001639 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001640enddef
1641
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001642def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001643 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001644 vim9script
1645 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001646 var name = 0
1647 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001648 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001649 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001650 enddef
1651 Func()
1652 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001653 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001654enddef
1655
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001656def Test_nested_closure_used()
1657 var lines =<< trim END
1658 vim9script
1659 def Func()
1660 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001661 var Closure = () => x
1662 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001663 enddef
1664 Func()
1665 assert_equal('hello', g:Myclosure())
1666 END
1667 CheckScriptSuccess(lines)
1668enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001669
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001670def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001671 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001672 vim9script
1673 def FuncA()
1674 FuncB(0)
1675 enddef
1676 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001677 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001678 enddef
1679 FuncA()
1680 END
1681 CheckScriptFailure(lines, 'E1012:')
1682enddef
1683
Bram Moolenaarf112f302020-12-20 17:47:52 +01001684def Test_global_closure()
1685 var lines =<< trim END
1686 vim9script
1687 def ReverseEveryNLines(n: number, line1: number, line2: number)
1688 var mods = 'sil keepj keepp lockm '
1689 var range = ':' .. line1 .. ',' .. line2
1690 def g:Offset(): number
1691 var offset = (line('.') - line1 + 1) % n
1692 return offset != 0 ? offset : n
1693 enddef
1694 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
1695 enddef
1696
1697 new
1698 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
1699 ReverseEveryNLines(3, 1, 9)
1700 END
1701 CheckScriptSuccess(lines)
1702 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
1703 assert_equal(expected, getline(1, 9))
1704 bwipe!
1705enddef
1706
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001707def Test_global_closure_called_directly()
1708 var lines =<< trim END
1709 vim9script
1710 def Outer()
1711 var x = 1
1712 def g:Inner()
1713 var y = x
1714 x += 1
1715 assert_equal(1, y)
1716 enddef
1717 g:Inner()
1718 assert_equal(2, x)
1719 enddef
1720 Outer()
1721 END
1722 CheckScriptSuccess(lines)
1723 delfunc g:Inner
1724enddef
1725
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01001726def Test_failure_in_called_function()
1727 # this was using the frame index as the return value
1728 var lines =<< trim END
1729 vim9script
1730 au TerminalWinOpen * eval [][0]
1731 def PopupTerm(a: any)
1732 # make sure typvals on stack are string
1733 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1734 FireEvent()
1735 enddef
1736 def FireEvent()
1737 do TerminalWinOpen
1738 enddef
1739 # use try/catch to make eval fail
1740 try
1741 call PopupTerm(0)
1742 catch
1743 endtry
1744 au! TerminalWinOpen
1745 END
1746 CheckScriptSuccess(lines)
1747enddef
1748
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001749def Test_nested_lambda()
1750 var lines =<< trim END
1751 vim9script
1752 def Func()
1753 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001754 var Lambda1 = () => 7
1755 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001756 var res = Lambda2()
1757 assert_equal([7, 4], res)
1758 enddef
1759 Func()
1760 END
1761 CheckScriptSuccess(lines)
1762enddef
1763
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001764def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001765 var FuncList: list<func: number> = [() => 42]
1766 return FuncList->map((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001767enddef
1768
1769def Test_lambda_arg_shadows_func()
1770 assert_equal([42], Shadowed())
1771enddef
1772
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001773def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001774 var path: string = empty(dir)
1775 \ ? 'empty'
1776 \ : 'full'
1777 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001778enddef
1779
1780def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001781 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001782enddef
1783
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001784def Test_script_var_in_lambda()
1785 var lines =<< trim END
1786 vim9script
1787 var script = 'test'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001788 assert_equal(['test'], map(['one'], () => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001789 END
1790 CheckScriptSuccess(lines)
1791enddef
1792
Bram Moolenaar5e654232020-09-16 15:22:00 +02001793def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001794 var x = range(97, 100)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001795 ->map((_, v) => nr2char(v)
1796 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001797 ->reverse()
1798 return x
1799enddef
1800
1801def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001802 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001803enddef
1804
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001805func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001806 CheckScreendump
1807
1808 let lines =<< trim END
1809 vim9script
1810 def EchoNothing()
1811 silent echo ''
1812 enddef
1813 defcompile
1814 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001815 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001816
1817 " Check that the balloon shows up after a mouse move
1818 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001819 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001820 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1821
1822 " clean up
1823 call StopVimInTerminal(buf)
1824 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001825endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001826
Bram Moolenaar171fb922020-10-28 16:54:47 +01001827def SilentlyError()
1828 execute('silent! invalid')
1829 g:did_it = 'yes'
1830enddef
1831
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001832func UserError()
1833 silent! invalid
1834endfunc
1835
1836def SilentlyUserError()
1837 UserError()
1838 g:did_it = 'yes'
1839enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001840
1841" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001842func Test_ignore_silent_error()
1843 let g:did_it = 'no'
1844 call SilentlyError()
1845 call assert_equal('yes', g:did_it)
1846
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001847 let g:did_it = 'no'
1848 call SilentlyUserError()
1849 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001850
1851 unlet g:did_it
1852endfunc
1853
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001854def Test_ignore_silent_error_in_filter()
1855 var lines =<< trim END
1856 vim9script
1857 def Filter(winid: number, key: string): bool
1858 if key == 'o'
1859 silent! eval [][0]
1860 return true
1861 endif
1862 return popup_filter_menu(winid, key)
1863 enddef
1864
Bram Moolenaare0de1712020-12-02 17:36:54 +01001865 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001866 feedkeys("o\r", 'xnt')
1867 END
1868 CheckScriptSuccess(lines)
1869enddef
1870
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001871def Fibonacci(n: number): number
1872 if n < 2
1873 return n
1874 else
1875 return Fibonacci(n - 1) + Fibonacci(n - 2)
1876 endif
1877enddef
1878
Bram Moolenaar985116a2020-07-12 17:31:09 +02001879def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001880 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001881enddef
1882
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001883def TreeWalk(dir: string): list<any>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001884 return readdir(dir)->map((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001885 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001886 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001887 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001888 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001889enddef
1890
1891def Test_closure_in_map()
1892 mkdir('XclosureDir/tdir', 'p')
1893 writefile(['111'], 'XclosureDir/file1')
1894 writefile(['222'], 'XclosureDir/file2')
1895 writefile(['333'], 'XclosureDir/tdir/file3')
1896
Bram Moolenaare0de1712020-12-02 17:36:54 +01001897 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001898
1899 delete('XclosureDir', 'rf')
1900enddef
1901
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001902def Test_invalid_function_name()
1903 var lines =<< trim END
1904 vim9script
1905 def s: list<string>
1906 END
1907 CheckScriptFailure(lines, 'E129:')
1908
1909 lines =<< trim END
1910 vim9script
1911 def g: list<string>
1912 END
1913 CheckScriptFailure(lines, 'E129:')
1914
1915 lines =<< trim END
1916 vim9script
1917 def <SID>: list<string>
1918 END
1919 CheckScriptFailure(lines, 'E884:')
1920
1921 lines =<< trim END
1922 vim9script
1923 def F list<string>
1924 END
1925 CheckScriptFailure(lines, 'E488:')
1926enddef
1927
Bram Moolenaara90afb92020-07-15 22:38:56 +02001928def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001929 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001930 Xsetlist([], ' ', {title: 'test'})
1931 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001932
1933 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001934 Xsetlist({title: 'test'})
1935 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001936
1937 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001938 Xsetlist([], ' ', {title: 'test'})
1939 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001940
1941 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001942 Xsetlist({title: 'test'})
1943 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001944
1945 var Len: func: number = function('len', ['word'])
1946 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001947enddef
1948
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001949def Test_cmd_modifier()
1950 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001951 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001952enddef
1953
1954def Test_restore_modifiers()
1955 # check that when compiling a :def function command modifiers are not messed
1956 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001957 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001958 vim9script
1959 set eventignore=
1960 autocmd QuickFixCmdPost * copen
1961 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001962 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001963 enddef
1964 func Func()
1965 noautocmd call s:AutocmdsDisabled()
1966 let g:ei_after = &eventignore
1967 endfunc
1968 Func()
1969 END
1970 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001971 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001972enddef
1973
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001974def StackTop()
1975 eval 1
1976 eval 2
1977 # call not on fourth line
1978 StackBot()
1979enddef
1980
1981def StackBot()
1982 # throw an error
1983 eval [][0]
1984enddef
1985
1986def Test_callstack_def()
1987 try
1988 StackTop()
1989 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001990 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001991 endtry
1992enddef
1993
Bram Moolenaare8211a32020-10-09 22:04:29 +02001994" Re-using spot for variable used in block
1995def Test_block_scoped_var()
1996 var lines =<< trim END
1997 vim9script
1998 def Func()
1999 var x = ['a', 'b', 'c']
2000 if 1
2001 var y = 'x'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002002 map(x, () => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02002003 endif
2004 var z = x
2005 assert_equal(['x', 'x', 'x'], z)
2006 enddef
2007 Func()
2008 END
2009 CheckScriptSuccess(lines)
2010enddef
2011
Bram Moolenaareeece9e2020-11-20 19:26:48 +01002012def Test_reset_did_emsg()
2013 var lines =<< trim END
2014 @s = 'blah'
2015 au BufWinLeave * #
2016 def Func()
2017 var winid = popup_create('popup', {})
2018 exe '*s'
2019 popup_close(winid)
2020 enddef
2021 Func()
2022 END
2023 CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002024 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01002025enddef
2026
Bram Moolenaar57f799e2020-12-12 20:42:19 +01002027def Test_did_emsg_reset()
2028 # executing an autocommand resets did_emsg, this should not result in a
2029 # builtin function considered failing
2030 var lines =<< trim END
2031 vim9script
2032 au BufWinLeave * #
2033 def Func()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002034 popup_menu('', {callback: () => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01002035 eval [][0]
2036 enddef
2037 nno <F3> <cmd>call <sid>Func()<cr>
2038 feedkeys("\<F3>\e", 'xt')
2039 END
2040 writefile(lines, 'XemsgReset')
2041 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
2042 delete('XemsgReset')
2043 nunmap <F3>
2044 au! BufWinLeave
2045enddef
2046
Bram Moolenaar56602ba2020-12-05 21:22:08 +01002047def Test_abort_with_silent_call()
2048 var lines =<< trim END
2049 vim9script
2050 g:result = 'none'
2051 def Func()
2052 g:result += 3
2053 g:result = 'yes'
2054 enddef
2055 # error is silenced, but function aborts on error
2056 silent! Func()
2057 assert_equal('none', g:result)
2058 unlet g:result
2059 END
2060 CheckScriptSuccess(lines)
2061enddef
2062
Bram Moolenaarf665e972020-12-05 19:17:16 +01002063def Test_continues_with_silent_error()
2064 var lines =<< trim END
2065 vim9script
2066 g:result = 'none'
2067 def Func()
2068 silent! g:result += 3
2069 g:result = 'yes'
2070 enddef
2071 # error is silenced, function does not abort
2072 Func()
2073 assert_equal('yes', g:result)
2074 unlet g:result
2075 END
2076 CheckScriptSuccess(lines)
2077enddef
2078
Bram Moolenaaraf0df472020-12-02 20:51:22 +01002079def Test_abort_even_with_silent()
2080 var lines =<< trim END
2081 vim9script
2082 g:result = 'none'
2083 def Func()
2084 eval {-> ''}() .. '' .. {}['X']
2085 g:result = 'yes'
2086 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01002087 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01002088 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01002089 unlet g:result
2090 END
2091 CheckScriptSuccess(lines)
2092enddef
2093
Bram Moolenaarf665e972020-12-05 19:17:16 +01002094def Test_cmdmod_silent_restored()
2095 var lines =<< trim END
2096 vim9script
2097 def Func()
2098 g:result = 'none'
2099 silent! g:result += 3
2100 g:result = 'none'
2101 g:result += 3
2102 enddef
2103 Func()
2104 END
2105 # can't use CheckScriptFailure, it ignores the :silent!
2106 var fname = 'Xdefsilent'
2107 writefile(lines, fname)
2108 var caught = 'no'
2109 try
2110 exe 'source ' .. fname
2111 catch /E1030:/
2112 caught = 'yes'
2113 assert_match('Func, line 4', v:throwpoint)
2114 endtry
2115 assert_equal('yes', caught)
2116 delete(fname)
2117enddef
2118
Bram Moolenaar4029cab2020-12-05 18:13:27 +01002119def Test_dict_member_with_silent()
2120 var lines =<< trim END
2121 vim9script
2122 g:result = 'none'
2123 var d: dict<any>
2124 def Func()
2125 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002126 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01002127 catch
2128 endtry
2129 enddef
2130 silent! Func()
2131 assert_equal('0', g:result)
2132 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01002133 END
2134 CheckScriptSuccess(lines)
2135enddef
2136
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01002137def Test_opfunc()
2138 nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
2139 def g:Opfunc(_: any): string
2140 setline(1, 'ASDF')
2141 return ''
2142 enddef
2143 new
2144 setline(1, 'asdf')
2145 feedkeys("\<F3>$", 'x')
2146 assert_equal('ASDF', getline(1))
2147
2148 bwipe!
2149 nunmap <F3>
2150enddef
2151
Bram Moolenaar077a4232020-12-22 18:33:27 +01002152" this was crashing on exit
2153def Test_nested_lambda_in_closure()
2154 var lines =<< trim END
2155 vim9script
2156 def Outer()
2157 def g:Inner()
2158 echo map([1, 2, 3], {_, v -> v + 1})
2159 enddef
2160 g:Inner()
2161 enddef
2162 defcompile
2163 writefile(['Done'], 'XnestedDone')
2164 quit
2165 END
2166 if !RunVim([], lines, '--clean')
2167 return
2168 endif
2169 assert_equal(['Done'], readfile('XnestedDone'))
2170 delete('XnestedDone')
2171enddef
2172
2173
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002174
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002175" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker