blob: 3b57e312b8cac7f390c3933c12a5b4eddf11030b [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 Moolenaarcd45ed02020-12-22 17:35:54 +0100302 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +0200303
304 lines =<< trim END
305 vim9script
306 def Func()
307 echo 'script'
308 enddef
309 def Outer()
310 def Func()
311 echo 'inner'
312 enddef
313 enddef
314 defcompile
315 END
316 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200317enddef
318
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100319def DefListAll()
320 def
321enddef
322
323def DefListOne()
324 def DefListOne
325enddef
326
327def DefListMatches()
328 def /DefList
329enddef
330
331def Test_nested_def_list()
332 var funcs = split(execute('call DefListAll()'), "\n")
333 assert_true(len(funcs) > 10)
334 assert_true(funcs->index('def DefListAll()') >= 0)
335
336 funcs = split(execute('call DefListOne()'), "\n")
337 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
338
339 funcs = split(execute('call DefListMatches()'), "\n")
340 assert_true(len(funcs) >= 3)
341 assert_true(funcs->index('def DefListAll()') >= 0)
342 assert_true(funcs->index('def DefListOne()') >= 0)
343 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +0100344
345 var lines =<< trim END
346 vim9script
347 def Func()
348 def +Func+
349 enddef
350 defcompile
351 END
352 CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +0100353enddef
354
Bram Moolenaar333894b2020-08-01 18:53:07 +0200355def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200356 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200357 vim9script
358 def g:Func(): string
359 return 'global'
360 enddef
361 def Func(): string
362 return 'local'
363 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200364 g:Func()->assert_equal('global')
365 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100366 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +0200367 END
368 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200369
370 lines =<< trim END
371 vim9script
372 def g:Funcy()
373 echo 'funcy'
374 enddef
375 s:Funcy()
376 END
377 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200378enddef
379
Bram Moolenaar0f769812020-09-12 18:32:34 +0200380def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200381 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200382 vim9script
383 def g:Gfunc(): string
384 return 'global'
385 enddef
386 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200387 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200388 return Gfunc('testing')
389 enddef
390 g:Gfunc()->assert_equal('global')
391 AnotherFunc()->assert_equal(7)
392 delfunc g:Gfunc
393 END
394 CheckScriptSuccess(lines)
395
396 lines =<< trim END
397 vim9script
398 def g:Func(): string
399 return 'global'
400 enddef
401 def AnotherFunc()
402 g:Func = function('len')
403 enddef
404 AnotherFunc()
405 END
406 CheckScriptFailure(lines, 'E705:')
407 delfunc g:Func
408enddef
409
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200410func TakesOneArg(arg)
411 echo a:arg
412endfunc
413
414def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200415 CheckDefFailure(['TakesOneArg()'], 'E119:')
416 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
417 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
418 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200419
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200420 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200421 vim9script
422 def Func(s: string)
423 echo s
424 enddef
425 Func([])
426 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200427 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200428
429 lines =<< trim END
430 vim9script
431 def FuncOne(nr: number)
432 echo nr
433 enddef
434 def FuncTwo()
435 FuncOne()
436 enddef
437 defcompile
438 END
439 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200440 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200441 try
442 source Xscript
443 catch
444 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
445 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
446 didCatch = true
447 endtry
448 assert_true(didCatch)
449
450 lines =<< trim END
451 vim9script
452 def FuncOne(nr: number)
453 echo nr
454 enddef
455 def FuncTwo()
456 FuncOne(1, 2)
457 enddef
458 defcompile
459 END
460 writefile(lines, 'Xscript')
461 didCatch = false
462 try
463 source Xscript
464 catch
465 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
466 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
467 didCatch = true
468 endtry
469 assert_true(didCatch)
470
471 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200472enddef
473
Bram Moolenaar50824712020-12-20 21:10:17 +0100474def Test_call_funcref_wrong_args()
475 var head =<< trim END
476 vim9script
477 def Func3(a1: string, a2: number, a3: list<number>)
478 echo a1 .. a2 .. a3[0]
479 enddef
480 def Testme()
481 var funcMap: dict<func> = {func: Func3}
482 END
483 var tail =<< trim END
484 enddef
485 Testme()
486 END
487 CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
488
489 CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
490 CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
491enddef
492
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +0100493def Test_call_lambda_args()
494 CheckDefFailure(['echo {i -> 0}()'],
495 'E119: Not enough arguments for function: {i -> 0}()')
496
497 var lines =<< trim END
498 var Ref = {x: number, y: number -> x + y}
499 echo Ref(1, 'x')
500 END
501 CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
502enddef
503
Bram Moolenaar709664c2020-12-12 14:33:41 +0100504def Test_lambda_uses_assigned_var()
505 CheckDefSuccess([
506 'var x: any = "aaa"'
507 'x = filter(["bbb"], {_, v -> v =~ x})'])
508enddef
509
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200510" Default arg and varargs
511def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200512 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200513 for s in rest
514 res ..= ',' .. s
515 endfor
516 return res
517enddef
518
519def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200520 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200521 MyDefVarargs('one')->assert_equal('one,foo')
522 MyDefVarargs('one', 'two')->assert_equal('one,two')
523 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200524 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200525 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200526 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200527 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200528
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200529 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200530 vim9script
531 def Func(...l: list<string>)
532 echo l
533 enddef
534 Func('a', 'b', 'c')
535 END
536 CheckScriptSuccess(lines)
537
538 lines =<< trim END
539 vim9script
540 def Func(...l: list<string>)
541 echo l
542 enddef
543 Func()
544 END
545 CheckScriptSuccess(lines)
546
547 lines =<< trim END
548 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200549 def Func(...l: any)
550 echo l
551 enddef
552 Func(0)
553 END
554 CheckScriptSuccess(lines)
555
556 lines =<< trim END
557 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200558 def Func(..._l: list<string>)
559 echo _l
560 enddef
561 Func('a', 'b', 'c')
562 END
563 CheckScriptSuccess(lines)
564
565 lines =<< trim END
566 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200567 def Func(...l: list<string>)
568 echo l
569 enddef
570 Func(1, 2, 3)
571 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200572 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200573
574 lines =<< trim END
575 vim9script
576 def Func(...l: list<string>)
577 echo l
578 enddef
579 Func('a', 9)
580 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200581 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200582
583 lines =<< trim END
584 vim9script
585 def Func(...l: list<string>)
586 echo l
587 enddef
588 Func(1, 'a')
589 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200590 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200591enddef
592
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200593let s:value = ''
594
595def FuncOneDefArg(opt = 'text')
596 s:value = opt
597enddef
598
599def FuncTwoDefArg(nr = 123, opt = 'text'): string
600 return nr .. opt
601enddef
602
603def FuncVarargs(...arg: list<string>): string
604 return join(arg, ',')
605enddef
606
607def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200608 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200609 RefDefArg = FuncOneDefArg
610 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200611 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200612 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200613 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200614
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200615 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200616 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200617 RefDef2Arg()->assert_equal('123text')
618 RefDef2Arg(99)->assert_equal('99text')
619 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200620
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200621 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
622 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200623
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200624 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200625 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200626 RefVarargs()->assert_equal('')
627 RefVarargs('one')->assert_equal('one')
628 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200629
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200630 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
631 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200632enddef
633
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200634" Only varargs
635def MyVarargsOnly(...args: list<string>): string
636 return join(args, ',')
637enddef
638
639def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200640 MyVarargsOnly()->assert_equal('')
641 MyVarargsOnly('one')->assert_equal('one')
642 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200643 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
644 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200645enddef
646
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200647def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200648 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200649 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200650 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200651enddef
652
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200653def DictArg(arg: dict<string>)
654 arg['key'] = 'value'
655enddef
656
657def ListArg(arg: list<string>)
658 arg[0] = 'value'
659enddef
660
661def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200662 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200663 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200664 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200665 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200666 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200667 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200668 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200669
Bram Moolenaard2c61702020-09-06 15:58:36 +0200670 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100671 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200672enddef
673
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200674" These argument names are reserved in legacy functions.
675def WithReservedNames(firstline: string, lastline: string): string
676 return firstline .. lastline
677enddef
678
679def Test_argument_names()
680 assert_equal('OK', WithReservedNames('O', 'K'))
681enddef
682
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200683def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200684 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200685 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200686enddef
687
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200688func DefinedLater(arg)
689 return a:arg
690endfunc
691
692def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200693 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200694 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
695 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200696
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200697 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200698 vim9script
699 def RetNumber(): number
700 return 123
701 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200702 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200703 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200704 END
705 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200706
707 lines =<< trim END
708 vim9script
709 def RetNumber(): number
710 return 123
711 enddef
712 def Bar(F: func: number): number
713 return F()
714 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200715 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200716 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200717 END
718 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200719
720 lines =<< trim END
721 vim9script
722 def UseNumber(nr: number)
723 echo nr
724 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200725 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200726 Funcref(123)
727 END
728 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200729
730 lines =<< trim END
731 vim9script
732 def UseNumber(nr: number)
733 echo nr
734 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200735 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200736 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200737 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200738
739 lines =<< trim END
740 vim9script
741 def EchoNr(nr = 34)
742 g:echo = nr
743 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200744 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200745 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200746 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200747 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200748 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200749 END
750 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200751
752 lines =<< trim END
753 vim9script
754 def EchoList(...l: list<number>)
755 g:echo = l
756 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200757 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200758 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200759 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200760 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200761 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200762 END
763 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200764
765 lines =<< trim END
766 vim9script
767 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
768 g:optarg = opt
769 g:listarg = l
770 return nr
771 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200772 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200773 Funcref(10)->assert_equal(10)
774 g:optarg->assert_equal(12)
775 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200776
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200777 Funcref(11, 22)->assert_equal(11)
778 g:optarg->assert_equal(22)
779 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200780
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200781 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
782 g:optarg->assert_equal(18)
783 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200784 END
785 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200786enddef
787
788let SomeFunc = function('len')
789let NotAFunc = 'text'
790
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200791def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200792 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200793 var Ref1: func(bool): string
794 var Ref2: func(bool): number
795 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200796 Ref3 = g:cond ? Ref1 : Ref2
797
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200798 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200799 var Refa1: func(bool): number
800 var Refa2: func(bool, number): number
801 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200802 Refa3 = g:cond ? Refa1 : Refa2
803
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200804 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200805 var Refb1: func(bool, string): number
806 var Refb2: func(string, number): number
807 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200808 Refb3 = g:cond ? Refb1 : Refb2
809enddef
810
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200811def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200812 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200813enddef
814
815def DefinedEvenLater(arg: string): string
816 return arg
817enddef
818
819def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200820 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200821 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200822enddef
823
824def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200825 CheckScriptFailure([
826 'def Func(): number',
827 'return "a"',
828 'enddef',
829 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100830 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200831 CheckScriptFailure([
832 'def Func(): string',
833 'return 1',
834 'enddef',
835 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100836 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200837 CheckScriptFailure([
838 'def Func(): void',
839 'return "a"',
840 'enddef',
841 'defcompile'],
842 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100843 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200844 CheckScriptFailure([
845 'def Func()',
846 'return "a"',
847 'enddef',
848 'defcompile'],
849 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100850 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200851
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200852 CheckScriptFailure([
853 'def Func(): number',
854 'return',
855 'enddef',
856 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100857 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200858
859 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100860 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200861 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100862 delfunc! g:Func
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200863 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100864 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200865
866 CheckScriptFailure([
867 'vim9script',
868 'def FuncB()',
869 ' return 123',
870 'enddef',
871 'def FuncA()',
872 ' FuncB()',
873 'enddef',
874 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200875enddef
876
877def Test_arg_type_wrong()
878 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200879 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200880 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200881 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200882enddef
883
884def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200885 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200886 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200887 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200888 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200889 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200890 enddef
891 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200892 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200893
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200894 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200895 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200896 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200897
Bram Moolenaar67979662020-06-20 22:50:47 +0200898 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200899 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200900 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200901
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200902 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200903 def ListFunc(arg: list<number>)
904 listvar = arg
905 enddef
906 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200907 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200908
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200909 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200910 def DictFunc(arg: dict<number>)
911 dictvar = arg
912 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +0100913 {a: 1, b: 2}->DictFunc()
914 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200915 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100916 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200917 enddef
918 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +0100919 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200920
Bram Moolenaare0de1712020-12-02 17:36:54 +0100921 {a: 3, b: 4}->DictFunc()
922 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200923
924 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200925 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200926 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200927 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200928
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200929 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200930 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200931 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200932 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200933 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200934 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200935
936 def UseString()
937 'xyork'->MyFunc()
938 enddef
939 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200940 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200941
Bram Moolenaar10409562020-07-29 20:00:38 +0200942 def UseString2()
943 "knife"->MyFunc()
944 enddef
945 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200946 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200947
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200948 # prepending a colon makes it a mark
949 new
950 setline(1, ['aaa', 'bbb', 'ccc'])
951 normal! 3Gmt1G
952 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200953 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200954 bwipe!
955
Bram Moolenaare6b53242020-07-01 17:28:33 +0200956 MyFunc(
957 'continued'
958 )
959 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200960 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200961 )
962
963 call MyFunc(
964 'more'
965 ..
966 'lines'
967 )
968 assert_equal(
969 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200970 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200971 END
972 writefile(lines, 'Xcall.vim')
973 source Xcall.vim
974 delete('Xcall.vim')
975enddef
976
977def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200978 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200979 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200980 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200981 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200982 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200983 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200984 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200985 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200986 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200987enddef
988
Bram Moolenaar65b95452020-07-19 14:03:09 +0200989def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200990 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200991 vim9script
992 def MyFunc(arg: string)
993 echo arg
994 enddef
995 MyFunc(1234)
996 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200997 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200998enddef
999
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001000def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001001 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001002 vim9script
1003 const var = ''
1004 def MyFunc(arg: string)
1005 var = 'asdf'
1006 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001007 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001008 END
1009 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001010 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001011 delete('Xcall_const.vim')
1012enddef
1013
1014" Test that inside :function a Python function can be defined, :def is not
1015" recognized.
1016func Test_function_python()
1017 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02001018 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001019 execute py "<< EOF"
1020def do_something():
1021 return 1
1022EOF
1023endfunc
1024
1025def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001026 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001027 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001028 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001029 echo 'hello'
1030 enddef
1031
1032 def CallGoneSoon()
1033 GoneSoon()
1034 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001035 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001036
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02001037 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001038 CallGoneSoon()
1039 END
1040 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001041 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
1042 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001043
1044 delete('XToDelFunc')
1045enddef
1046
1047def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02001048 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001049 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001050 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001051 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001052 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001053 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02001054 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001055 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02001056 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001057
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001058 g:Func0()->assert_equal(0)
1059 g:Func1()->assert_equal('Func1')
1060 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001061
1062 delfunc! Func0
1063 delfunc! Func1
1064 delfunc! Func2
1065enddef
1066
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001067def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001068 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001069 vim9script
1070 func Func(arg)
1071 echo a:arg
1072 endfunc
1073 Func('text')
1074 END
1075 writefile(lines, 'XVim9Func')
1076 so XVim9Func
1077
1078 delete('XVim9Func')
1079enddef
1080
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001081let s:funcResult = 0
1082
1083def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001084 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001085enddef
1086
1087def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001088 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001089 return 1234
1090enddef
1091
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001092def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001093 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001094 return 'text'
1095enddef
1096
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001097def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001098 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001099enddef
1100
1101def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001102 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001103 return arg
1104enddef
1105
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001106def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001107 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001108enddef
1109
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001110def FuncOneArgRetString(arg: string): string
1111 return arg
1112enddef
1113
Bram Moolenaar89228602020-04-05 22:14:54 +02001114def FuncOneArgRetAny(arg: any): any
1115 return arg
1116enddef
1117
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001118def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001119 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001120 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001121 Ref1 = FuncNoArgNoRet
1122 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001123 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001124
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001125 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001126 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001127 Ref2 = FuncNoArgNoRet
1128 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001129 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001130
Bram Moolenaar53900992020-08-22 19:02:02 +02001131 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001132 Ref2 = FuncOneArgNoRet
1133 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001134 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001135
Bram Moolenaar53900992020-08-22 19:02:02 +02001136 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001137 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001138 Ref2()->assert_equal(1234)
1139 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001140
Bram Moolenaar53900992020-08-22 19:02:02 +02001141 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001142 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001143 Ref2(13)->assert_equal(13)
1144 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001145enddef
1146
Bram Moolenaar9978d472020-07-05 16:01:56 +02001147def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001148 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001149 for n in repeat([1], 3)
1150 res += n
1151 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001152 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001153
1154 res = 0
1155 for n in add([1, 2], 3)
1156 res += n
1157 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001158 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001159enddef
1160
Bram Moolenaar846178a2020-07-05 17:04:13 +02001161def Test_argv_return_type()
1162 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001163 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001164 for name in argv()
1165 res ..= name
1166 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001167 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001168enddef
1169
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001170def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001171 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001172 RefVoid = FuncNoArgNoRet
1173 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001174 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1175 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001176
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001177 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001178 RefAny = FuncNoArgRetNumber
1179 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001180 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1181 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001182
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001183 var RefAnyNoArgs: func: any = RefAny
1184
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001185 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001186 RefNr = FuncNoArgRetNumber
1187 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001188 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1189 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001190
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001191 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001192 RefStr = FuncNoArgRetString
1193 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001194 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1195 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001196enddef
1197
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001198def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001199 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001200
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001201 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1202 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1203 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): 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)')
1206 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 +02001207
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001208 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1209 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1210 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:')
1211 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001212enddef
1213
Bram Moolenaar89228602020-04-05 22:14:54 +02001214def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001215 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001216 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001217 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001218
1219 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001220 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001221
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001222 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001223 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001224 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001225
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001226 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001227enddef
1228
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001229def Test_func_common_type()
1230 def FuncOne(n: number): number
1231 return n
1232 enddef
1233 def FuncTwo(s: string): number
1234 return len(s)
1235 enddef
1236 def FuncThree(n: number, s: string): number
1237 return n + len(s)
1238 enddef
1239 var list = [FuncOne, FuncTwo, FuncThree]
1240 assert_equal(8, list[0](8))
1241 assert_equal(4, list[1]('word'))
1242 assert_equal(7, list[2](3, 'word'))
1243enddef
1244
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001245def MultiLine(
1246 arg1: string,
1247 arg2 = 1234,
1248 ...rest: list<string>
1249 ): string
1250 return arg1 .. arg2 .. join(rest, '-')
1251enddef
1252
Bram Moolenaar2c330432020-04-13 14:41:35 +02001253def MultiLineComment(
1254 arg1: string, # comment
1255 arg2 = 1234, # comment
1256 ...rest: list<string> # comment
1257 ): string # comment
1258 return arg1 .. arg2 .. join(rest, '-')
1259enddef
1260
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001261def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001262 MultiLine('text')->assert_equal('text1234')
1263 MultiLine('text', 777)->assert_equal('text777')
1264 MultiLine('text', 777, 'one')->assert_equal('text777one')
1265 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001266enddef
1267
Bram Moolenaar23e03252020-04-12 22:22:31 +02001268func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001269 call MultiLine('text')->assert_equal('text1234')
1270 call MultiLine('text', 777)->assert_equal('text777')
1271 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1272 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001273endfunc
1274
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001275
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001276" When using CheckScriptFailure() for the below test, E1010 is generated instead
1277" of E1056.
1278func Test_E1056_1059()
1279 let caught_1056 = 0
1280 try
1281 def F():
1282 return 1
1283 enddef
1284 catch /E1056:/
1285 let caught_1056 = 1
1286 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001287 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001288
1289 let caught_1059 = 0
1290 try
1291 def F5(items : list)
1292 echo 'a'
1293 enddef
1294 catch /E1059:/
1295 let caught_1059 = 1
1296 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001297 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001298endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001299
Bram Moolenaar015f4262020-05-05 21:25:22 +02001300func DelMe()
1301 echo 'DelMe'
1302endfunc
1303
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001304def Test_error_reporting()
1305 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001306 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001307 " comment
1308 def Func()
1309 # comment
1310 # comment
1311 invalid
1312 enddef
1313 defcompile
1314 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001315 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001316 try
1317 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001318 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001319 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001320 v:exception->assert_match('Invalid command: invalid')
1321 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001322 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001323 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001324
1325 # comment lines after the start of the function
1326 lines =<< trim END
1327 " comment
1328 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001329 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001330 # comment
1331 # comment
1332 invalid
1333 enddef
1334 defcompile
1335 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001336 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001337 try
1338 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001339 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001340 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001341 v:exception->assert_match('Invalid command: invalid')
1342 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001343 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001344 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001345
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001346 lines =<< trim END
1347 vim9script
1348 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01001349 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001350 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001351 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001352 enddef
1353 defcompile
1354 Func()
1355 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001356 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001357 try
1358 source Xdef
1359 assert_report('should have failed')
1360 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001361 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001362 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001363 delfunc! g:Func
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001364
Bram Moolenaar08052222020-09-14 17:04:31 +02001365 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001366enddef
1367
Bram Moolenaar015f4262020-05-05 21:25:22 +02001368def Test_deleted_function()
1369 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001370 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001371 'delfunc g:DelMe',
1372 'echo RefMe()'], 'E117:')
1373enddef
1374
1375def Test_unknown_function()
1376 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001377 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001378 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001379enddef
1380
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001381def RefFunc(Ref: func(string): string): string
1382 return Ref('more')
1383enddef
1384
1385def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001386 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001387 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001388enddef
1389
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001390def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001391 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001392 g:Ref = {s -> local .. s}
1393enddef
1394
1395def Test_closure_ref_after_return()
1396 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001397 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001398 unlet g:Ref
1399enddef
1400
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001401def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001402 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001403 g:Extend = {s -> local->add(s)}
1404 g:Read = {-> local}
1405enddef
1406
1407def Test_closure_two_refs()
1408 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001409 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001410 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001411 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001412 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001413 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001414
1415 unlet g:Extend
1416 unlet g:Read
1417enddef
1418
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001419def ReadRef(Ref: func(): list<string>): string
1420 return join(Ref(), ' ')
1421enddef
1422
Bram Moolenaar5e654232020-09-16 15:22:00 +02001423def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001424 Ref(add)
1425enddef
1426
1427def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001428 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001429 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001430 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001431 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001432 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001433 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001434
1435 unlet g:Extend
1436 unlet g:Read
1437enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001438
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001439def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001440 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001441 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1442enddef
1443
1444def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001445 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001446 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1447enddef
1448
1449def Test_closure_using_argument()
1450 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001451 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001452
1453 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001454 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001455
1456 unlet g:UseArg
1457 unlet g:UseVararg
1458enddef
1459
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001460def MakeGetAndAppendRefs()
1461 var local = 'a'
1462
1463 def Append(arg: string)
1464 local ..= arg
1465 enddef
1466 g:Append = Append
1467
1468 def Get(): string
1469 return local
1470 enddef
1471 g:Get = Get
1472enddef
1473
1474def Test_closure_append_get()
1475 MakeGetAndAppendRefs()
1476 g:Get()->assert_equal('a')
1477 g:Append('-b')
1478 g:Get()->assert_equal('a-b')
1479 g:Append('-c')
1480 g:Get()->assert_equal('a-b-c')
1481
1482 unlet g:Append
1483 unlet g:Get
1484enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001485
Bram Moolenaar04b12692020-05-04 23:24:44 +02001486def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001487 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001488 def Closure(arg: string): string
1489 return local .. arg
1490 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001491 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001492enddef
1493
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001494func GetResult(Ref)
1495 return a:Ref('some')
1496endfunc
1497
1498def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001499 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001500 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001501 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001502enddef
1503
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001504def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001505 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001506 vim9script
1507 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001508 var name = 0
1509 for i in range(2)
1510 timer_start(0, {-> name})
1511 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001512 enddef
1513 Func()
1514 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001515 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001516enddef
1517
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001518def Test_nested_closure_used()
1519 var lines =<< trim END
1520 vim9script
1521 def Func()
1522 var x = 'hello'
1523 var Closure = {-> x}
1524 g:Myclosure = {-> Closure()}
1525 enddef
1526 Func()
1527 assert_equal('hello', g:Myclosure())
1528 END
1529 CheckScriptSuccess(lines)
1530enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001531
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001532def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001533 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001534 vim9script
1535 def FuncA()
1536 FuncB(0)
1537 enddef
1538 def FuncB(n: number): list<string>
1539 return map([0], {_, v -> n})
1540 enddef
1541 FuncA()
1542 END
1543 CheckScriptFailure(lines, 'E1012:')
1544enddef
1545
Bram Moolenaarf112f302020-12-20 17:47:52 +01001546def Test_global_closure()
1547 var lines =<< trim END
1548 vim9script
1549 def ReverseEveryNLines(n: number, line1: number, line2: number)
1550 var mods = 'sil keepj keepp lockm '
1551 var range = ':' .. line1 .. ',' .. line2
1552 def g:Offset(): number
1553 var offset = (line('.') - line1 + 1) % n
1554 return offset != 0 ? offset : n
1555 enddef
1556 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
1557 enddef
1558
1559 new
1560 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
1561 ReverseEveryNLines(3, 1, 9)
1562 END
1563 CheckScriptSuccess(lines)
1564 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
1565 assert_equal(expected, getline(1, 9))
1566 bwipe!
1567enddef
1568
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001569def Test_global_closure_called_directly()
1570 var lines =<< trim END
1571 vim9script
1572 def Outer()
1573 var x = 1
1574 def g:Inner()
1575 var y = x
1576 x += 1
1577 assert_equal(1, y)
1578 enddef
1579 g:Inner()
1580 assert_equal(2, x)
1581 enddef
1582 Outer()
1583 END
1584 CheckScriptSuccess(lines)
1585 delfunc g:Inner
1586enddef
1587
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01001588def Test_failure_in_called_function()
1589 # this was using the frame index as the return value
1590 var lines =<< trim END
1591 vim9script
1592 au TerminalWinOpen * eval [][0]
1593 def PopupTerm(a: any)
1594 # make sure typvals on stack are string
1595 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1596 FireEvent()
1597 enddef
1598 def FireEvent()
1599 do TerminalWinOpen
1600 enddef
1601 # use try/catch to make eval fail
1602 try
1603 call PopupTerm(0)
1604 catch
1605 endtry
1606 au! TerminalWinOpen
1607 END
1608 CheckScriptSuccess(lines)
1609enddef
1610
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001611def Test_nested_lambda()
1612 var lines =<< trim END
1613 vim9script
1614 def Func()
1615 var x = 4
1616 var Lambda1 = {-> 7}
1617 var Lambda2 = {-> [Lambda1(), x]}
1618 var res = Lambda2()
1619 assert_equal([7, 4], res)
1620 enddef
1621 Func()
1622 END
1623 CheckScriptSuccess(lines)
1624enddef
1625
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01001626def Shadowed(): list<number>
1627 var FuncList: list<func: number> = [{ -> 42}]
1628 return FuncList->map({_, Shadowed -> Shadowed()})
1629enddef
1630
1631def Test_lambda_arg_shadows_func()
1632 assert_equal([42], Shadowed())
1633enddef
1634
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001635def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001636 var path: string = empty(dir)
1637 \ ? 'empty'
1638 \ : 'full'
1639 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001640enddef
1641
1642def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001643 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001644enddef
1645
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01001646def Test_script_var_in_lambda()
1647 var lines =<< trim END
1648 vim9script
1649 var script = 'test'
1650 assert_equal(['test'], map(['one'], {-> script}))
1651 END
1652 CheckScriptSuccess(lines)
1653enddef
1654
Bram Moolenaar5e654232020-09-16 15:22:00 +02001655def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001656 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001657 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001658 ->toupper()})
1659 ->reverse()
1660 return x
1661enddef
1662
1663def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001664 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001665enddef
1666
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001667func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001668 CheckScreendump
1669
1670 let lines =<< trim END
1671 vim9script
1672 def EchoNothing()
1673 silent echo ''
1674 enddef
1675 defcompile
1676 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001677 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001678
1679 " Check that the balloon shows up after a mouse move
1680 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001681 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001682 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1683
1684 " clean up
1685 call StopVimInTerminal(buf)
1686 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001687endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001688
Bram Moolenaar171fb922020-10-28 16:54:47 +01001689def SilentlyError()
1690 execute('silent! invalid')
1691 g:did_it = 'yes'
1692enddef
1693
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001694func UserError()
1695 silent! invalid
1696endfunc
1697
1698def SilentlyUserError()
1699 UserError()
1700 g:did_it = 'yes'
1701enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01001702
1703" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01001704func Test_ignore_silent_error()
1705 let g:did_it = 'no'
1706 call SilentlyError()
1707 call assert_equal('yes', g:did_it)
1708
Bram Moolenaar28ee8922020-10-28 20:20:00 +01001709 let g:did_it = 'no'
1710 call SilentlyUserError()
1711 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01001712
1713 unlet g:did_it
1714endfunc
1715
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001716def Test_ignore_silent_error_in_filter()
1717 var lines =<< trim END
1718 vim9script
1719 def Filter(winid: number, key: string): bool
1720 if key == 'o'
1721 silent! eval [][0]
1722 return true
1723 endif
1724 return popup_filter_menu(winid, key)
1725 enddef
1726
Bram Moolenaare0de1712020-12-02 17:36:54 +01001727 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01001728 feedkeys("o\r", 'xnt')
1729 END
1730 CheckScriptSuccess(lines)
1731enddef
1732
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001733def Fibonacci(n: number): number
1734 if n < 2
1735 return n
1736 else
1737 return Fibonacci(n - 1) + Fibonacci(n - 2)
1738 endif
1739enddef
1740
Bram Moolenaar985116a2020-07-12 17:31:09 +02001741def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001742 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001743enddef
1744
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001745def TreeWalk(dir: string): list<any>
1746 return readdir(dir)->map({_, val ->
1747 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01001748 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001749 : val
1750 })
1751enddef
1752
1753def Test_closure_in_map()
1754 mkdir('XclosureDir/tdir', 'p')
1755 writefile(['111'], 'XclosureDir/file1')
1756 writefile(['222'], 'XclosureDir/file2')
1757 writefile(['333'], 'XclosureDir/tdir/file3')
1758
Bram Moolenaare0de1712020-12-02 17:36:54 +01001759 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001760
1761 delete('XclosureDir', 'rf')
1762enddef
1763
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001764def Test_invalid_function_name()
1765 var lines =<< trim END
1766 vim9script
1767 def s: list<string>
1768 END
1769 CheckScriptFailure(lines, 'E129:')
1770
1771 lines =<< trim END
1772 vim9script
1773 def g: list<string>
1774 END
1775 CheckScriptFailure(lines, 'E129:')
1776
1777 lines =<< trim END
1778 vim9script
1779 def <SID>: list<string>
1780 END
1781 CheckScriptFailure(lines, 'E884:')
1782
1783 lines =<< trim END
1784 vim9script
1785 def F list<string>
1786 END
1787 CheckScriptFailure(lines, 'E488:')
1788enddef
1789
Bram Moolenaara90afb92020-07-15 22:38:56 +02001790def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001791 var Xsetlist = function('setloclist', [0])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001792 Xsetlist([], ' ', {title: 'test'})
1793 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001794
1795 Xsetlist = function('setloclist', [0, [], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001796 Xsetlist({title: 'test'})
1797 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001798
1799 Xsetlist = function('setqflist')
Bram Moolenaare0de1712020-12-02 17:36:54 +01001800 Xsetlist([], ' ', {title: 'test'})
1801 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001802
1803 Xsetlist = function('setqflist', [[], ' '])
Bram Moolenaare0de1712020-12-02 17:36:54 +01001804 Xsetlist({title: 'test'})
1805 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001806
1807 var Len: func: number = function('len', ['word'])
1808 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02001809enddef
1810
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001811def Test_cmd_modifier()
1812 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001813 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001814enddef
1815
1816def Test_restore_modifiers()
1817 # check that when compiling a :def function command modifiers are not messed
1818 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001819 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001820 vim9script
1821 set eventignore=
1822 autocmd QuickFixCmdPost * copen
1823 def AutocmdsDisabled()
Bram Moolenaar6cf7e3b2020-10-28 14:31:16 +01001824 eval 0
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001825 enddef
1826 func Func()
1827 noautocmd call s:AutocmdsDisabled()
1828 let g:ei_after = &eventignore
1829 endfunc
1830 Func()
1831 END
1832 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001833 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001834enddef
1835
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001836def StackTop()
1837 eval 1
1838 eval 2
1839 # call not on fourth line
1840 StackBot()
1841enddef
1842
1843def StackBot()
1844 # throw an error
1845 eval [][0]
1846enddef
1847
1848def Test_callstack_def()
1849 try
1850 StackTop()
1851 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001852 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001853 endtry
1854enddef
1855
Bram Moolenaare8211a32020-10-09 22:04:29 +02001856" Re-using spot for variable used in block
1857def Test_block_scoped_var()
1858 var lines =<< trim END
1859 vim9script
1860 def Func()
1861 var x = ['a', 'b', 'c']
1862 if 1
1863 var y = 'x'
1864 map(x, {-> y})
1865 endif
1866 var z = x
1867 assert_equal(['x', 'x', 'x'], z)
1868 enddef
1869 Func()
1870 END
1871 CheckScriptSuccess(lines)
1872enddef
1873
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001874def Test_reset_did_emsg()
1875 var lines =<< trim END
1876 @s = 'blah'
1877 au BufWinLeave * #
1878 def Func()
1879 var winid = popup_create('popup', {})
1880 exe '*s'
1881 popup_close(winid)
1882 enddef
1883 Func()
1884 END
1885 CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001886 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01001887enddef
1888
Bram Moolenaar57f799e2020-12-12 20:42:19 +01001889def Test_did_emsg_reset()
1890 # executing an autocommand resets did_emsg, this should not result in a
1891 # builtin function considered failing
1892 var lines =<< trim END
1893 vim9script
1894 au BufWinLeave * #
1895 def Func()
1896 popup_menu('', {callback: {-> popup_create('', {})->popup_close()}})
1897 eval [][0]
1898 enddef
1899 nno <F3> <cmd>call <sid>Func()<cr>
1900 feedkeys("\<F3>\e", 'xt')
1901 END
1902 writefile(lines, 'XemsgReset')
1903 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
1904 delete('XemsgReset')
1905 nunmap <F3>
1906 au! BufWinLeave
1907enddef
1908
Bram Moolenaar56602ba2020-12-05 21:22:08 +01001909def Test_abort_with_silent_call()
1910 var lines =<< trim END
1911 vim9script
1912 g:result = 'none'
1913 def Func()
1914 g:result += 3
1915 g:result = 'yes'
1916 enddef
1917 # error is silenced, but function aborts on error
1918 silent! Func()
1919 assert_equal('none', g:result)
1920 unlet g:result
1921 END
1922 CheckScriptSuccess(lines)
1923enddef
1924
Bram Moolenaarf665e972020-12-05 19:17:16 +01001925def Test_continues_with_silent_error()
1926 var lines =<< trim END
1927 vim9script
1928 g:result = 'none'
1929 def Func()
1930 silent! g:result += 3
1931 g:result = 'yes'
1932 enddef
1933 # error is silenced, function does not abort
1934 Func()
1935 assert_equal('yes', g:result)
1936 unlet g:result
1937 END
1938 CheckScriptSuccess(lines)
1939enddef
1940
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001941def Test_abort_even_with_silent()
1942 var lines =<< trim END
1943 vim9script
1944 g:result = 'none'
1945 def Func()
1946 eval {-> ''}() .. '' .. {}['X']
1947 g:result = 'yes'
1948 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01001949 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001950 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001951 unlet g:result
1952 END
1953 CheckScriptSuccess(lines)
1954enddef
1955
Bram Moolenaarf665e972020-12-05 19:17:16 +01001956def Test_cmdmod_silent_restored()
1957 var lines =<< trim END
1958 vim9script
1959 def Func()
1960 g:result = 'none'
1961 silent! g:result += 3
1962 g:result = 'none'
1963 g:result += 3
1964 enddef
1965 Func()
1966 END
1967 # can't use CheckScriptFailure, it ignores the :silent!
1968 var fname = 'Xdefsilent'
1969 writefile(lines, fname)
1970 var caught = 'no'
1971 try
1972 exe 'source ' .. fname
1973 catch /E1030:/
1974 caught = 'yes'
1975 assert_match('Func, line 4', v:throwpoint)
1976 endtry
1977 assert_equal('yes', caught)
1978 delete(fname)
1979enddef
1980
Bram Moolenaar4029cab2020-12-05 18:13:27 +01001981def Test_dict_member_with_silent()
1982 var lines =<< trim END
1983 vim9script
1984 g:result = 'none'
1985 var d: dict<any>
1986 def Func()
1987 try
1988 g:result = map([], {_, v -> {}[v]})->join() .. d['']
1989 catch
1990 endtry
1991 enddef
1992 silent! Func()
1993 assert_equal('0', g:result)
1994 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01001995 END
1996 CheckScriptSuccess(lines)
1997enddef
1998
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01001999def Test_opfunc()
2000 nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
2001 def g:Opfunc(_: any): string
2002 setline(1, 'ASDF')
2003 return ''
2004 enddef
2005 new
2006 setline(1, 'asdf')
2007 feedkeys("\<F3>$", 'x')
2008 assert_equal('ASDF', getline(1))
2009
2010 bwipe!
2011 nunmap <F3>
2012enddef
2013
Bram Moolenaar077a4232020-12-22 18:33:27 +01002014" this was crashing on exit
2015def Test_nested_lambda_in_closure()
2016 var lines =<< trim END
2017 vim9script
2018 def Outer()
2019 def g:Inner()
2020 echo map([1, 2, 3], {_, v -> v + 1})
2021 enddef
2022 g:Inner()
2023 enddef
2024 defcompile
2025 writefile(['Done'], 'XnestedDone')
2026 quit
2027 END
2028 if !RunVim([], lines, '--clean')
2029 return
2030 endif
2031 assert_equal(['Done'], readfile('XnestedDone'))
2032 delete('XnestedDone')
2033enddef
2034
2035
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002036
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002037" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker