blob: b008929611fd60b0d1eecb866e1c2f6cc65372e3 [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 Moolenaar62aec932022-01-29 21:45:34 +00006import './vim9.vim' as v9
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()
Bram Moolenaare8c46602021-04-05 22:27:37 +020021 call TestCompilingErrorInTry()
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020022endfunc
23
24def TestCompilingError()
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020025 var lines =<< trim END
26 vim9script
27 def Fails()
28 echo nothing
29 enddef
30 defcompile
31 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +010032 writefile(lines, 'XTest_compile_error', 'D')
Bram Moolenaar62aec932022-01-29 21:45:34 +000033 var buf = g:RunVimInTerminal('-S XTest_compile_error',
Bram Moolenaare0de1712020-12-02 17:36:54 +010034 {rows: 10, wait_for_ruler: 0})
Bram Moolenaar62aec932022-01-29 21:45:34 +000035 g:WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
36 g:Term_getlines(buf, range(1, 9))))
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020037
38 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +000039 g:StopVimInTerminal(buf)
Bram Moolenaare8c46602021-04-05 22:27:37 +020040enddef
41
42def TestCompilingErrorInTry()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010043 var dir = 'Xcompdir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +010044 mkdir(dir, 'pR')
Bram Moolenaare8c46602021-04-05 22:27:37 +020045
46 var lines =<< trim END
47 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +000048 export def OnlyCompiled()
Bram Moolenaare8c46602021-04-05 22:27:37 +020049 g:runtime = 'yes'
50 invalid
51 enddef
52 END
53 writefile(lines, dir .. '/script.vim')
54
55 lines =<< trim END
56 vim9script
57 todo
58 try
59 script#OnlyCompiled()
60 catch /nothing/
61 endtry
62 END
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +010063 lines[1] = 'set rtp=' .. getcwd() .. '/Xcompdir'
Bram Moolenaarf5fec052022-09-11 11:49:22 +010064 writefile(lines, 'XTest_compile_error', 'D')
Bram Moolenaare8c46602021-04-05 22:27:37 +020065
Bram Moolenaar62aec932022-01-29 21:45:34 +000066 var buf = g:RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0})
67 g:WaitForAssert(() => assert_match('Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid',
68 g:Term_getlines(buf, range(1, 9))))
Bram Moolenaare8c46602021-04-05 22:27:37 +020069
70 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +000071 g:StopVimInTerminal(buf)
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020072enddef
73
Bram Moolenaarad6d9cc2022-08-08 21:43:11 +010074def Test_comment_error()
75 v9.CheckDefFailure(['#{ comment'], 'E1170:')
76enddef
77
Bram Moolenaarb55d6182021-06-08 22:01:53 +020078def Test_compile_error_in_called_function()
79 var lines =<< trim END
80 vim9script
81 var n: number
82 def Foo()
83 &hls = n
84 enddef
85 def Bar()
86 Foo()
87 enddef
88 silent! Foo()
89 Bar()
90 END
Bram Moolenaar62aec932022-01-29 21:45:34 +000091 v9.CheckScriptFailureList(lines, ['E1012:', 'E1191:'])
Bram Moolenaarb55d6182021-06-08 22:01:53 +020092enddef
93
Bram Moolenaar22f17a22021-06-21 20:48:58 +020094def Test_wrong_function_name()
95 var lines =<< trim END
96 vim9script
97 func _Foo()
98 echo 'foo'
99 endfunc
100 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000101 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaar22f17a22021-06-21 20:48:58 +0200102
103 lines =<< trim END
104 vim9script
105 def _Foo()
106 echo 'foo'
107 enddef
108 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000109 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaardea5ab02022-02-23 22:12:02 +0000110
111 lines =<< trim END
112 vim9script
113 var Object = {}
114 function Object.Method()
115 endfunction
116 END
117 v9.CheckScriptFailure(lines, 'E1182:')
118
119 lines =<< trim END
120 vim9script
121 var Object = {}
122 def Object.Method()
123 enddef
124 END
125 v9.CheckScriptFailure(lines, 'E1182:')
126
127 lines =<< trim END
128 vim9script
129 g:Object = {}
130 function g:Object.Method()
131 endfunction
132 END
133 v9.CheckScriptFailure(lines, 'E1182:')
134
135 lines =<< trim END
136 let s:Object = {}
137 def Define()
138 function s:Object.Method()
139 endfunction
140 enddef
141 defcompile
142 END
143 v9.CheckScriptFailure(lines, 'E1182:')
144 delfunc g:Define
145
146 lines =<< trim END
147 let s:Object = {}
148 def Define()
149 def Object.Method()
150 enddef
151 enddef
152 defcompile
153 END
154 v9.CheckScriptFailure(lines, 'E1182:')
155 delfunc g:Define
156
157 lines =<< trim END
158 let g:Object = {}
159 def Define()
160 function g:Object.Method()
161 endfunction
162 enddef
163 defcompile
164 END
165 v9.CheckScriptFailure(lines, 'E1182:')
166 delfunc g:Define
Bram Moolenaar22f17a22021-06-21 20:48:58 +0200167enddef
168
Ernie Rael3f821d62024-04-24 20:07:50 +0200169" Check that in a legacy script a :def accesses the correct script variables.
170" Github issue: #14615.
171def Test_access_var_from_legacy_def()
172 # Access a script variable by name WITH "s:" prefix.
173 var lines =<< trim END
174 let s:foo = 'init'
175 let s:xxfoo = 'init'
176 def! AccessVarFromLegacyDef()
177 s:xxfoo = 'CHANGED'
178 enddef
179 call AccessVarFromLegacyDef()
180 call assert_equal('init', s:foo)
181 call assert_equal('CHANGED', s:xxfoo)
182 END
183 v9.CheckScriptSuccess(lines)
184
185 # Access a script variable by name WITHOUT "s:" prefix;
186 # previously this accessed "foo" and not "xxfoo"
187 lines =<< trim END
188 let s:foo = 'init'
189 let s:xxfoo = 'init'
190 def! AccessVarFromLegacyDef()
191 xxfoo = 'CHANGED'
192 enddef
193 call AccessVarFromLegacyDef()
194 call assert_equal('init', s:foo)
195 call assert_equal('CHANGED', s:xxfoo)
196 END
197 v9.CheckScriptSuccess(lines)
198enddef
199
Bram Moolenaard4a9b7f2023-05-23 14:48:42 +0100200def Test_listing_function_error()
201 var lines =<< trim END
202 var filler = 123
203 func DoesNotExist
204 END
205 v9.CheckDefExecFailure(lines, 'E123:', 2)
206enddef
207
Bram Moolenaar3f45d672023-02-27 22:06:51 +0000208def Test_break_in_skipped_block()
209 var lines =<< trim END
210 vim9script
211
212 def FixStackFrame(): string
213 for _ in [2]
214 var path = 'xxx'
215 if !!path
216 if false
217 break
218 else
219 return 'foo'
220 endif
221 endif
222 endfor
223 return 'xxx'
224 enddef
225
226 disas FixStackFrame
227
228 FixStackFrame()
229 END
230 v9.CheckScriptSuccess(lines)
231enddef
232
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200233def Test_autoload_name_mismatch()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100234 var dir = 'Xnamedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100235 mkdir(dir, 'pR')
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200236
237 var lines =<< trim END
238 vim9script
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000239 export def NoFunction()
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200240 # comment
241 g:runtime = 'yes'
242 enddef
243 END
244 writefile(lines, dir .. '/script.vim')
245
246 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100247 exe 'set rtp=' .. getcwd() .. '/Xnamedir'
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200248 lines =<< trim END
249 call script#Function()
250 END
Bram Moolenaard8fe6d32022-01-30 18:40:44 +0000251 v9.CheckScriptFailure(lines, 'E117:', 1)
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200252
253 &rtp = save_rtp
Bram Moolenaarf48b2fa2021-04-12 22:02:36 +0200254enddef
255
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200256def Test_autoload_names()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100257 var dir = 'Xandir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100258 mkdir(dir, 'pR')
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200259
260 var lines =<< trim END
261 func foobar#function()
262 return 'yes'
263 endfunc
264 let foobar#var = 'no'
265 END
266 writefile(lines, dir .. '/foobar.vim')
267
268 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100269 exe 'set rtp=' .. getcwd() .. '/Xandir'
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200270
271 lines =<< trim END
272 assert_equal('yes', foobar#function())
273 var Function = foobar#function
274 assert_equal('yes', Function())
275
276 assert_equal('no', foobar#var)
277 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000278 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200279
280 &rtp = save_rtp
Bram Moolenaarf0a40692021-06-11 22:05:47 +0200281enddef
282
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200283def Test_autoload_error_in_script()
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100284 var dir = 'Xaedir/autoload'
Bram Moolenaarf5fec052022-09-11 11:49:22 +0100285 mkdir(dir, 'pR')
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200286
287 var lines =<< trim END
288 func scripterror#function()
289 let g:called_function = 'yes'
290 endfunc
291 let 0 = 1
292 END
293 writefile(lines, dir .. '/scripterror.vim')
294
295 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100296 exe 'set rtp=' .. getcwd() .. '/Xaedir'
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200297
298 g:called_function = 'no'
299 # The error in the autoload script cannot be checked with assert_fails(), use
300 # CheckDefSuccess() instead of CheckDefFailure()
301 try
Bram Moolenaar62aec932022-01-29 21:45:34 +0000302 v9.CheckDefSuccess(['scripterror#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200303 catch
304 assert_match('E121: Undefined variable: 0', v:exception)
305 endtry
306 assert_equal('no', g:called_function)
307
308 lines =<< trim END
309 func scriptcaught#function()
310 let g:called_function = 'yes'
311 endfunc
312 try
313 let 0 = 1
314 catch
315 let g:caught = v:exception
316 endtry
317 END
318 writefile(lines, dir .. '/scriptcaught.vim')
319
320 g:called_function = 'no'
Bram Moolenaar62aec932022-01-29 21:45:34 +0000321 v9.CheckDefSuccess(['scriptcaught#function()'])
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200322 assert_match('E121: Undefined variable: 0', g:caught)
323 assert_equal('yes', g:called_function)
324
325 &rtp = save_rtp
Bram Moolenaar88c89c72021-08-14 14:01:05 +0200326enddef
327
Bram Moolenaar62aec932022-01-29 21:45:34 +0000328def s:CallRecursive(n: number): number
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100329 return CallRecursive(n + 1)
330enddef
331
Bram Moolenaar62aec932022-01-29 21:45:34 +0000332def s:CallMapRecursive(l: list<number>): number
Bram Moolenaar2949cfd2020-12-31 21:28:47 +0100333 return map(l, (_, v) => CallMapRecursive([v]))[0]
Bram Moolenaar0ba48e82020-11-17 18:23:19 +0100334enddef
335
336def Test_funcdepth_error()
337 set maxfuncdepth=10
338
339 var caught = false
340 try
341 CallRecursive(1)
342 catch /E132:/
343 caught = true
344 endtry
345 assert_true(caught)
346
347 caught = false
348 try
349 CallMapRecursive([1])
350 catch /E132:/
351 caught = true
352 endtry
353 assert_true(caught)
354
355 set maxfuncdepth&
356enddef
357
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100358def Test_endfunc_enddef()
359 var lines =<< trim END
360 def Test()
361 echo 'test'
362 endfunc
363 enddef
364 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000365 v9.CheckScriptFailure(lines, 'E1151:', 3)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100366
367 lines =<< trim END
368 def Test()
369 func Nested()
370 echo 'test'
371 enddef
372 enddef
373 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000374 v9.CheckScriptFailure(lines, 'E1152:', 4)
Bram Moolenaar49f1e9e2021-03-22 20:49:02 +0100375
376 lines =<< trim END
377 def Ok()
378 echo 'hello'
379 enddef | echo 'there'
380 def Bad()
381 echo 'hello'
382 enddef there
383 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000384 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
Bram Moolenaar5178b1b2021-01-01 18:43:51 +0100385enddef
386
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100387def Test_missing_endfunc_enddef()
388 var lines =<< trim END
389 vim9script
390 def Test()
391 echo 'test'
392 endef
393 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000394 v9.CheckScriptFailure(lines, 'E1057:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100395
396 lines =<< trim END
397 vim9script
398 func Some()
399 echo 'test'
400 enfffunc
401 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000402 v9.CheckScriptFailure(lines, 'E126:', 2)
Bram Moolenaarb8ba9b92021-01-01 18:54:34 +0100403enddef
404
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100405def Test_white_space_before_paren()
406 var lines =<< trim END
407 vim9script
408 def Test ()
409 echo 'test'
410 enddef
411 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000412 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100413
414 lines =<< trim END
415 vim9script
416 func Test ()
417 echo 'test'
418 endfunc
419 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000420 v9.CheckScriptFailure(lines, 'E1068:', 2)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100421
422 lines =<< trim END
423 def Test ()
424 echo 'test'
425 enddef
426 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000427 v9.CheckScriptFailure(lines, 'E1068:', 1)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100428
429 lines =<< trim END
430 func Test ()
431 echo 'test'
432 endfunc
433 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000434 v9.CheckScriptSuccess(lines)
Bram Moolenaar4efd9942021-01-24 21:14:20 +0100435enddef
436
Bram Moolenaar832ea892021-01-08 21:55:26 +0100437def Test_enddef_dict_key()
438 var d = {
439 enddef: 'x',
440 endfunc: 'y',
441 }
442 assert_equal({enddef: 'x', endfunc: 'y'}, d)
443enddef
444
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200445def ReturnString(): string
446 return 'string'
447enddef
448
449def ReturnNumber(): number
450 return 123
451enddef
452
453let g:notNumber = 'string'
454
455def ReturnGlobal(): number
456 return g:notNumber
457enddef
458
459def Test_return_something()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000460 g:ReturnString()->assert_equal('string')
461 g:ReturnNumber()->assert_equal(123)
Bram Moolenaar848fadd2022-01-30 15:28:30 +0000462 assert_fails('g:ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaaref7aadb2022-01-18 18:46:07 +0000463
464 var lines =<< trim END
465 vim9script
466
467 def Msg()
468 echomsg 'in Msg()...'
469 enddef
470
471 def Func()
472 return Msg()
473 enddef
474 defcompile
475 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000476 v9.CheckScriptFailure(lines, 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200477enddef
478
Bram Moolenaare32e5162021-01-21 20:21:29 +0100479def Test_check_argument_type()
480 var lines =<< trim END
481 vim9script
482 def Val(a: number, b: number): number
483 return 0
484 enddef
485 def Func()
486 var x: any = true
487 Val(0, x)
488 enddef
489 disass Func
490 Func()
491 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000492 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
Bram Moolenaar56310d32022-12-27 17:25:05 +0000493
494 lines =<< trim END
495 vim9script
496
497 def Foobar(Fn: func(any, ?string): any)
498 enddef
499
500 Foobar((t) => 0)
501 END
502 v9.CheckScriptSuccess(lines)
Bram Moolenaare32e5162021-01-21 20:21:29 +0100503enddef
504
Bram Moolenaarefd88552020-06-18 20:50:10 +0200505def Test_missing_return()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000506 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200507 ' if g:cond',
508 ' echo "no return"',
509 ' else',
510 ' return 0',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100511 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200512 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000513 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200514 ' if g:cond',
515 ' return 1',
516 ' else',
517 ' echo "no return"',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100518 ' endif',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200519 'enddef'], 'E1027:')
Bram Moolenaar62aec932022-01-29 21:45:34 +0000520 v9.CheckDefFailure(['def Missing(): number',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200521 ' if g:cond',
522 ' return 1',
523 ' else',
524 ' return 2',
Bram Moolenaar2984ed32022-08-20 14:51:17 +0100525 ' endif',
526 ' return 3',
Bram Moolenaarefd88552020-06-18 20:50:10 +0200527 'enddef'], 'E1095:')
528enddef
529
Bram Moolenaarcf2610c2023-05-14 19:59:59 +0100530def Test_not_missing_return()
531 var lines =<< trim END
532 def Funky(): number
533 if false
534 return 0
535 endif
536 throw 'Error'
537 enddef
538 defcompile
539 END
540 v9.CheckScriptSuccess(lines)
541enddef
542
Bram Moolenaar403dc312020-10-17 19:29:51 +0200543def Test_return_bool()
544 var lines =<< trim END
545 vim9script
546 def MenuFilter(id: number, key: string): bool
547 return popup_filter_menu(id, key)
548 enddef
549 def YesnoFilter(id: number, key: string): bool
550 return popup_filter_yesno(id, key)
551 enddef
552 defcompile
553 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000554 v9.CheckScriptSuccess(lines)
Bram Moolenaar403dc312020-10-17 19:29:51 +0200555enddef
556
mityu500c4442022-12-02 18:12:05 +0000557def Test_return_void_comment_follows()
558 var lines =<< trim END
559 vim9script
560 def ReturnCommentFollows(): void
561 return # Some comment
562 enddef
563 defcompile
564 END
565 v9.CheckScriptSuccess(lines)
566enddef
567
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200568let s:nothing = 0
569def ReturnNothing()
570 s:nothing = 1
571 if true
572 return
573 endif
574 s:nothing = 2
575enddef
576
577def Test_return_nothing()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000578 g:ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200579 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200580enddef
581
Bram Moolenaar648ea762021-01-15 19:04:32 +0100582def Test_return_invalid()
583 var lines =<< trim END
584 vim9script
585 def Func(): invalid
586 return xxx
587 enddef
588 defcompile
589 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000590 v9.CheckScriptFailure(lines, 'E1010:', 2)
Bram Moolenaar31842cd2021-02-12 22:10:21 +0100591
592 lines =<< trim END
593 vim9script
594 def Test(Fun: func(number): number): list<number>
595 return map([1, 2, 3], (_, i) => Fun(i))
596 enddef
597 defcompile
598 def Inc(nr: number): nr
599 return nr + 2
600 enddef
601 echo Test(Inc)
602 END
603 # doing this twice was leaking memory
Bram Moolenaar62aec932022-01-29 21:45:34 +0000604 v9.CheckScriptFailure(lines, 'E1010:')
605 v9.CheckScriptFailure(lines, 'E1010:')
Bram Moolenaar648ea762021-01-15 19:04:32 +0100606enddef
607
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200608def Test_return_list_any()
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000609 # This used to fail but now the actual list type is checked, and since it has
610 # an item of type string it can be used as list<string>.
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200611 var lines =<< trim END
612 vim9script
613 def Func(): list<string>
614 var l: list<any>
615 l->add('string')
616 return l
617 enddef
618 echo Func()
619 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000620 v9.CheckScriptSuccess(lines)
Bram Moolenaar114dbda2022-01-03 12:28:03 +0000621
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200622 lines =<< trim END
623 vim9script
624 def Func(): list<string>
625 var l: list<any>
626 l += ['string']
627 return l
628 enddef
629 echo Func()
630 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000631 v9.CheckScriptSuccess(lines)
Bram Moolenaarefc084e2021-09-09 22:30:52 +0200632enddef
633
Bram Moolenaar1a572e92022-03-15 12:28:10 +0000634def Test_return_any_two_types()
635 var lines =<< trim END
636 vim9script
637
638 def G(Fn: func(string): any)
639 g:result = Fn("hello")
640 enddef
641
642 def F(a: number, b: string): any
643 echo b
644 if a > 0
645 return 1
646 else
647 return []
648 endif
649 enddef
650
651 G(function(F, [1]))
652 END
653 v9.CheckScriptSuccess(lines)
654 assert_equal(1, g:result)
655 unlet g:result
656enddef
657
Bram Moolenaar62aec932022-01-29 21:45:34 +0000658func s:Increment()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200659 let g:counter += 1
660endfunc
661
662def Test_call_ufunc_count()
663 g:counter = 1
664 Increment()
665 Increment()
666 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200667 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200668 g:counter->assert_equal(4)
669 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200670 unlet g:counter
671enddef
672
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000673def Test_call_ufunc_failure()
674 var lines =<< trim END
675 vim9script
676 def Tryit()
677 g:Global(1, 2, 3)
678 enddef
679
680 func g:Global(a, b, c)
681 echo a:a a:b a:c
682 endfunc
683
684 defcompile
685
686 func! g:Global(a, b)
Bram Moolenaar94722c52023-01-28 19:19:03 +0000687 echo a:a a:b
Bram Moolenaar1983f1a2022-02-28 20:55:02 +0000688 endfunc
689 Tryit()
690 END
691 v9.CheckScriptFailure(lines, 'E118: Too many arguments for function: Global')
692 delfunc g:Global
693
694 lines =<< trim END
695 vim9script
696
697 g:Ref = function('len')
698 def Tryit()
699 g:Ref('x')
700 enddef
701
702 defcompile
703
704 g:Ref = function('add')
705 Tryit()
706 END
707 v9.CheckScriptFailure(lines, 'E119: Not enough arguments for function: add')
708 unlet g:Ref
709enddef
710
Bram Moolenaar62aec932022-01-29 21:45:34 +0000711def s:MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200712 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200713 for s in rest
714 res ..= ',' .. s
715 endfor
716 return res
717enddef
718
719def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200720 MyVarargs('one')->assert_equal('one')
721 MyVarargs('one', 'two')->assert_equal('one,two')
722 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200723enddef
724
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200725def Test_call_white_space()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000726 v9.CheckDefAndScriptFailure(["call Test ('text')"], ['E476:', 'E1068:'])
Bram Moolenaar01dd6c32021-09-05 16:36:23 +0200727enddef
728
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200729def MyDefaultArgs(name = 'string'): string
730 return name
731enddef
732
Bram Moolenaar62aec932022-01-29 21:45:34 +0000733def s:MyDefaultSecond(name: string, second: bool = true): string
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200734 return second ? name : 'none'
735enddef
736
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200737
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200738def Test_call_default_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +0000739 g:MyDefaultArgs()->assert_equal('string')
740 g:MyDefaultArgs(v:none)->assert_equal('string')
741 g:MyDefaultArgs('one')->assert_equal('one')
742 assert_fails('g:MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200743
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200744 MyDefaultSecond('test')->assert_equal('test')
745 MyDefaultSecond('test', true)->assert_equal('test')
746 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200747
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200748 var lines =<< trim END
749 def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
750 return name .. aa .. bb
751 enddef
752
753 MyDefaultThird('->')->assert_equal('->aabb')
754 MyDefaultThird('->', v:none)->assert_equal('->aabb')
755 MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
756 MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
757 MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
758 MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
759 MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
Bram Moolenaare28d9b32021-07-03 18:56:53 +0200760
761 def DefArg(mandatory: any, optional = mandatory): string
762 return mandatory .. optional
763 enddef
764 DefArg(1234)->assert_equal('12341234')
765 DefArg("ok")->assert_equal('okok')
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200766 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000767 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200768
Bram Moolenaar62aec932022-01-29 21:45:34 +0000769 v9.CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +0100770 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000771 v9.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 +0100772 delfunc g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +0000773 v9.CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
Bram Moolenaar12bce952021-03-11 20:04:04 +0100774
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +0200775 lines =<< trim END
Bram Moolenaar12bce952021-03-11 20:04:04 +0100776 vim9script
777 def Func(a = b == 0 ? 1 : 2, b = 0)
778 enddef
779 defcompile
780 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000781 v9.CheckScriptFailure(lines, 'E1001: Variable not found: b')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000782
Bram Moolenaarfa46ead2021-12-22 13:18:39 +0000783 # using script variable requires matching type or type cast when executed
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000784 lines =<< trim END
785 vim9script
786 var a: any
787 def Func(arg: string = a)
788 echo arg
789 enddef
790 defcompile
791 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000792 v9.CheckScriptSuccess(lines + ['a = "text"', 'Func()'])
793 v9.CheckScriptFailure(lines + ['a = 123', 'Func()'], 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar59618fe2021-12-21 12:32:17 +0000794
795 # using global variable does not require type cast
796 lines =<< trim END
797 vim9script
798 def Func(arg: string = g:str)
799 echo arg
800 enddef
801 g:str = 'works'
802 Func()
803 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000804 v9.CheckScriptSuccess(lines)
Bram Moolenaar04b12692020-05-04 23:24:44 +0200805enddef
806
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100807def Test_using_vnone_default()
808 var lines =<< trim END
809 vim9script
810
811 def F(a: string = v:none)
812 if a isnot v:none
813 var b = a
814 endif
815 enddef
816 F()
817 END
818 v9.CheckScriptSuccess(lines)
819
Bram Moolenaar2ba51232023-05-15 16:22:38 +0100820 lines =<< trim END
821 vim9script
822
823 export def Floats(x: float, y = 2.0, z = 5.0)
824 g:result = printf("%.2f %.2f %.2f", x, y, z)
825 enddef
826 END
827 writefile(lines, 'Xlib.vim', 'D')
828
829 # test using a function reference in script-local variable
830 lines =<< trim END
831 vim9script
832
833 import './Xlib.vim'
834 const Floatfunc = Xlib.Floats
835 Floatfunc(1.0, v:none, 3.0)
836 END
837 v9.CheckScriptSuccess(lines)
838 assert_equal('1.00 2.00 3.00', g:result)
839 unlet g:result
840
841 # test calling the imported function
842 lines =<< trim END
843 vim9script
844
845 import './Xlib.vim'
846 Xlib.Floats(1.0, v:none, 3.0)
847 END
848 v9.CheckScriptSuccess(lines)
849 assert_equal('1.00 2.00 3.00', g:result)
850 unlet g:result
851
Bram Moolenaar2ed57ac2023-04-01 22:05:38 +0100852 # TODO: this should give an error for using a missing argument
853 # lines =<< trim END
854 # vim9script
855
856 # def F(a: string = v:none)
857 # var b = a
858 # enddef
859 # F()
860 # END
861 # v9.CheckScriptFailure(lines, 'E99:')
862enddef
863
Bram Moolenaar47bba532023-01-20 18:49:46 +0000864def Test_convert_number_to_float()
865 var lines =<< trim END
866 vim9script
867 def Foo(a: float, b: float): float
868 return a + b
869 enddef
870
871 assert_equal(5.3, Foo(3.3, 2))
872 END
873 v9.CheckScriptSuccess(lines)
874enddef
875
Bram Moolenaar62aec932022-01-29 21:45:34 +0000876def s:FuncWithComment( # comment
Bram Moolenaarcef12702021-01-04 14:09:43 +0100877 a: number, #comment
878 b: bool, # comment
879 c: string) #comment
880 assert_equal(4, a)
881 assert_equal(true, b)
882 assert_equal('yes', c)
883enddef
884
885def Test_func_with_comments()
886 FuncWithComment(4, true, 'yes')
887
888 var lines =<< trim END
889 def Func(# comment
890 arg: string)
891 enddef
892 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000893 v9.CheckScriptFailure(lines, 'E125:', 1)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100894
895 lines =<< trim END
Christian Brabandte4a450a2023-12-08 20:57:38 +0100896 def Func(f=
897 )
898 enddef
899 END
900 v9.CheckScriptFailure(lines, 'E125:', 2)
901
902 lines =<< trim END
Bram Moolenaarcef12702021-01-04 14:09:43 +0100903 def Func(
904 arg: string# comment
905 )
906 enddef
907 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000908 v9.CheckScriptFailure(lines, 'E475:', 2)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100909
910 lines =<< trim END
911 def Func(
912 arg: string
913 )# comment
914 enddef
915 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000916 v9.CheckScriptFailure(lines, 'E488:', 3)
Bram Moolenaarcef12702021-01-04 14:09:43 +0100917enddef
918
Bram Moolenaar04b12692020-05-04 23:24:44 +0200919def Test_nested_function()
Bram Moolenaar38453522021-11-28 22:00:12 +0000920 def NestedDef(arg: string): string
Bram Moolenaar04b12692020-05-04 23:24:44 +0200921 return 'nested ' .. arg
922 enddef
Bram Moolenaar38453522021-11-28 22:00:12 +0000923 NestedDef(':def')->assert_equal('nested :def')
924
925 func NestedFunc(arg)
926 return 'nested ' .. a:arg
927 endfunc
928 NestedFunc(':func')->assert_equal('nested :func')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200929
Bram Moolenaar62aec932022-01-29 21:45:34 +0000930 v9.CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
931 v9.CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200932
Bram Moolenaar62aec932022-01-29 21:45:34 +0000933 v9.CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
934 v9.CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200935
Bram Moolenaar54021752020-12-06 18:50:36 +0100936 var lines =<< trim END
937 def Outer()
938 def Inner()
939 # comment
940 enddef
941 def Inner()
942 enddef
943 enddef
944 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000945 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100946
947 lines =<< trim END
948 def Outer()
949 def Inner()
950 # comment
951 enddef
952 def! Inner()
953 enddef
954 enddef
955 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000956 v9.CheckDefFailure(lines, 'E1117:')
Bram Moolenaar54021752020-12-06 18:50:36 +0100957
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000958 lines =<< trim END
959 vim9script
960 def Outer()
961 def Inner()
962 g:result = 'ok'
963 enddef
964 Inner()
965 enddef
966 Outer()
967 Inner()
968 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000969 v9.CheckScriptFailure(lines, 'E117: Unknown function: Inner')
Bram Moolenaardb8e5c22021-12-25 19:58:22 +0000970 assert_equal('ok', g:result)
971 unlet g:result
972
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000973 lines =<< trim END
974 vim9script
975 def Outer()
976 def _Inner()
977 echo 'bad'
978 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000979 _Inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000980 enddef
981 defcompile
982 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000983 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000984
985 lines =<< trim END
986 vim9script
987 def Outer()
988 def g:inner()
989 echo 'bad'
990 enddef
Bram Moolenaar3787f262022-02-07 21:54:01 +0000991 g:inner()
Bram Moolenaarf681cfb2022-02-07 20:30:57 +0000992 enddef
993 defcompile
994 END
Bram Moolenaar3787f262022-02-07 21:54:01 +0000995 v9.CheckScriptFailure(lines, 'E1267:')
996
997 lines =<< trim END
998 vim9script
999 def g:_Func()
1000 echo 'bad'
1001 enddef
1002 END
1003 v9.CheckScriptFailure(lines, 'E1267:')
1004
1005 lines =<< trim END
1006 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001007 def _Func()
Bram Moolenaar3787f262022-02-07 21:54:01 +00001008 echo 'bad'
1009 enddef
1010 END
1011 v9.CheckScriptFailure(lines, 'E1267:')
Bram Moolenaarf681cfb2022-02-07 20:30:57 +00001012
Bram Moolenaar54021752020-12-06 18:50:36 +01001013 # nested function inside conditional
Bram Moolenaar54021752020-12-06 18:50:36 +01001014 lines =<< trim END
1015 vim9script
1016 var thecount = 0
1017 if true
1018 def Test(): number
1019 def TheFunc(): number
1020 thecount += 1
1021 return thecount
1022 enddef
1023 return TheFunc()
1024 enddef
1025 endif
1026 defcompile
1027 assert_equal(1, Test())
1028 assert_equal(2, Test())
1029 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001030 v9.CheckScriptSuccess(lines)
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001031
1032 # also works when "thecount" is inside the "if" block
1033 lines =<< trim END
1034 vim9script
1035 if true
1036 var thecount = 0
1037 def Test(): number
1038 def TheFunc(): number
1039 thecount += 1
1040 return thecount
1041 enddef
1042 return TheFunc()
1043 enddef
1044 endif
1045 defcompile
1046 assert_equal(1, Test())
1047 assert_equal(2, Test())
1048 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001049 v9.CheckScriptSuccess(lines)
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001050
Bram Moolenaara915fa02022-03-23 11:29:15 +00001051 # nested function with recursive call
1052 lines =<< trim END
1053 vim9script
1054
1055 def MyFunc(): number
1056 def Fib(n: number): number
1057 if n < 2
1058 return 1
1059 endif
1060 return Fib(n - 2) + Fib(n - 1)
1061 enddef
1062
1063 return Fib(5)
1064 enddef
1065
1066 assert_equal(8, MyFunc())
1067 END
1068 v9.CheckScriptSuccess(lines)
1069
Bram Moolenaar4bba16d2021-08-15 19:28:05 +02001070 lines =<< trim END
1071 vim9script
1072 def Outer()
1073 def Inner()
1074 echo 'hello'
1075 enddef burp
1076 enddef
1077 defcompile
1078 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001079 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001080enddef
1081
Bram Moolenaar1889f492022-08-16 19:34:44 +01001082def Test_nested_function_fails()
1083 var lines =<< trim END
1084 def T()
1085 def Func(g: string):string
1086 enddef
1087 Func()
1088 enddef
1089 silent! defcompile
1090 END
1091 v9.CheckScriptFailure(lines, 'E1069:')
1092enddef
1093
Bram Moolenaaradc8e442020-12-31 18:28:18 +01001094def Test_not_nested_function()
1095 echo printf('%d',
1096 function('len')('xxx'))
1097enddef
1098
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001099func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001100 call MyDefaultArgs()->assert_equal('string')
1101 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001102 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001103endfunc
1104
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001105def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001106 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001107 vim9script
1108 def Outer()
1109 def g:Inner(): string
1110 return 'inner'
1111 enddef
1112 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001113 defcompile
1114 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001115 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001116 delfunc g:Inner
1117 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001118 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001119 delfunc g:Inner
1120 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001121 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +02001122 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001123 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001124 v9.CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001125
1126 lines =<< trim END
1127 vim9script
1128 def Outer()
Bram Moolenaar38453522021-11-28 22:00:12 +00001129 func g:Inner()
1130 return 'inner'
1131 endfunc
1132 enddef
1133 defcompile
1134 Outer()
1135 g:Inner()->assert_equal('inner')
1136 delfunc g:Inner
1137 Outer()
1138 g:Inner()->assert_equal('inner')
1139 delfunc g:Inner
1140 Outer()
1141 g:Inner()->assert_equal('inner')
1142 delfunc g:Inner
1143 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001144 v9.CheckScriptSuccess(lines)
Bram Moolenaar38453522021-11-28 22:00:12 +00001145
1146 lines =<< trim END
1147 vim9script
1148 def Outer()
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +02001149 def g:Inner(): string
1150 return 'inner'
1151 enddef
1152 enddef
1153 defcompile
1154 Outer()
1155 Outer()
1156 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001157 v9.CheckScriptFailure(lines, "E122:")
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01001158 delfunc g:Inner
Bram Moolenaarad486a02020-08-01 23:22:18 +02001159
1160 lines =<< trim END
1161 vim9script
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001162 def Outer()
1163 def g:Inner()
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001164 echo map([1, 2, 3], (_, v) => v + 1)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001165 enddef
1166 g:Inner()
1167 enddef
1168 Outer()
1169 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001170 v9.CheckScriptSuccess(lines)
Bram Moolenaar58a52f22020-12-22 18:56:55 +01001171 delfunc g:Inner
1172
1173 lines =<< trim END
1174 vim9script
Bram Moolenaarad486a02020-08-01 23:22:18 +02001175 def Func()
1176 echo 'script'
1177 enddef
1178 def Outer()
1179 def Func()
1180 echo 'inner'
1181 enddef
1182 enddef
1183 defcompile
1184 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001185 v9.CheckScriptFailure(lines, "E1073:", 1)
Bram Moolenaard604d782021-11-20 21:46:20 +00001186
1187 lines =<< trim END
1188 vim9script
1189 def Func()
1190 echo 'script'
1191 enddef
1192 def Func()
1193 echo 'script'
1194 enddef
1195 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001196 v9.CheckScriptFailure(lines, "E1073:", 5)
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001197enddef
1198
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001199def DefListAll()
1200 def
1201enddef
1202
1203def DefListOne()
1204 def DefListOne
1205enddef
1206
1207def DefListMatches()
1208 def /DefList
1209enddef
1210
1211def Test_nested_def_list()
1212 var funcs = split(execute('call DefListAll()'), "\n")
1213 assert_true(len(funcs) > 10)
1214 assert_true(funcs->index('def DefListAll()') >= 0)
1215
1216 funcs = split(execute('call DefListOne()'), "\n")
1217 assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs)
1218
1219 funcs = split(execute('call DefListMatches()'), "\n")
1220 assert_true(len(funcs) >= 3)
1221 assert_true(funcs->index('def DefListAll()') >= 0)
1222 assert_true(funcs->index('def DefListOne()') >= 0)
1223 assert_true(funcs->index('def DefListMatches()') >= 0)
Bram Moolenaar54021752020-12-06 18:50:36 +01001224
1225 var lines =<< trim END
1226 vim9script
1227 def Func()
1228 def +Func+
1229 enddef
1230 defcompile
1231 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001232 v9.CheckScriptFailure(lines, 'E476:', 1)
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001233enddef
1234
Bram Moolenaare08be092022-02-17 13:08:26 +00001235def Test_global_function_not_found()
1236 var lines =<< trim END
1237 g:Ref = 123
1238 call g:Ref()
1239 END
1240 v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
1241enddef
1242
Bram Moolenaar333894b2020-08-01 18:53:07 +02001243def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001244 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +02001245 vim9script
1246 def g:Func(): string
1247 return 'global'
1248 enddef
1249 def Func(): string
1250 return 'local'
1251 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001252 g:Func()->assert_equal('global')
1253 Func()->assert_equal('local')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01001254 delfunc g:Func
Bram Moolenaar333894b2020-08-01 18:53:07 +02001255 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001256 v9.CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001257
1258 lines =<< trim END
1259 vim9script
1260 def g:Funcy()
1261 echo 'funcy'
1262 enddef
Bram Moolenaara749a422022-02-12 19:52:25 +00001263 Funcy()
Bram Moolenaar035d6e92020-08-11 22:30:42 +02001264 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001265 v9.CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +02001266enddef
1267
Bram Moolenaar0f769812020-09-12 18:32:34 +02001268def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001269 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +02001270 vim9script
1271 def g:Gfunc(): string
1272 return 'global'
1273 enddef
1274 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001275 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001276 return Gfunc('testing')
1277 enddef
1278 g:Gfunc()->assert_equal('global')
1279 AnotherFunc()->assert_equal(7)
1280 delfunc g:Gfunc
1281 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001282 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001283
1284 lines =<< trim END
1285 vim9script
1286 def g:Func(): string
1287 return 'global'
1288 enddef
1289 def AnotherFunc()
1290 g:Func = function('len')
1291 enddef
1292 AnotherFunc()
1293 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001294 v9.CheckScriptFailure(lines, 'E705:')
Bram Moolenaar0f769812020-09-12 18:32:34 +02001295 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001296
Bram Moolenaar62aec932022-01-29 21:45:34 +00001297 # global function is not found with g: prefix
Bram Moolenaar0865b152021-04-05 15:38:51 +02001298 lines =<< trim END
1299 vim9script
1300 def g:Func(): string
1301 return 'global'
1302 enddef
1303 def AnotherFunc(): string
1304 return Func()
1305 enddef
1306 assert_equal('global', AnotherFunc())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001307 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001308 v9.CheckScriptFailure(lines, 'E117:')
1309 delfunc g:Func
Bram Moolenaar0865b152021-04-05 15:38:51 +02001310
1311 lines =<< trim END
1312 vim9script
1313 def g:Func(): string
1314 return 'global'
1315 enddef
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001316 assert_equal('global', g:Func())
Bram Moolenaar0865b152021-04-05 15:38:51 +02001317 delfunc g:Func
1318 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001319 v9.CheckScriptSuccess(lines)
Bram Moolenaar58493cf2022-01-06 12:23:30 +00001320
1321 # This does not shadow "i" which is visible only inside the for loop
1322 lines =<< trim END
1323 vim9script
1324
1325 def Foo(i: number)
1326 echo i
1327 enddef
1328
1329 for i in range(3)
1330 # Foo() is compiled here
1331 Foo(i)
1332 endfor
1333 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001334 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f769812020-09-12 18:32:34 +02001335enddef
1336
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001337func TakesOneArg(arg)
1338 echo a:arg
1339endfunc
1340
1341def Test_call_wrong_args()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001342 v9.CheckDefFailure(['g:TakesOneArg()'], 'E119:')
1343 v9.CheckDefFailure(['g:TakesOneArg(11, 22)'], 'E118:')
1344 v9.CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1345 v9.CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001346
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001347 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +02001348 vim9script
1349 def Func(s: string)
1350 echo s
1351 enddef
1352 Func([])
1353 END
Yegappan Lakshmanan66897192023-12-05 15:51:50 +01001354 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<any>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +02001355
Bram Moolenaar9a015112021-12-31 14:06:45 +00001356 # argument name declared earlier is found when declaring a function
Bram Moolenaarb185a402020-09-18 22:42:00 +02001357 lines =<< trim END
1358 vim9script
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001359 var name = 'piet'
1360 def FuncOne(name: string)
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001361 echo name
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001362 enddef
1363 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001364 v9.CheckScriptFailure(lines, 'E1168:')
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001365
Bram Moolenaar3a5988c2022-02-08 19:23:35 +00001366 # same, inside the same block
1367 lines =<< trim END
1368 vim9script
1369 if true
1370 var name = 'piet'
1371 def FuncOne(name: string)
1372 echo name
1373 enddef
1374 endif
1375 END
1376 v9.CheckScriptFailure(lines, 'E1168:')
1377
1378 # variable in other block is OK
1379 lines =<< trim END
1380 vim9script
1381 if true
1382 var name = 'piet'
1383 endif
1384 def FuncOne(name: string)
1385 echo name
1386 enddef
1387 END
1388 v9.CheckScriptSuccess(lines)
1389
Bram Moolenaardce24412022-02-08 20:35:30 +00001390 # with another variable in another block
1391 lines =<< trim END
1392 vim9script
1393 if true
1394 var name = 'piet'
1395 # define a function so that the variable isn't cleared
1396 def GetItem(): string
1397 return item
1398 enddef
1399 endif
1400 if true
1401 var name = 'peter'
1402 def FuncOne(name: string)
1403 echo name
1404 enddef
1405 endif
1406 END
1407 v9.CheckScriptFailure(lines, 'E1168:')
1408
1409 # only variable in another block is OK
1410 lines =<< trim END
1411 vim9script
1412 if true
1413 var name = 'piet'
1414 # define a function so that the variable isn't cleared
1415 def GetItem(): string
1416 return item
1417 enddef
1418 endif
1419 if true
1420 def FuncOne(name: string)
1421 echo name
1422 enddef
1423 endif
1424 END
1425 v9.CheckScriptSuccess(lines)
1426
Bram Moolenaar9a015112021-12-31 14:06:45 +00001427 # argument name declared later is only found when compiling
1428 lines =<< trim END
1429 vim9script
1430 def FuncOne(name: string)
1431 echo nr
1432 enddef
1433 var name = 'piet'
1434 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001435 v9.CheckScriptSuccess(lines)
1436 v9.CheckScriptFailure(lines + ['defcompile'], 'E1168:')
Bram Moolenaar9a015112021-12-31 14:06:45 +00001437
Bram Moolenaarb4893b82021-02-21 22:20:24 +01001438 lines =<< trim END
1439 vim9script
Bram Moolenaarb185a402020-09-18 22:42:00 +02001440 def FuncOne(nr: number)
1441 echo nr
1442 enddef
1443 def FuncTwo()
1444 FuncOne()
1445 enddef
1446 defcompile
1447 END
1448 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001449 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +02001450 try
1451 source Xscript
1452 catch
1453 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
1454 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1455 didCatch = true
1456 endtry
1457 assert_true(didCatch)
1458
1459 lines =<< trim END
1460 vim9script
1461 def FuncOne(nr: number)
1462 echo nr
1463 enddef
1464 def FuncTwo()
1465 FuncOne(1, 2)
1466 enddef
1467 defcompile
1468 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01001469 writefile(lines, 'Xscript', 'D')
Bram Moolenaarb185a402020-09-18 22:42:00 +02001470 didCatch = false
1471 try
1472 source Xscript
1473 catch
1474 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
1475 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
1476 didCatch = true
1477 endtry
1478 assert_true(didCatch)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001479enddef
1480
Bram Moolenaar50824712020-12-20 21:10:17 +01001481def Test_call_funcref_wrong_args()
1482 var head =<< trim END
1483 vim9script
1484 def Func3(a1: string, a2: number, a3: list<number>)
1485 echo a1 .. a2 .. a3[0]
1486 enddef
1487 def Testme()
1488 var funcMap: dict<func> = {func: Func3}
1489 END
1490 var tail =<< trim END
1491 enddef
1492 Testme()
1493 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001494 v9.CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
Bram Moolenaar50824712020-12-20 21:10:17 +01001495
Bram Moolenaar62aec932022-01-29 21:45:34 +00001496 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
1497 v9.CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001498
1499 var lines =<< trim END
1500 vim9script
1501 var Ref: func(number): any
1502 Ref = (j) => !j
1503 echo Ref(false)
1504 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001505 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar32b3f822021-01-06 21:59:39 +01001506
1507 lines =<< trim END
1508 vim9script
1509 var Ref: func(number): any
1510 Ref = (j) => !j
1511 call Ref(false)
1512 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001513 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
Bram Moolenaar50824712020-12-20 21:10:17 +01001514enddef
1515
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001516def Test_call_lambda_args()
Bram Moolenaar2a389082021-04-09 20:24:31 +02001517 var lines =<< trim END
1518 var Callback = (..._) => 'anything'
1519 assert_equal('anything', Callback())
1520 assert_equal('anything', Callback(1))
1521 assert_equal('anything', Callback('a', 2))
Bram Moolenaar1088b692021-04-09 22:12:44 +02001522
1523 assert_equal('xyz', ((a: string): string => a)('xyz'))
Bram Moolenaar2a389082021-04-09 20:24:31 +02001524 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001525 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001526
Bram Moolenaar62aec932022-01-29 21:45:34 +00001527 v9.CheckDefFailure(['echo ((i) => 0)()'],
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001528 'E119: Not enough arguments for function: ((i) => 0)()')
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001529
Bram Moolenaar2a389082021-04-09 20:24:31 +02001530 lines =<< trim END
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001531 var Ref = (x: number, y: number) => x + y
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001532 echo Ref(1, 'x')
1533 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001534 v9.CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001535
1536 lines =<< trim END
1537 var Ref: func(job, string, number)
1538 Ref = (x, y) => 0
1539 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001540 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaare68b02a2021-01-03 13:09:51 +01001541
1542 lines =<< trim END
1543 var Ref: func(job, string)
1544 Ref = (x, y, z) => 0
1545 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001546 v9.CheckDefAndScriptFailure(lines, 'E1012:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001547
1548 lines =<< trim END
1549 var one = 1
1550 var l = [1, 2, 3]
1551 echo map(l, (one) => one)
1552 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001553 v9.CheckDefFailure(lines, 'E1167:')
1554 v9.CheckScriptFailure(['vim9script'] + lines, 'E1168:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001555
1556 lines =<< trim END
Bram Moolenaar14ded112021-06-26 19:25:49 +02001557 var Ref: func(any, ?any): bool
1558 Ref = (_, y = 1) => false
1559 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001560 v9.CheckDefAndScriptFailure(lines, 'E1172:')
Bram Moolenaar14ded112021-06-26 19:25:49 +02001561
1562 lines =<< trim END
Bram Moolenaar015cf102021-06-26 21:52:02 +02001563 var a = 0
1564 var b = (a == 0 ? 1 : 2)
1565 assert_equal(1, b)
Bram Moolenaar98f9a5f2021-06-26 22:22:38 +02001566 var txt = 'a'
1567 b = (txt =~ 'x' ? 1 : 2)
1568 assert_equal(2, b)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001569 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001570 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaar015cf102021-06-26 21:52:02 +02001571
1572 lines =<< trim END
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001573 def ShadowLocal()
1574 var one = 1
1575 var l = [1, 2, 3]
1576 echo map(l, (one) => one)
1577 enddef
1578 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001579 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar057e84a2021-02-28 16:55:11 +01001580
1581 lines =<< trim END
1582 def Shadowarg(one: number)
1583 var l = [1, 2, 3]
1584 echo map(l, (one) => one)
1585 enddef
1586 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001587 v9.CheckDefFailure(lines, 'E1167:')
Bram Moolenaar767034c2021-04-09 17:24:52 +02001588
1589 lines =<< trim END
1590 echo ((a) => a)('aa', 'bb')
1591 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001592 v9.CheckDefAndScriptFailure(lines, 'E118:', 1)
Bram Moolenaarc4c56422021-07-21 20:38:46 +02001593
1594 lines =<< trim END
1595 echo 'aa'->((a) => a)('bb')
1596 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001597 v9.CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1598 v9.CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001599enddef
1600
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001601def Test_lambda_line_nr()
1602 var lines =<< trim END
1603 vim9script
1604 # comment
1605 # comment
1606 var id = timer_start(1'000, (_) => 0)
1607 var out = execute('verbose ' .. timer_info(id)[0].callback
1608 ->string()
1609 ->substitute("('\\|')", ' ', 'g'))
1610 assert_match('Last set from .* line 4', out)
1611 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001612 v9.CheckScriptSuccess(lines)
Bram Moolenaara755fdb2021-11-20 21:35:41 +00001613enddef
1614
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001615def FilterWithCond(x: string, Cond: func(string): bool): bool
1616 return Cond(x)
1617enddef
1618
Bram Moolenaar0346b792021-01-31 22:18:29 +01001619def Test_lambda_return_type()
1620 var lines =<< trim END
1621 var Ref = (): => 123
1622 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001623 v9.CheckDefAndScriptFailure(lines, 'E1157:', 1)
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001624
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001625 # no space before the return type
1626 lines =<< trim END
1627 var Ref = (x):number => x + 1
1628 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001629 v9.CheckDefAndScriptFailure(lines, 'E1069:', 1)
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02001630
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001631 # this works
1632 for x in ['foo', 'boo']
Bram Moolenaar62aec932022-01-29 21:45:34 +00001633 echo g:FilterWithCond(x, (v) => v =~ '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001634 endfor
1635
1636 # this fails
1637 lines =<< trim END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001638 echo g:FilterWithCond('foo', (v) => v .. '^b')
Bram Moolenaar5f91e742021-03-17 21:29:29 +01001639 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001640 v9.CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
Bram Moolenaara9931532021-06-12 15:58:16 +02001641
1642 lines =<< trim END
1643 var Lambda1 = (x) => {
1644 return x
1645 }
1646 assert_equal('asdf', Lambda1('asdf'))
1647 var Lambda2 = (x): string => {
1648 return x
1649 }
1650 assert_equal('foo', Lambda2('foo'))
1651 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001652 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara9931532021-06-12 15:58:16 +02001653
1654 lines =<< trim END
1655 var Lambda = (x): string => {
1656 return x
1657 }
1658 echo Lambda(['foo'])
1659 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001660 v9.CheckDefExecAndScriptFailure(lines, 'E1012:')
Bram Moolenaar0346b792021-01-31 22:18:29 +01001661enddef
1662
Bram Moolenaar709664c2020-12-12 14:33:41 +01001663def Test_lambda_uses_assigned_var()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001664 v9.CheckDefSuccess([
Bram Moolenaar2984ed32022-08-20 14:51:17 +01001665 'var x: any = "aaa"',
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001666 'x = filter(["bbb"], (_, v) => v =~ x)'])
Bram Moolenaar709664c2020-12-12 14:33:41 +01001667enddef
1668
Bram Moolenaarf5f4e852022-09-22 22:03:14 +01001669def Test_lambda_invalid_block()
1670 var lines =<< trim END
1671 timer_start(0, (_) => { # echo
1672 echo 'yes'
1673 })
1674 END
1675 v9.CheckDefAndScriptSuccess(lines)
1676
1677 lines =<< trim END
1678 timer_start(0, (_) => { " echo
1679 echo 'yes'
1680 })
1681 END
1682 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: " echo')
1683
1684 lines =<< trim END
1685 timer_start(0, (_) => { | echo
1686 echo 'yes'
1687 })
1688 END
1689 v9.CheckDefAndScriptFailure(lines, 'E488: Trailing characters: | echo')
1690enddef
1691
Bram Moolenaarf8addf12022-09-23 12:44:25 +01001692def Test_lambda_with_following_cmd()
1693 var lines =<< trim END
1694 set ts=2
1695 var Lambda = () => {
1696 set ts=4
1697 } | set ts=3
1698 assert_equal(3, &ts)
1699 Lambda()
1700 assert_equal(4, &ts)
1701 END
1702 v9.CheckDefAndScriptSuccess(lines)
1703 set ts=8
1704enddef
1705
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001706def Test_pass_legacy_lambda_to_def_func()
1707 var lines =<< trim END
1708 vim9script
1709 func Foo()
1710 eval s:Bar({x -> 0})
1711 endfunc
1712 def Bar(y: any)
1713 enddef
1714 Foo()
1715 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001716 v9.CheckScriptSuccess(lines)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001717
1718 lines =<< trim END
1719 vim9script
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001720 def g:TestFunc(F: func)
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001721 enddef
1722 legacy call g:TestFunc({-> 0})
1723 delfunc g:TestFunc
1724
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00001725 def g:TestFunc(F: func(number))
Bram Moolenaar831bdf82021-06-22 19:32:17 +02001726 enddef
1727 legacy call g:TestFunc({nr -> 0})
1728 delfunc g:TestFunc
1729 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001730 v9.CheckScriptSuccess(lines)
Bram Moolenaar18062fc2021-03-05 21:35:47 +01001731enddef
1732
Bram Moolenaar844fb642021-10-23 13:32:30 +01001733def Test_lambda_in_reduce_line_break()
1734 # this was using freed memory
1735 var lines =<< trim END
1736 vim9script
1737 const result: dict<number> =
1738 ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1739 ->reduce((acc, val) => {
1740 if has_key(acc, val)
1741 acc[val] += 1
1742 return acc
1743 else
1744 acc[val] = 1
1745 return acc
1746 endif
1747 }, {})
1748 assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1749 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001750 v9.CheckScriptSuccess(lines)
Bram Moolenaar844fb642021-10-23 13:32:30 +01001751enddef
1752
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001753def Test_set_opfunc_to_lambda()
1754 var lines =<< trim END
1755 vim9script
1756 nnoremap <expr> <F4> <SID>CountSpaces() .. '_'
1757 def CountSpaces(type = ''): string
1758 if type == ''
1759 &operatorfunc = (t) => CountSpaces(t)
1760 return 'g@'
1761 endif
1762 normal! '[V']y
1763 g:result = getreg('"')->count(' ')
1764 return ''
1765 enddef
1766 new
1767 'a b c d e'->setline(1)
1768 feedkeys("\<F4>", 'x')
1769 assert_equal(4, g:result)
1770 bwipe!
1771 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001772 v9.CheckScriptSuccess(lines)
Bram Moolenaardcb53be2021-12-09 14:23:43 +00001773enddef
1774
Bram Moolenaaref082e12021-12-12 21:02:03 +00001775def Test_set_opfunc_to_global_function()
1776 var lines =<< trim END
1777 vim9script
1778 def g:CountSpaces(type = ''): string
1779 normal! '[V']y
1780 g:result = getreg('"')->count(' ')
1781 return ''
1782 enddef
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001783 # global function works at script level
Bram Moolenaaref082e12021-12-12 21:02:03 +00001784 &operatorfunc = g:CountSpaces
1785 new
1786 'a b c d e'->setline(1)
1787 feedkeys("g@_", 'x')
1788 assert_equal(4, g:result)
Bram Moolenaarb15cf442021-12-16 15:49:43 +00001789
1790 &operatorfunc = ''
1791 g:result = 0
1792 # global function works in :def function
1793 def Func()
1794 &operatorfunc = g:CountSpaces
1795 enddef
1796 Func()
1797 feedkeys("g@_", 'x')
1798 assert_equal(4, g:result)
1799
Bram Moolenaaref082e12021-12-12 21:02:03 +00001800 bwipe!
1801 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001802 v9.CheckScriptSuccess(lines)
Bram Moolenaaref082e12021-12-12 21:02:03 +00001803 &operatorfunc = ''
1804enddef
1805
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001806def Test_use_script_func_name_with_prefix()
1807 var lines =<< trim END
1808 vim9script
Bram Moolenaara749a422022-02-12 19:52:25 +00001809 func g:Getit()
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001810 return 'it'
1811 endfunc
Bram Moolenaara749a422022-02-12 19:52:25 +00001812 var Fn = g:Getit
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001813 assert_equal('it', Fn())
1814 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001815 v9.CheckScriptSuccess(lines)
Bram Moolenaar33b968d2021-12-13 11:31:04 +00001816enddef
1817
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001818def Test_lambda_type_allocated()
1819 # Check that unreferencing a partial using a lambda can use the variable type
1820 # after the lambda has been freed and does not leak memory.
1821 var lines =<< trim END
1822 vim9script
1823
1824 func MyomniFunc1(val, findstart, base)
1825 return a:findstart ? 0 : []
1826 endfunc
1827
1828 var Lambda = (a, b) => MyomniFunc1(19, a, b)
1829 &omnifunc = Lambda
1830 Lambda = (a, b) => MyomniFunc1(20, a, b)
1831 &omnifunc = string(Lambda)
1832 Lambda = (a, b) => strlen(a)
1833 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001834 v9.CheckScriptSuccess(lines)
Bram Moolenaardd297bc2021-12-10 10:37:38 +00001835enddef
1836
Bram Moolenaara7583c42022-05-07 21:14:05 +01001837def Test_define_lambda_in_execute()
1838 var lines =<< trim [CODE]
1839 vim9script
1840
1841 def BuildFuncMultiLine(): func
1842 var x =<< trim END
1843 g:SomeRandomFunc = (d: dict<any>) => {
1844 return d.k1 + d.k2
1845 }
1846 END
1847 execute(x)
1848 return g:SomeRandomFunc
1849 enddef
1850 var ResultPlus = BuildFuncMultiLine()
1851 assert_equal(7, ResultPlus({k1: 3, k2: 4}))
1852 [CODE]
1853 v9.CheckScriptSuccess(lines)
1854 unlet g:SomeRandomFunc
1855enddef
1856
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001857" Default arg and varargs
1858def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001859 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001860 for s in rest
1861 res ..= ',' .. s
1862 endfor
1863 return res
1864enddef
1865
1866def Test_call_def_varargs()
Bram Moolenaar62aec932022-01-29 21:45:34 +00001867 assert_fails('g:MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1868 g:MyDefVarargs('one')->assert_equal('one,foo')
1869 g:MyDefVarargs('one', 'two')->assert_equal('one,two')
1870 g:MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
1871 v9.CheckDefFailure(['g:MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001872 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00001873 v9.CheckDefFailure(['g:MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +02001874 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001875
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001876 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001877 vim9script
1878 def Func(...l: list<string>)
1879 echo l
1880 enddef
1881 Func('a', 'b', 'c')
1882 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001883 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001884
1885 lines =<< trim END
1886 vim9script
1887 def Func(...l: list<string>)
1888 echo l
1889 enddef
1890 Func()
1891 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001892 v9.CheckScriptSuccess(lines)
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001893
1894 lines =<< trim END
1895 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001896 def Func(...l: list<any>)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001897 echo l
1898 enddef
1899 Func(0)
1900 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001901 v9.CheckScriptSuccess(lines)
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +02001902
1903 lines =<< trim END
1904 vim9script
Bram Moolenaar2a389082021-04-09 20:24:31 +02001905 def Func(...l: any)
1906 echo l
1907 enddef
1908 Func(0)
1909 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001910 v9.CheckScriptFailure(lines, 'E1180:', 2)
Bram Moolenaar2a389082021-04-09 20:24:31 +02001911
1912 lines =<< trim END
1913 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +02001914 def Func(..._l: list<string>)
1915 echo _l
1916 enddef
1917 Func('a', 'b', 'c')
1918 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001919 v9.CheckScriptSuccess(lines)
Bram Moolenaar28022722020-09-21 22:02:49 +02001920
1921 lines =<< trim END
1922 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001923 def Func(...l: list<string>)
1924 echo l
1925 enddef
1926 Func(1, 2, 3)
1927 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001928 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001929
1930 lines =<< trim END
1931 vim9script
1932 def Func(...l: list<string>)
1933 echo l
1934 enddef
1935 Func('a', 9)
1936 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001937 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +02001938
1939 lines =<< trim END
1940 vim9script
1941 def Func(...l: list<string>)
1942 echo l
1943 enddef
1944 Func(1, 'a')
1945 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001946 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar4f53b792021-02-07 15:59:49 +01001947
1948 lines =<< trim END
1949 vim9script
1950 def Func( # some comment
1951 ...l = []
1952 )
1953 echo l
1954 enddef
1955 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001956 v9.CheckScriptFailure(lines, 'E1160:')
Bram Moolenaar6ce46b92021-08-07 15:35:36 +02001957
1958 lines =<< trim END
1959 vim9script
1960 def DoIt()
1961 g:Later('')
1962 enddef
1963 defcompile
1964 def g:Later(...l: list<number>)
1965 enddef
1966 DoIt()
1967 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00001968 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001969enddef
1970
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001971let s:value = ''
1972
1973def FuncOneDefArg(opt = 'text')
1974 s:value = opt
1975enddef
1976
1977def FuncTwoDefArg(nr = 123, opt = 'text'): string
1978 return nr .. opt
1979enddef
1980
1981def FuncVarargs(...arg: list<string>): string
1982 return join(arg, ',')
1983enddef
1984
1985def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001986 var RefDefArg: func(?string)
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001987 RefDefArg = g:FuncOneDefArg
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001988 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001989 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001990 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001991 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001992
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001993 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001994 RefDef2Arg = g:FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001995 RefDef2Arg()->assert_equal('123text')
1996 RefDef2Arg(99)->assert_equal('99text')
1997 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02001998
Bram Moolenaar62aec932022-01-29 21:45:34 +00001999 v9.CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
2000 v9.CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002001
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002002 var RefVarargs: func(...list<string>): string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002003 RefVarargs = g:FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002004 RefVarargs()->assert_equal('')
2005 RefVarargs('one')->assert_equal('one')
2006 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002007
Bram Moolenaar62aec932022-01-29 21:45:34 +00002008 v9.CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
2009 v9.CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +02002010enddef
2011
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002012" Only varargs
2013def MyVarargsOnly(...args: list<string>): string
2014 return join(args, ',')
2015enddef
2016
2017def Test_call_varargs_only()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002018 g:MyVarargsOnly()->assert_equal('')
2019 g:MyVarargsOnly('one')->assert_equal('one')
2020 g:MyVarargsOnly('one', 'two')->assert_equal('one,two')
2021 v9.CheckDefFailure(['g:MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
2022 v9.CheckDefFailure(['g:MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +02002023enddef
2024
Bram Moolenaar36818a92023-01-03 12:33:26 +00002025def Test_varargs_mismatch()
2026 var lines =<< trim END
2027 vim9script
2028
2029 def Map(Fn: func(...any): number): number
2030 return Fn('12')
2031 enddef
2032
2033 var res = Map((v) => str2nr(v))
2034 assert_equal(12, res)
2035 END
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002036 v9.CheckScriptFailure(lines, 'E1180: Variable arguments type must be a list: any')
Bram Moolenaar36818a92023-01-03 12:33:26 +00002037enddef
2038
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002039def Test_using_var_as_arg()
Bram Moolenaard2939812021-12-30 17:09:05 +00002040 var lines =<< trim END
2041 def Func(x: number)
2042 var x = 234
2043 enddef
2044 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002045 v9.CheckDefFailure(lines, 'E1006:')
Bram Moolenaard2939812021-12-30 17:09:05 +00002046
2047 lines =<< trim END
2048 def Func(Ref: number)
2049 def Ref()
2050 enddef
2051 enddef
2052 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002053 v9.CheckDefFailure(lines, 'E1073:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002054enddef
2055
Bram Moolenaar62aec932022-01-29 21:45:34 +00002056def s:DictArg(arg: dict<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002057 arg['key'] = 'value'
2058enddef
2059
Bram Moolenaar62aec932022-01-29 21:45:34 +00002060def s:ListArg(arg: list<string>)
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002061 arg[0] = 'value'
2062enddef
2063
2064def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002065 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002066 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002067 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002068 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002069 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002070 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002071 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002072
Bram Moolenaar62aec932022-01-29 21:45:34 +00002073 v9.CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002074 delfunc! g:Func
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +02002075enddef
2076
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002077" These argument names are reserved in legacy functions.
Bram Moolenaar62aec932022-01-29 21:45:34 +00002078def s:WithReservedNames(firstline: string, lastline: string): string
Bram Moolenaarb816dae2020-09-20 22:04:00 +02002079 return firstline .. lastline
2080enddef
2081
2082def Test_argument_names()
2083 assert_equal('OK', WithReservedNames('O', 'K'))
2084enddef
2085
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002086def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002087 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002088 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002089enddef
2090
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002091func DefinedLater(arg)
2092 return a:arg
2093endfunc
2094
2095def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002096 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002097 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
Bram Moolenaar2ef91562021-12-11 16:14:07 +00002098 assert_fails('g:NotAFunc()', 'E1085:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002099
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002100 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002101 vim9script
2102 def RetNumber(): number
2103 return 123
2104 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002105 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002106 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +02002107 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002108 v9.CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002109
2110 lines =<< trim END
2111 vim9script
2112 def RetNumber(): number
2113 return 123
2114 enddef
2115 def Bar(F: func: number): number
2116 return F()
2117 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002118 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002119 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +02002120 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002121 v9.CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002122
2123 lines =<< trim END
2124 vim9script
2125 def UseNumber(nr: number)
2126 echo nr
2127 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002128 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +02002129 Funcref(123)
2130 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002131 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002132
2133 lines =<< trim END
2134 vim9script
2135 def UseNumber(nr: number)
2136 echo nr
2137 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002138 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +02002139 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002140 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002141
2142 lines =<< trim END
2143 vim9script
2144 def EchoNr(nr = 34)
2145 g:echo = nr
2146 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002147 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002148 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002149 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002150 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002151 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +02002152 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002153 v9.CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +02002154
2155 lines =<< trim END
2156 vim9script
2157 def EchoList(...l: list<number>)
2158 g:echo = l
2159 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002160 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +02002161 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002162 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +02002163 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002164 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +02002165 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002166 v9.CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002167
2168 lines =<< trim END
2169 vim9script
2170 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
2171 g:optarg = opt
2172 g:listarg = l
2173 return nr
2174 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002175 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002176 Funcref(10)->assert_equal(10)
2177 g:optarg->assert_equal(12)
2178 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002179
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002180 Funcref(11, 22)->assert_equal(11)
2181 g:optarg->assert_equal(22)
2182 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002183
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002184 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
2185 g:optarg->assert_equal(18)
2186 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +02002187 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002188 v9.CheckScriptSuccess(lines)
Kota Kato948a3892022-08-16 16:09:59 +01002189
2190 lines =<< trim END
2191 function s:func(num)
2192 return a:num * 2
2193 endfunction
2194
2195 def s:CallFuncref()
2196 var Funcref = function('s:func')
2197 Funcref(3)->assert_equal(6)
2198 enddef
2199 call s:CallFuncref()
2200 END
2201 v9.CheckScriptSuccess(lines)
2202
2203 lines =<< trim END
2204 function s:func(num)
2205 return a:num * 2
2206 endfunction
2207
2208 def s:CallFuncref()
2209 var Funcref = function(s:func)
2210 Funcref(3)->assert_equal(6)
2211 enddef
2212 call s:CallFuncref()
2213 END
2214 v9.CheckScriptSuccess(lines)
2215
2216 lines =<< trim END
2217 function s:func(num)
2218 return a:num * 2
2219 endfunction
2220
2221 def s:CallFuncref()
2222 var Funcref = s:func
2223 Funcref(3)->assert_equal(6)
2224 enddef
2225 call s:CallFuncref()
2226 END
2227 v9.CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002228enddef
2229
2230let SomeFunc = function('len')
2231let NotAFunc = 'text'
2232
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002233def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002234 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002235 var Ref1: func(bool): string
2236 var Ref2: func(bool): number
2237 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002238 Ref3 = g:cond ? Ref1 : Ref2
2239
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002240 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002241 var Refa1: func(bool): number
2242 var Refa2: func(bool, number): number
2243 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002244 Refa3 = g:cond ? Refa1 : Refa2
2245
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002246 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002247 var Refb1: func(bool, string): number
2248 var Refb2: func(string, number): number
2249 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +02002250 Refb3 = g:cond ? Refb1 : Refb2
2251enddef
2252
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002253def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +02002254 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002255enddef
2256
2257def DefinedEvenLater(arg: string): string
2258 return arg
2259enddef
2260
2261def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002262 # Error in called function requires unwinding the call stack.
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002263 assert_fails('g:FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002264enddef
2265
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002266def Test_nested_function_with_nextcmd()
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002267 var lines =<< trim END
2268 vim9script
2269 # Define an outer function
2270 def FirstFunction()
2271 # Define an inner function
2272 def SecondFunction()
2273 # the function has a body, a double free is detected.
2274 AAAAA
2275
2276 # enddef followed by | or } followed by # one or more characters
2277 enddef|BBBB
2278 enddef
2279
2280 # Compile all functions
2281 defcompile
2282 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002283 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar9c23f9b2021-12-26 14:23:22 +00002284enddef
2285
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002286def Test_nested_function_with_args_split()
2287 var lines =<< trim END
2288 vim9script
2289 def FirstFunction()
2290 def SecondFunction(
2291 )
2292 # had a double free if the right parenthesis of the nested function is
2293 # on the next line
Bram Moolenaar94722c52023-01-28 19:19:03 +00002294
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002295 enddef|BBBB
2296 enddef
2297 # Compile all functions
2298 defcompile
2299 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002300 v9.CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
Bram Moolenaar7473a842021-12-28 17:55:26 +00002301
2302 lines =<< trim END
2303 vim9script
2304 def FirstFunction()
2305 func SecondFunction()
2306 endfunc|BBBB
2307 enddef
2308 defcompile
2309 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002310 v9.CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
Bram Moolenaar4bf10062021-12-28 17:23:12 +00002311enddef
2312
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002313def Test_error_in_function_args()
2314 var lines =<< trim END
2315 def FirstFunction()
2316 def SecondFunction(J =
2317 # Nois
2318 # one
Bram Moolenaar94722c52023-01-28 19:19:03 +00002319
2320 enddef|BBBB
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002321 enddef
2322 # Compile all functions
2323 defcompile
2324 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002325 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar9f1a39a2022-01-08 15:39:39 +00002326enddef
2327
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002328def Test_return_type_wrong()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002329 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002330 'def Func(): number',
2331 'return "a"',
2332 'enddef',
2333 'defcompile'], 'expected number but got string')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002334 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002335 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002336 'def Func(): string',
2337 'return 1',
2338 'enddef',
2339 'defcompile'], 'expected string but got number')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002340 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002341 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002342 'def Func(): void',
2343 'return "a"',
2344 'enddef',
2345 'defcompile'],
2346 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002347 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002348 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002349 'def Func()',
2350 'return "a"',
2351 'enddef',
2352 'defcompile'],
2353 'E1096: Returning a value in a function without a return type')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002354 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002355
Bram Moolenaar62aec932022-01-29 21:45:34 +00002356 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002357 'def Func(): number',
2358 'return',
2359 'enddef',
2360 'defcompile'], 'E1003:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002361 delfunc! g:Func
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002362
Bram Moolenaar62aec932022-01-29 21:45:34 +00002363 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002364 'def Func():number',
2365 'return 123',
2366 'enddef',
2367 'defcompile'], 'E1069:')
2368 delfunc! g:Func
2369
Bram Moolenaar62aec932022-01-29 21:45:34 +00002370 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002371 'def Func() :number',
2372 'return 123',
2373 'enddef',
2374 'defcompile'], 'E1059:')
2375 delfunc! g:Func
2376
Bram Moolenaar62aec932022-01-29 21:45:34 +00002377 v9.CheckScriptFailure([
Bram Moolenaar33ea9fd2021-08-08 19:07:37 +02002378 'def Func() : number',
2379 'return 123',
2380 'enddef',
2381 'defcompile'], 'E1059:')
2382 delfunc! g:Func
2383
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002384 v9.CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002385 delfunc! g:Func
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002386 v9.CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008: Missing <type> after dict')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002387 delfunc! g:Func
Bram Moolenaar62aec932022-01-29 21:45:34 +00002388 v9.CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002389 delfunc! g:Func
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002390
Bram Moolenaar62aec932022-01-29 21:45:34 +00002391 v9.CheckScriptFailure([
Bram Moolenaar5a849da2020-08-08 16:47:30 +02002392 'vim9script',
2393 'def FuncB()',
2394 ' return 123',
2395 'enddef',
2396 'def FuncA()',
2397 ' FuncB()',
2398 'enddef',
2399 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002400enddef
2401
2402def Test_arg_type_wrong()
Bram Moolenaar62e0e2e2022-08-20 12:07:58 +01002403 v9.CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type> after list')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002404 v9.CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
2405 v9.CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2406 v9.CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2407 v9.CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
2408 v9.CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002409enddef
2410
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002411def Test_white_space_before_comma()
2412 var lines =<< trim END
2413 vim9script
2414 def Func(a: number , b: number)
2415 enddef
2416 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002417 v9.CheckScriptFailure(lines, 'E1068:')
Yegappan Lakshmanan611728f2021-05-24 15:15:47 +02002418 call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
Bram Moolenaar86cdb8a2021-04-06 19:01:03 +02002419enddef
2420
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002421def Test_white_space_after_comma()
2422 var lines =<< trim END
2423 vim9script
2424 def Func(a: number,b: number)
2425 enddef
2426 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002427 v9.CheckScriptFailure(lines, 'E1069:')
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002428
2429 # OK in legacy function
2430 lines =<< trim END
2431 vim9script
2432 func Func(a,b)
2433 endfunc
2434 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002435 v9.CheckScriptSuccess(lines)
Bram Moolenaar608d78f2021-03-06 22:33:12 +01002436enddef
2437
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002438def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002439 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002440 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002441 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002442 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002443 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002444 enddef
2445 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002446 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002447
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002448 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002449 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002450 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002451
Bram Moolenaar67979662020-06-20 22:50:47 +02002452 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002453 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002454 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002455
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002456 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002457 def ListFunc(arg: list<number>)
2458 listvar = arg
2459 enddef
2460 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002461 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002462
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002463 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002464 def DictFunc(arg: dict<number>)
2465 dictvar = arg
2466 enddef
Bram Moolenaare0de1712020-12-02 17:36:54 +01002467 {a: 1, b: 2}->DictFunc()
2468 dictvar->assert_equal({a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002469 def CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002470 {a: 3, b: 4}->DictFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002471 enddef
2472 CompiledDict()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002473 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002474
Bram Moolenaare0de1712020-12-02 17:36:54 +01002475 {a: 3, b: 4}->DictFunc()
2476 dictvar->assert_equal({a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002477
2478 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002479 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002480 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002481 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +02002482
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002483 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +02002484 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002485 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002486 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +02002487 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002488 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002489
2490 def UseString()
2491 'xyork'->MyFunc()
2492 enddef
2493 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002494 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +02002495
Bram Moolenaar10409562020-07-29 20:00:38 +02002496 def UseString2()
2497 "knife"->MyFunc()
2498 enddef
2499 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002500 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +02002501
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002502 # prepending a colon makes it a mark
2503 new
2504 setline(1, ['aaa', 'bbb', 'ccc'])
2505 normal! 3Gmt1G
2506 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002507 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +02002508 bwipe!
2509
Bram Moolenaare6b53242020-07-01 17:28:33 +02002510 MyFunc(
2511 'continued'
2512 )
2513 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002514 name
Bram Moolenaare6b53242020-07-01 17:28:33 +02002515 )
2516
2517 call MyFunc(
2518 'more'
2519 ..
2520 'lines'
2521 )
2522 assert_equal(
2523 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002524 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002525 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002526 writefile(lines, 'Xcall.vim', 'D')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002527 source Xcall.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002528enddef
2529
2530def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002531 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002532 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002533 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002534 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002535 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002536 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002537 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002538 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002539 v9.CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002540enddef
2541
Bram Moolenaar65b95452020-07-19 14:03:09 +02002542def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002543 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +02002544 vim9script
2545 def MyFunc(arg: string)
2546 echo arg
2547 enddef
2548 MyFunc(1234)
2549 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002550 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +02002551enddef
2552
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002553def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002554 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002555 vim9script
2556 const var = ''
2557 def MyFunc(arg: string)
2558 var = 'asdf'
2559 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002560 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002561 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002562 writefile(lines, 'Xcall_const.vim', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002563 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar3bdc90b2020-12-22 20:35:40 +01002564
2565 lines =<< trim END
2566 const g:Aconst = 77
2567 def Change()
2568 # comment
2569 g:Aconst = 99
2570 enddef
2571 call Change()
2572 unlet g:Aconst
2573 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002574 v9.CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002575enddef
2576
2577" Test that inside :function a Python function can be defined, :def is not
2578" recognized.
2579func Test_function_python()
2580 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +02002581 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002582 execute py "<< EOF"
2583def do_something():
2584 return 1
2585EOF
2586endfunc
2587
2588def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002589 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002590 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002591 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002592 echo 'hello'
2593 enddef
2594
2595 def CallGoneSoon()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002596 g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002597 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02002598 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002599
Bram Moolenaar4c17ad92020-04-27 22:47:51 +02002600 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002601 CallGoneSoon()
2602 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002603 writefile(lines, 'XToDelFunc', 'D')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002604 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
2605 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002606enddef
2607
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002608func Test_free_dict_while_in_funcstack()
2609 " relies on the sleep command
2610 CheckUnix
2611 call Run_Test_free_dict_while_in_funcstack()
2612endfunc
2613
2614def Run_Test_free_dict_while_in_funcstack()
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002615 # this was freeing the TermRun() default argument dictionary while it was
2616 # still referenced in a funcstack_T
2617 var lines =<< trim END
2618 vim9script
2619
2620 &updatetime = 400
2621 def TermRun(_ = {})
2622 def Post()
2623 enddef
2624 def Exec()
2625 term_start('sleep 1', {
2626 term_finish: 'close',
2627 exit_cb: (_, _) => Post(),
2628 })
2629 enddef
2630 Exec()
2631 enddef
2632 nnoremap <F4> <Cmd>call <SID>TermRun()<CR>
2633 timer_start(100, (_) => feedkeys("\<F4>"))
2634 timer_start(1000, (_) => feedkeys("\<F4>"))
2635 sleep 1500m
2636 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00002637 v9.CheckScriptSuccess(lines)
Bram Moolenaar7509ad82021-12-14 18:14:37 +00002638 nunmap <F4>
2639 set updatetime&
2640enddef
2641
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002642def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +02002643 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002644 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002645 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002646 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002647 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02002648 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +02002649 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002650 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +02002651 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002652
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02002653 assert_fails('g:Func0()', 'E1091:')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002654 g:Func1()->assert_equal('Func1')
2655 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002656
2657 delfunc! Func0
2658 delfunc! Func1
2659 delfunc! Func2
2660enddef
2661
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002662def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002663 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002664 vim9script
2665 func Func(arg)
2666 echo a:arg
2667 endfunc
2668 Func('text')
2669 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002670 writefile(lines, 'XVim9Func', 'D')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002671 so XVim9Func
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002672enddef
2673
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002674let s:funcResult = 0
2675
2676def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02002677 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002678enddef
2679
2680def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002681 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002682 return 1234
2683enddef
2684
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002685def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02002686 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002687 return 'text'
2688enddef
2689
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002690def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002691 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002692enddef
2693
2694def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02002695 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002696 return arg
2697enddef
2698
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002699def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02002700 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002701enddef
2702
Bram Moolenaar62aec932022-01-29 21:45:34 +00002703def s:FuncOneArgRetString(arg: string): string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002704 return arg
2705enddef
2706
Bram Moolenaar62aec932022-01-29 21:45:34 +00002707def s:FuncOneArgRetAny(arg: any): any
Bram Moolenaar89228602020-04-05 22:14:54 +02002708 return arg
2709enddef
2710
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002711def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002712 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02002713 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002714 Ref1 = g:FuncNoArgNoRet
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002715 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002716 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002717
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002718 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02002719 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002720 Ref2 = g:FuncNoArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002721 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002722 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002723
Bram Moolenaar53900992020-08-22 19:02:02 +02002724 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002725 Ref2 = g:FuncOneArgNoRet
Bram Moolenaar4c683752020-04-05 21:38:23 +02002726 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002727 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002728
Bram Moolenaar53900992020-08-22 19:02:02 +02002729 s:funcResult = 0
Bram Moolenaar62aec932022-01-29 21:45:34 +00002730 Ref2 = g:FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002731 Ref2()->assert_equal(1234)
2732 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02002733
Bram Moolenaar53900992020-08-22 19:02:02 +02002734 s:funcResult = 0
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002735 Ref2 = g:FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002736 Ref2(13)->assert_equal(13)
2737 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002738enddef
2739
Bram Moolenaar9978d472020-07-05 16:01:56 +02002740def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002741 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02002742 for n in repeat([1], 3)
2743 res += n
2744 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002745 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002746
2747 res = 0
Bakudankun375141e2022-09-09 18:46:47 +01002748 for n in repeat(0z01, 3)->blob2list()
2749 res += n
2750 endfor
2751 res->assert_equal(3)
2752
2753 res = 0
Bram Moolenaarfce82b32020-07-05 16:07:21 +02002754 for n in add([1, 2], 3)
2755 res += n
2756 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002757 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02002758enddef
2759
Bram Moolenaar846178a2020-07-05 17:04:13 +02002760def Test_argv_return_type()
2761 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002762 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02002763 for name in argv()
2764 res ..= name
2765 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002766 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02002767enddef
2768
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002769def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002770 var RefVoid: func: void
Bram Moolenaar62aec932022-01-29 21:45:34 +00002771 RefVoid = g:FuncNoArgNoRet
2772 RefVoid = g:FuncOneArgNoRet
2773 v9.CheckDefFailure(['var RefVoid: func: void', 'RefVoid = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002774 v9.CheckDefFailure(['var RefVoid: func: void', 'RefVoid = g:FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002775
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002776 var RefAny: func(): any
Bram Moolenaar62aec932022-01-29 21:45:34 +00002777 RefAny = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002778 RefAny = g:FuncNoArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002779 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
2780 v9.CheckDefFailure(['var RefAny: func(): any', 'RefAny = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002781
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002782 var RefAnyNoArgs: func: any = RefAny
2783
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002784 var RefNr: func: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002785 RefNr = g:FuncNoArgRetNumber
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002786 RefNr = g:FuncOneArgRetNumber
Bram Moolenaar62aec932022-01-29 21:45:34 +00002787 v9.CheckDefFailure(['var RefNr: func: number', 'RefNr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002788 v9.CheckDefFailure(['var RefNr: func: number', 'RefNr = g:FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002789
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002790 var RefStr: func: string
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002791 RefStr = g:FuncNoArgRetString
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002792 RefStr = FuncOneArgRetString
Bram Moolenaar62aec932022-01-29 21:45:34 +00002793 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
2794 v9.CheckDefFailure(['var RefStr: func: string', 'RefStr = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02002795enddef
2796
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002797def Test_func_type_fails()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002798 v9.CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002799
Bram Moolenaar62aec932022-01-29 21:45:34 +00002800 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
2801 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002802 v9.CheckDefFailure(['var Ref1: func()', 'Ref1 = g:FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
Bram Moolenaar62aec932022-01-29 21:45:34 +00002803 v9.CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
2804 v9.CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
Ernie Rael3ec6c1f2023-10-21 11:45:38 +02002805 v9.CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = g:FuncTwoArgNoRet'], 'E1180: Variable arguments type must be a list: bool')
Bram Moolenaar08938ee2020-04-11 23:17:17 +02002806
Bram Moolenaar62aec932022-01-29 21:45:34 +00002807 v9.CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
2808 v9.CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
2809 v9.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:')
2810 v9.CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002811enddef
2812
Bram Moolenaar89228602020-04-05 22:14:54 +02002813def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002814 var nr: number
Bram Moolenaar62aec932022-01-29 21:45:34 +00002815 nr = g:FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002816 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02002817
2818 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002819 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02002820
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002821 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02002822 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002823 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02002824
Bram Moolenaar62aec932022-01-29 21:45:34 +00002825 v9.CheckDefFailure(['var str: string', 'str = g:FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02002826enddef
2827
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002828def Test_func_common_type()
2829 def FuncOne(n: number): number
2830 return n
2831 enddef
2832 def FuncTwo(s: string): number
2833 return len(s)
2834 enddef
2835 def FuncThree(n: number, s: string): number
2836 return n + len(s)
2837 enddef
2838 var list = [FuncOne, FuncTwo, FuncThree]
2839 assert_equal(8, list[0](8))
2840 assert_equal(4, list[1]('word'))
2841 assert_equal(7, list[2](3, 'word'))
2842enddef
2843
Bram Moolenaar62aec932022-01-29 21:45:34 +00002844def s:MultiLine(
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002845 arg1: string,
2846 arg2 = 1234,
2847 ...rest: list<string>
2848 ): string
2849 return arg1 .. arg2 .. join(rest, '-')
2850enddef
2851
Bram Moolenaar2c330432020-04-13 14:41:35 +02002852def MultiLineComment(
2853 arg1: string, # comment
2854 arg2 = 1234, # comment
2855 ...rest: list<string> # comment
2856 ): string # comment
2857 return arg1 .. arg2 .. join(rest, '-')
2858enddef
2859
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002860def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002861 MultiLine('text')->assert_equal('text1234')
2862 MultiLine('text', 777)->assert_equal('text777')
2863 MultiLine('text', 777, 'one')->assert_equal('text777one')
2864 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002865enddef
2866
Bram Moolenaar23e03252020-04-12 22:22:31 +02002867func Test_multiline_not_vim9()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002868 call s:MultiLine('text')->assert_equal('text1234')
2869 call s:MultiLine('text', 777)->assert_equal('text777')
2870 call s:MultiLine('text', 777, 'one')->assert_equal('text777one')
2871 call s:MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02002872endfunc
2873
Bram Moolenaar5e774c72020-04-12 21:53:00 +02002874
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002875" When using CheckScriptFailure() for the below test, E1010 is generated instead
2876" of E1056.
2877func Test_E1056_1059()
2878 let caught_1056 = 0
2879 try
2880 def F():
2881 return 1
2882 enddef
2883 catch /E1056:/
2884 let caught_1056 = 1
2885 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002886 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002887
2888 let caught_1059 = 0
2889 try
2890 def F5(items : list)
2891 echo 'a'
2892 enddef
2893 catch /E1059:/
2894 let caught_1059 = 1
2895 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002896 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02002897endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002898
Bram Moolenaar015f4262020-05-05 21:25:22 +02002899func DelMe()
2900 echo 'DelMe'
2901endfunc
2902
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002903def Test_error_reporting()
2904 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002905 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002906 " comment
2907 def Func()
2908 # comment
2909 # comment
2910 invalid
2911 enddef
2912 defcompile
2913 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01002914 writefile(lines, 'Xdef', 'D')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002915 try
2916 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002917 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002918 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002919 v:exception->assert_match('Invalid command: invalid')
2920 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002921 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002922 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002923
2924 # comment lines after the start of the function
2925 lines =<< trim END
2926 " comment
2927 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002928 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002929 # comment
2930 # comment
2931 invalid
2932 enddef
2933 defcompile
2934 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002935 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002936 try
2937 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002938 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002939 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002940 v:exception->assert_match('Invalid command: invalid')
2941 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002942 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002943 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002944
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002945 lines =<< trim END
2946 vim9script
2947 def Func()
Bram Moolenaare0de1712020-12-02 17:36:54 +01002948 var db = {foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002949 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002950 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002951 enddef
2952 defcompile
2953 Func()
2954 END
Bram Moolenaar08052222020-09-14 17:04:31 +02002955 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002956 try
2957 source Xdef
2958 assert_report('should have failed')
2959 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002960 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02002961 endtry
Bram Moolenaar2d870f82020-12-05 13:41:01 +01002962 delfunc! g:Func
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02002963enddef
2964
Bram Moolenaar015f4262020-05-05 21:25:22 +02002965def Test_deleted_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002966 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002967 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02002968 'delfunc g:DelMe',
2969 'echo RefMe()'], 'E117:')
2970enddef
2971
2972def Test_unknown_function()
Bram Moolenaar62aec932022-01-29 21:45:34 +00002973 v9.CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002974 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02002975 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02002976enddef
2977
Bram Moolenaar62aec932022-01-29 21:45:34 +00002978def s:RefFunc(Ref: func(any): any): string
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002979 return Ref('more')
2980enddef
2981
2982def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002983 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002984 RefFunc((s) => local .. s)->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02002985enddef
2986
Bram Moolenaar62aec932022-01-29 21:45:34 +00002987def s:MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002988 var local = 'some '
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002989 g:Ref = (s) => local .. s
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002990enddef
2991
2992def Test_closure_ref_after_return()
2993 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002994 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02002995 unlet g:Ref
2996enddef
2997
Bram Moolenaar62aec932022-01-29 21:45:34 +00002998def s:MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002999 var local = ['some']
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003000 g:Extend = (s) => local->add(s)
3001 g:Read = () => local
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003002enddef
3003
3004def Test_closure_two_refs()
3005 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003006 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003007 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003008 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003009 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003010 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003011
3012 unlet g:Extend
3013 unlet g:Read
3014enddef
3015
Bram Moolenaar62aec932022-01-29 21:45:34 +00003016def s:ReadRef(Ref: func(): list<string>): string
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003017 return join(Ref(), ' ')
3018enddef
3019
Bram Moolenaar62aec932022-01-29 21:45:34 +00003020def s:ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003021 Ref(add)
3022enddef
3023
3024def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02003025 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003026 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003027 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003028 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003029 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003030 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02003031
3032 unlet g:Extend
3033 unlet g:Read
3034enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02003035
Bram Moolenaar62aec932022-01-29 21:45:34 +00003036def s:MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003037 var local = 'loc_val'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003038 g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003039enddef
3040
Bram Moolenaar62aec932022-01-29 21:45:34 +00003041def s:MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003042 var local = 'the_loc'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003043 g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003044enddef
3045
3046def Test_closure_using_argument()
3047 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003048 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003049
3050 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003051 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003052
3053 unlet g:UseArg
3054 unlet g:UseVararg
Bram Moolenaar44ec21c2021-02-12 21:50:57 +01003055
3056 var lines =<< trim END
3057 vim9script
3058 def Test(Fun: func(number): number): list<number>
3059 return map([1, 2, 3], (_, i) => Fun(i))
3060 enddef
3061 def Inc(nr: number): number
3062 return nr + 2
3063 enddef
3064 assert_equal([3, 4, 5], Test(Inc))
3065 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003066 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02003067enddef
3068
Bram Moolenaar62aec932022-01-29 21:45:34 +00003069def s:MakeGetAndAppendRefs()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003070 var local = 'a'
3071
3072 def Append(arg: string)
3073 local ..= arg
3074 enddef
3075 g:Append = Append
3076
3077 def Get(): string
3078 return local
3079 enddef
3080 g:Get = Get
3081enddef
3082
3083def Test_closure_append_get()
3084 MakeGetAndAppendRefs()
3085 g:Get()->assert_equal('a')
3086 g:Append('-b')
3087 g:Get()->assert_equal('a-b')
3088 g:Append('-c')
3089 g:Get()->assert_equal('a-b-c')
3090
3091 unlet g:Append
3092 unlet g:Get
3093enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02003094
Bram Moolenaar04b12692020-05-04 23:24:44 +02003095def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003096 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02003097 def Closure(arg: string): string
3098 return local .. arg
3099 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003100 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02003101enddef
3102
Bram Moolenaar62aec932022-01-29 21:45:34 +00003103func s:GetResult(Ref)
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003104 return a:Ref('some')
3105endfunc
3106
3107def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003108 var text = 'text'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003109 g:Ref = (s) => s .. text
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003110 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02003111enddef
3112
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003113def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003114 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003115 vim9script
3116 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003117 var name = 0
3118 for i in range(2)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003119 timer_start(0, () => name)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003120 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003121 enddef
3122 Func()
3123 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003124 v9.CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02003125enddef
3126
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003127def Test_nested_closure_used()
3128 var lines =<< trim END
3129 vim9script
3130 def Func()
3131 var x = 'hello'
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003132 var Closure = () => x
3133 g:Myclosure = () => Closure()
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003134 enddef
3135 Func()
3136 assert_equal('hello', g:Myclosure())
3137 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003138 v9.CheckScriptSuccess(lines)
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02003139enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02003140
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003141def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003142 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003143 vim9script
3144 def FuncA()
3145 FuncB(0)
3146 enddef
3147 def FuncB(n: number): list<string>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003148 return map([0], (_, v) => n)
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003149 enddef
3150 FuncA()
3151 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003152 v9.CheckScriptFailure(lines, 'E1012:')
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02003153enddef
3154
Bram Moolenaar6de22962022-09-09 21:35:36 +01003155def Run_Test_closure_in_for_loop_fails()
3156 var lines =<< trim END
3157 vim9script
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003158 redraw
Bram Moolenaar6de22962022-09-09 21:35:36 +01003159 for n in [0]
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003160 # time should be enough for startup to finish
3161 timer_start(200, (_) => {
Bram Moolenaar6de22962022-09-09 21:35:36 +01003162 echo n
3163 })
3164 endfor
3165 END
3166 writefile(lines, 'XTest_closure_fails', 'D')
3167
3168 # Check that an error shows
Bram Moolenaarc069ede2022-09-11 12:01:04 +01003169 var buf = g:RunVimInTerminal('-S XTest_closure_fails', {rows: 6, wait_for_ruler: 0})
Bram Moolenaar766ae5b2022-09-14 00:30:51 +01003170 g:VerifyScreenDump(buf, 'Test_vim9_closure_fails', {wait: 3000})
Bram Moolenaar6de22962022-09-09 21:35:36 +01003171
3172 # clean up
3173 g:StopVimInTerminal(buf)
3174enddef
3175
3176func Test_closure_in_for_loop_fails()
3177 CheckScreendump
3178 call Run_Test_closure_in_for_loop_fails()
3179endfunc
3180
Bram Moolenaarf112f302020-12-20 17:47:52 +01003181def Test_global_closure()
3182 var lines =<< trim END
3183 vim9script
3184 def ReverseEveryNLines(n: number, line1: number, line2: number)
3185 var mods = 'sil keepj keepp lockm '
3186 var range = ':' .. line1 .. ',' .. line2
3187 def g:Offset(): number
3188 var offset = (line('.') - line1 + 1) % n
3189 return offset != 0 ? offset : n
3190 enddef
3191 exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
3192 enddef
3193
3194 new
3195 repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
3196 ReverseEveryNLines(3, 1, 9)
3197 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003198 v9.CheckScriptSuccess(lines)
Bram Moolenaarf112f302020-12-20 17:47:52 +01003199 var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
3200 assert_equal(expected, getline(1, 9))
3201 bwipe!
3202enddef
3203
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003204def Test_global_closure_called_directly()
3205 var lines =<< trim END
3206 vim9script
3207 def Outer()
3208 var x = 1
3209 def g:Inner()
3210 var y = x
3211 x += 1
3212 assert_equal(1, y)
3213 enddef
3214 g:Inner()
3215 assert_equal(2, x)
3216 enddef
3217 Outer()
3218 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003219 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd45ed02020-12-22 17:35:54 +01003220 delfunc g:Inner
3221enddef
3222
Bram Moolenaar69c76172021-12-02 16:38:52 +00003223def Test_closure_called_from_legacy()
3224 var lines =<< trim END
3225 vim9script
3226 def Func()
3227 var outer = 'foo'
3228 var F = () => {
3229 outer = 'bar'
3230 }
3231 execute printf('call %s()', string(F))
3232 enddef
3233 Func()
3234 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003235 v9.CheckScriptFailure(lines, 'E1248')
Bram Moolenaar69c76172021-12-02 16:38:52 +00003236enddef
3237
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003238def Test_failure_in_called_function()
3239 # this was using the frame index as the return value
3240 var lines =<< trim END
3241 vim9script
3242 au TerminalWinOpen * eval [][0]
3243 def PopupTerm(a: any)
3244 # make sure typvals on stack are string
3245 ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
3246 FireEvent()
3247 enddef
3248 def FireEvent()
3249 do TerminalWinOpen
3250 enddef
3251 # use try/catch to make eval fail
3252 try
3253 call PopupTerm(0)
3254 catch
3255 endtry
3256 au! TerminalWinOpen
3257 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003258 v9.CheckScriptSuccess(lines)
Bram Moolenaar34c54eb2020-11-25 19:15:19 +01003259enddef
3260
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003261def Test_nested_lambda()
3262 var lines =<< trim END
3263 vim9script
3264 def Func()
3265 var x = 4
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003266 var Lambda1 = () => 7
3267 var Lambda2 = () => [Lambda1(), x]
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003268 var res = Lambda2()
3269 assert_equal([7, 4], res)
3270 enddef
3271 Func()
3272 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003273 v9.CheckScriptSuccess(lines)
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02003274enddef
3275
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003276def Test_double_nested_lambda()
3277 var lines =<< trim END
3278 vim9script
3279 def F(head: string): func(string): func(string): string
3280 return (sep: string): func(string): string => ((tail: string): string => {
3281 return head .. sep .. tail
3282 })
3283 enddef
3284 assert_equal('hello-there', F('hello')('-')('there'))
3285 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003286 v9.CheckScriptSuccess(lines)
Bram Moolenaarc04f2a42021-06-09 19:30:03 +02003287enddef
3288
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003289def Test_nested_inline_lambda()
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003290 var lines =<< trim END
3291 vim9script
3292 def F(text: string): func(string): func(string): string
3293 return (arg: string): func(string): string => ((sep: string): string => {
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003294 return sep .. arg .. text
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003295 })
3296 enddef
Bram Moolenaar23e2e112021-08-03 21:16:18 +02003297 assert_equal('--there++', F('++')('there')('--'))
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003298 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003299 v9.CheckScriptSuccess(lines)
Bram Moolenaar5245beb2021-07-15 22:03:50 +02003300
3301 lines =<< trim END
3302 vim9script
3303 echo range(4)->mapnew((_, v) => {
3304 return range(v) ->mapnew((_, s) => {
3305 return string(s)
3306 })
3307 })
3308 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003309 v9.CheckScriptSuccess(lines)
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003310
3311 lines =<< trim END
3312 vim9script
3313
Bram Moolenaara749a422022-02-12 19:52:25 +00003314 def Func()
Bram Moolenaarc6ba2f92021-07-18 13:42:29 +02003315 range(10)
3316 ->mapnew((_, _) => ({
3317 key: range(10)->mapnew((_, _) => {
3318 return ' '
3319 }),
3320 }))
3321 enddef
3322
3323 defcomp
3324 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003325 v9.CheckScriptSuccess(lines)
Bram Moolenaar074f84c2021-05-18 11:47:44 +02003326enddef
3327
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003328def Shadowed(): list<number>
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003329 var FuncList: list<func: number> = [() => 42]
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003330 return FuncList->mapnew((_, Shadowed) => Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003331enddef
3332
3333def Test_lambda_arg_shadows_func()
Bram Moolenaar62aec932022-01-29 21:45:34 +00003334 assert_equal([42], g:Shadowed())
Bram Moolenaar52bf81c2020-11-17 18:50:44 +01003335enddef
3336
Bram Moolenaar21dc8f12022-03-16 17:54:17 +00003337def Test_compiling_referenced_func_no_shadow()
3338 var lines =<< trim END
3339 vim9script
3340
3341 def InitializeReply(lspserver: dict<any>)
3342 enddef
3343
3344 def ProcessReply(lspserver: dict<any>)
3345 var lsp_reply_handlers: dict<func> =
3346 { 'initialize': InitializeReply }
3347 lsp_reply_handlers['initialize'](lspserver)
3348 enddef
3349
3350 call ProcessReply({})
3351 END
3352 v9.CheckScriptSuccess(lines)
3353enddef
3354
Bram Moolenaar62aec932022-01-29 21:45:34 +00003355def s:Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003356 var path: string = empty(dir)
3357 \ ? 'empty'
3358 \ : 'full'
3359 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003360enddef
3361
3362def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003363 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02003364enddef
3365
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003366def Test_script_var_in_lambda()
3367 var lines =<< trim END
3368 vim9script
3369 var script = 'test'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003370 assert_equal(['test'], map(['one'], (_, _) => script))
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003371 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003372 v9.CheckScriptSuccess(lines)
Bram Moolenaar2ea95b62020-11-19 21:47:56 +01003373enddef
3374
Bram Moolenaar62aec932022-01-29 21:45:34 +00003375def s:Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003376 var x = range(97, 100)
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003377 ->mapnew((_, v) => nr2char(v)
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003378 ->toupper())
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003379 ->reverse()
3380 return x
3381enddef
3382
3383def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003384 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaarf898f7c2021-01-16 18:09:52 +01003385
3386 var lines =<< trim END
3387 vim9script
3388 var res = [{n: 1, m: 2, s: 'xxx'}]
3389 ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
3390 v.n,
3391 v.m,
3392 substitute(v.s, '.*', 'yyy', '')
3393 ))
3394 assert_equal(['1:2:yyy'], res)
3395 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003396 v9.CheckScriptSuccess(lines)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02003397enddef
3398
Bram Moolenaarb6571982021-01-08 22:24:19 +01003399def Test_list_lambda()
3400 timer_start(1000, (_) => 0)
3401 var body = execute(timer_info()[0].callback
3402 ->string()
3403 ->substitute("('", ' ', '')
3404 ->substitute("')", '', '')
3405 ->substitute('function\zs', ' ', ''))
Bram Moolenaar767034c2021-04-09 17:24:52 +02003406 assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body)
Bram Moolenaarb6571982021-01-08 22:24:19 +01003407enddef
3408
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003409def Test_lambda_block_variable()
Bram Moolenaar88421d62021-07-24 14:14:52 +02003410 var lines =<< trim END
3411 vim9script
3412 var flist: list<func>
3413 for i in range(10)
3414 var inloop = i
3415 flist[i] = () => inloop
3416 endfor
3417 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003418 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003419
3420 lines =<< trim END
3421 vim9script
3422 if true
3423 var outloop = 5
3424 var flist: list<func>
3425 for i in range(10)
3426 flist[i] = () => outloop
3427 endfor
3428 endif
3429 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003430 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003431
3432 lines =<< trim END
3433 vim9script
3434 if true
3435 var outloop = 5
3436 endif
3437 var flist: list<func>
3438 for i in range(10)
3439 flist[i] = () => outloop
3440 endfor
3441 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003442 v9.CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
Bram Moolenaar3c77b6a2021-07-25 18:07:00 +02003443
3444 lines =<< trim END
3445 vim9script
3446 for i in range(10)
3447 var Ref = () => 0
3448 endfor
3449 assert_equal(0, ((i) => 0)(0))
3450 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003451 v9.CheckScriptSuccess(lines)
Bram Moolenaar88421d62021-07-24 14:14:52 +02003452enddef
3453
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003454def Test_legacy_lambda()
3455 legacy echo {x -> 'hello ' .. x}('foo')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003456
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003457 var lines =<< trim END
3458 echo {x -> 'hello ' .. x}('foo')
3459 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003460 v9.CheckDefAndScriptFailure(lines, 'E720:')
Bram Moolenaardc4c2302021-04-25 13:54:42 +02003461
3462 lines =<< trim END
3463 vim9script
3464 def Func()
3465 echo (() => 'no error')()
3466 enddef
3467 legacy call s:Func()
3468 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003469 v9.CheckScriptSuccess(lines)
Bram Moolenaar96cf4ba2021-04-24 14:15:41 +02003470enddef
3471
Bram Moolenaarce024c32021-06-26 13:00:49 +02003472def Test_legacy()
3473 var lines =<< trim END
3474 vim9script
3475 func g:LegacyFunction()
3476 let g:legacyvar = 1
3477 endfunc
3478 def Testit()
3479 legacy call g:LegacyFunction()
3480 enddef
3481 Testit()
3482 assert_equal(1, g:legacyvar)
3483 unlet g:legacyvar
3484 delfunc g:LegacyFunction
3485 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003486 v9.CheckScriptSuccess(lines)
Bram Moolenaarce024c32021-06-26 13:00:49 +02003487enddef
3488
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003489def Test_legacy_errors()
3490 for cmd in ['if', 'elseif', 'else', 'endif',
3491 'for', 'endfor', 'continue', 'break',
3492 'while', 'endwhile',
3493 'try', 'catch', 'finally', 'endtry']
Bram Moolenaar62aec932022-01-29 21:45:34 +00003494 v9.CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
Bram Moolenaarc3cb1c92021-06-02 16:47:53 +02003495 endfor
3496enddef
3497
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003498def Test_call_legacy_with_dict()
3499 var lines =<< trim END
3500 vim9script
3501 func Legacy() dict
3502 let g:result = self.value
3503 endfunc
3504 def TestDirect()
3505 var d = {value: 'yes', func: Legacy}
3506 d.func()
3507 enddef
3508 TestDirect()
3509 assert_equal('yes', g:result)
3510 unlet g:result
3511
3512 def TestIndirect()
3513 var d = {value: 'foo', func: Legacy}
3514 var Fi = d.func
3515 Fi()
3516 enddef
3517 TestIndirect()
3518 assert_equal('foo', g:result)
3519 unlet g:result
3520
3521 var d = {value: 'bar', func: Legacy}
3522 d.func()
3523 assert_equal('bar', g:result)
3524 unlet g:result
3525 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003526 v9.CheckScriptSuccess(lines)
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003527enddef
3528
Bram Moolenaar62aec932022-01-29 21:45:34 +00003529def s:DoFilterThis(a: string): list<string>
Bram Moolenaarab360522021-01-10 14:02:28 +01003530 # closure nested inside another closure using argument
3531 var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
3532 return ['x', 'y', 'a', 'x2', 'c']->Filter()
3533enddef
3534
3535def Test_nested_closure_using_argument()
3536 assert_equal(['x', 'x2'], DoFilterThis('x'))
3537enddef
3538
Bram Moolenaar0186e582021-01-10 18:33:11 +01003539def Test_triple_nested_closure()
3540 var what = 'x'
3541 var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
3542 var Filter = (l) => filter(l, (_, v) => Match(v, what))
3543 assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
3544enddef
3545
Bram Moolenaar8f510af2020-07-05 18:48:23 +02003546func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003547 CheckScreendump
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003548 call Run_Test_silent_echo()
3549endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003550
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003551def Run_Test_silent_echo()
3552 var lines =<< trim END
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003553 vim9script
3554 def EchoNothing()
3555 silent echo ''
3556 enddef
3557 defcompile
3558 END
Bram Moolenaar6de22962022-09-09 21:35:36 +01003559 writefile(lines, 'XTest_silent_echo', 'D')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003560
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003561 # Check that the balloon shows up after a mouse move
Bram Moolenaar62aec932022-01-29 21:45:34 +00003562 var buf = g:RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003563 term_sendkeys(buf, ":abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +00003564 g:VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003565
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003566 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00003567 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003568enddef
Bram Moolenaar47e7d702020-07-05 18:18:42 +02003569
Bram Moolenaar171fb922020-10-28 16:54:47 +01003570def SilentlyError()
3571 execute('silent! invalid')
3572 g:did_it = 'yes'
3573enddef
3574
Bram Moolenaar62aec932022-01-29 21:45:34 +00003575func s:UserError()
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003576 silent! invalid
3577endfunc
3578
3579def SilentlyUserError()
3580 UserError()
3581 g:did_it = 'yes'
3582enddef
Bram Moolenaar171fb922020-10-28 16:54:47 +01003583
3584" This can't be a :def function, because the assert would not be reached.
Bram Moolenaar171fb922020-10-28 16:54:47 +01003585func Test_ignore_silent_error()
3586 let g:did_it = 'no'
3587 call SilentlyError()
3588 call assert_equal('yes', g:did_it)
3589
Bram Moolenaar28ee8922020-10-28 20:20:00 +01003590 let g:did_it = 'no'
3591 call SilentlyUserError()
3592 call assert_equal('yes', g:did_it)
Bram Moolenaar171fb922020-10-28 16:54:47 +01003593
3594 unlet g:did_it
3595endfunc
3596
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003597def Test_ignore_silent_error_in_filter()
3598 var lines =<< trim END
3599 vim9script
3600 def Filter(winid: number, key: string): bool
3601 if key == 'o'
3602 silent! eval [][0]
3603 return true
3604 endif
3605 return popup_filter_menu(winid, key)
3606 enddef
3607
Bram Moolenaare0de1712020-12-02 17:36:54 +01003608 popup_create('popup', {filter: Filter})
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003609 feedkeys("o\r", 'xnt')
3610 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003611 v9.CheckScriptSuccess(lines)
Bram Moolenaarcd030c42020-10-30 21:49:40 +01003612enddef
3613
Bram Moolenaar62aec932022-01-29 21:45:34 +00003614def s:Fibonacci(n: number): number
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02003615 if n < 2
3616 return n
3617 else
3618 return Fibonacci(n - 1) + Fibonacci(n - 2)
3619 endif
3620enddef
3621
Bram Moolenaar985116a2020-07-12 17:31:09 +02003622def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003623 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02003624enddef
3625
Bram Moolenaar62aec932022-01-29 21:45:34 +00003626def s:TreeWalk(dir: string): list<any>
Bram Moolenaar75ab91f2021-01-10 22:42:50 +01003627 return readdir(dir)->mapnew((_, val) =>
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003628 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaar2bede172020-11-19 18:53:18 +01003629 ? {[val]: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003630 : val
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003631 )
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003632enddef
3633
3634def Test_closure_in_map()
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003635 mkdir('XclosureDir/tdir', 'pR')
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003636 writefile(['111'], 'XclosureDir/file1')
3637 writefile(['222'], 'XclosureDir/file2')
3638 writefile(['333'], 'XclosureDir/tdir/file3')
3639
Bram Moolenaare0de1712020-12-02 17:36:54 +01003640 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02003641enddef
3642
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003643def Test_invalid_function_name()
3644 var lines =<< trim END
3645 vim9script
3646 def s: list<string>
3647 END
Bram Moolenaara749a422022-02-12 19:52:25 +00003648 v9.CheckScriptFailure(lines, 'E1268:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003649
3650 lines =<< trim END
3651 vim9script
3652 def g: list<string>
3653 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003654 v9.CheckScriptFailure(lines, 'E129:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003655
3656 lines =<< trim END
3657 vim9script
3658 def <SID>: list<string>
3659 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003660 v9.CheckScriptFailure(lines, 'E884:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003661
3662 lines =<< trim END
3663 vim9script
3664 def F list<string>
3665 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003666 v9.CheckScriptFailure(lines, 'E488:')
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02003667enddef
3668
Bram Moolenaara90afb92020-07-15 22:38:56 +02003669def Test_partial_call()
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003670 var lines =<< trim END
3671 var Xsetlist: func
3672 Xsetlist = function('setloclist', [0])
3673 Xsetlist([], ' ', {title: 'test'})
3674 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003675
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003676 Xsetlist = function('setloclist', [0, [], ' '])
3677 Xsetlist({title: 'test'})
3678 getloclist(0, {title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003679
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003680 Xsetlist = function('setqflist')
3681 Xsetlist([], ' ', {title: 'test'})
3682 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02003683
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003684 Xsetlist = function('setqflist', [[], ' '])
3685 Xsetlist({title: 'test'})
3686 getqflist({title: 1})->assert_equal({title: 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02003687
Bram Moolenaarf78da4f2021-08-01 15:40:31 +02003688 var Len: func: number = function('len', ['word'])
3689 assert_equal(4, Len())
3690
3691 var RepeatFunc = function('repeat', ['o'])
3692 assert_equal('ooooo', RepeatFunc(5))
3693 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003694 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaarc66f6452021-08-19 21:08:30 +02003695
3696 lines =<< trim END
3697 vim9script
3698 def Foo(Parser: any)
3699 enddef
3700 var Expr: func(dict<any>): dict<any>
3701 const Call = Foo(Expr)
3702 END
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +00003703 v9.CheckScriptFailure(lines, 'E1031:')
Yegappan Lakshmanan29bb67f2023-10-14 11:18:50 +02003704
3705 # Test for calling a partial that takes a single argument.
3706 # This used to produce a "E340: Internal error" message.
3707 lines =<< trim END
3708 def Foo(n: number): number
3709 return n * 2
3710 enddef
3711 var Fn = function(Foo, [10])
3712 assert_equal(20, Fn())
3713 END
3714 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara90afb92020-07-15 22:38:56 +02003715enddef
3716
Bram Moolenaarcd1cda22022-02-16 21:48:25 +00003717def Test_partial_double_nested()
3718 var idx = 123
3719 var Get = () => idx
3720 var Ref = function(Get, [])
3721 var RefRef = function(Ref, [])
3722 assert_equal(123, RefRef())
3723enddef
3724
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003725def Test_partial_null_function()
3726 var lines =<< trim END
3727 var d: dict<func> = {f: null_function}
3728 var Ref = d.f
Bram Moolenaared0c62e2022-03-08 19:43:55 +00003729 assert_equal('func(...): unknown', typename(Ref))
Bram Moolenaar673bcb12022-03-08 16:52:24 +00003730 END
3731 v9.CheckDefAndScriptSuccess(lines)
3732enddef
3733
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003734def Test_cmd_modifier()
3735 tab echo '0'
Bram Moolenaar62aec932022-01-29 21:45:34 +00003736 v9.CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003737enddef
3738
3739def Test_restore_modifiers()
3740 # check that when compiling a :def function command modifiers are not messed
3741 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02003742 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003743 vim9script
3744 set eventignore=
3745 autocmd QuickFixCmdPost * copen
3746 def AutocmdsDisabled()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003747 eval 1 + 2
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003748 enddef
3749 func Func()
3750 noautocmd call s:AutocmdsDisabled()
3751 let g:ei_after = &eventignore
3752 endfunc
3753 Func()
3754 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003755 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003756 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02003757enddef
3758
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003759def StackTop()
Bram Moolenaarc3235272021-07-10 19:42:03 +02003760 eval 1 + 2
3761 eval 2 + 3
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003762 # call not on fourth line
Bram Moolenaar62aec932022-01-29 21:45:34 +00003763 g:StackBot()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003764enddef
3765
3766def StackBot()
3767 # throw an error
3768 eval [][0]
3769enddef
3770
3771def Test_callstack_def()
3772 try
Bram Moolenaar62aec932022-01-29 21:45:34 +00003773 g:StackTop()
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003774 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02003775 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02003776 endtry
3777enddef
3778
Bram Moolenaare8211a32020-10-09 22:04:29 +02003779" Re-using spot for variable used in block
3780def Test_block_scoped_var()
3781 var lines =<< trim END
3782 vim9script
3783 def Func()
3784 var x = ['a', 'b', 'c']
3785 if 1
3786 var y = 'x'
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02003787 map(x, (_, _) => y)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003788 endif
3789 var z = x
3790 assert_equal(['x', 'x', 'x'], z)
3791 enddef
3792 Func()
3793 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003794 v9.CheckScriptSuccess(lines)
Bram Moolenaare8211a32020-10-09 22:04:29 +02003795enddef
3796
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003797def Test_reset_did_emsg()
3798 var lines =<< trim END
3799 @s = 'blah'
3800 au BufWinLeave * #
3801 def Func()
3802 var winid = popup_create('popup', {})
3803 exe '*s'
3804 popup_close(winid)
3805 enddef
3806 Func()
3807 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003808 v9.CheckScriptFailure(lines, 'E492:', 8)
Bram Moolenaar2d870f82020-12-05 13:41:01 +01003809 delfunc! g:Func
Bram Moolenaareeece9e2020-11-20 19:26:48 +01003810enddef
3811
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003812def Test_did_emsg_reset()
3813 # executing an autocommand resets did_emsg, this should not result in a
3814 # builtin function considered failing
3815 var lines =<< trim END
3816 vim9script
3817 au BufWinLeave * #
3818 def Func()
Bram Moolenaar767034c2021-04-09 17:24:52 +02003819 popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003820 eval [][0]
3821 enddef
3822 nno <F3> <cmd>call <sid>Func()<cr>
3823 feedkeys("\<F3>\e", 'xt')
3824 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003825 writefile(lines, 'XemsgReset', 'D')
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003826 assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003827
Bram Moolenaar57f799e2020-12-12 20:42:19 +01003828 nunmap <F3>
3829 au! BufWinLeave
3830enddef
3831
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003832def Test_abort_with_silent_call()
3833 var lines =<< trim END
3834 vim9script
3835 g:result = 'none'
3836 def Func()
3837 g:result += 3
3838 g:result = 'yes'
3839 enddef
3840 # error is silenced, but function aborts on error
3841 silent! Func()
3842 assert_equal('none', g:result)
3843 unlet g:result
3844 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003845 v9.CheckScriptSuccess(lines)
Bram Moolenaar56602ba2020-12-05 21:22:08 +01003846enddef
3847
Bram Moolenaarf665e972020-12-05 19:17:16 +01003848def Test_continues_with_silent_error()
3849 var lines =<< trim END
3850 vim9script
3851 g:result = 'none'
3852 def Func()
3853 silent! g:result += 3
3854 g:result = 'yes'
3855 enddef
3856 # error is silenced, function does not abort
3857 Func()
3858 assert_equal('yes', g:result)
3859 unlet g:result
3860 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003861 v9.CheckScriptSuccess(lines)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003862enddef
3863
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003864def Test_abort_even_with_silent()
3865 var lines =<< trim END
3866 vim9script
3867 g:result = 'none'
3868 def Func()
3869 eval {-> ''}() .. '' .. {}['X']
3870 g:result = 'yes'
3871 enddef
Bram Moolenaarf665e972020-12-05 19:17:16 +01003872 silent! Func()
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003873 assert_equal('none', g:result)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003874 unlet g:result
3875 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003876 v9.CheckScriptSuccess(lines)
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003877enddef
3878
Bram Moolenaarf665e972020-12-05 19:17:16 +01003879def Test_cmdmod_silent_restored()
3880 var lines =<< trim END
3881 vim9script
3882 def Func()
3883 g:result = 'none'
3884 silent! g:result += 3
3885 g:result = 'none'
3886 g:result += 3
3887 enddef
3888 Func()
3889 END
3890 # can't use CheckScriptFailure, it ignores the :silent!
3891 var fname = 'Xdefsilent'
Bram Moolenaarf5fec052022-09-11 11:49:22 +01003892 writefile(lines, fname, 'D')
Bram Moolenaarf665e972020-12-05 19:17:16 +01003893 var caught = 'no'
3894 try
3895 exe 'source ' .. fname
3896 catch /E1030:/
3897 caught = 'yes'
3898 assert_match('Func, line 4', v:throwpoint)
3899 endtry
3900 assert_equal('yes', caught)
Bram Moolenaarf665e972020-12-05 19:17:16 +01003901enddef
3902
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003903def Test_cmdmod_silent_nested()
3904 var lines =<< trim END
3905 vim9script
3906 var result = ''
3907
3908 def Error()
3909 result ..= 'Eb'
3910 eval [][0]
3911 result ..= 'Ea'
3912 enddef
3913
3914 def Crash()
3915 result ..= 'Cb'
3916 sil! Error()
3917 result ..= 'Ca'
3918 enddef
3919
3920 Crash()
3921 assert_equal('CbEbEaCa', result)
3922 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003923 v9.CheckScriptSuccess(lines)
Bram Moolenaar2fecb532021-03-24 22:00:56 +01003924enddef
3925
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003926def Test_dict_member_with_silent()
3927 var lines =<< trim END
3928 vim9script
3929 g:result = 'none'
3930 var d: dict<any>
3931 def Func()
3932 try
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01003933 g:result = map([], (_, v) => ({}[v]))->join() .. d['']
Bram Moolenaar4029cab2020-12-05 18:13:27 +01003934 catch
3935 endtry
3936 enddef
3937 silent! Func()
3938 assert_equal('0', g:result)
3939 unlet g:result
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003940 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003941 v9.CheckScriptSuccess(lines)
Bram Moolenaaraf0df472020-12-02 20:51:22 +01003942enddef
3943
Bram Moolenaarf9041332021-01-21 19:41:16 +01003944def Test_skip_cmds_with_silent()
3945 var lines =<< trim END
3946 vim9script
3947
3948 def Func(b: bool)
3949 Crash()
3950 enddef
3951
3952 def Crash()
3953 sil! :/not found/d _
3954 sil! :/not found/put _
3955 enddef
3956
3957 Func(true)
3958 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00003959 v9.CheckScriptSuccess(lines)
Bram Moolenaarf9041332021-01-21 19:41:16 +01003960enddef
3961
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003962def Test_opfunc()
Bram Moolenaar848fadd2022-01-30 15:28:30 +00003963 nnoremap <F3> <cmd>set opfunc=g:Opfunc<cr>g@
Bram Moolenaar5b3d1bb2020-12-22 12:20:08 +01003964 def g:Opfunc(_: any): string
3965 setline(1, 'ASDF')
3966 return ''
3967 enddef
3968 new
3969 setline(1, 'asdf')
3970 feedkeys("\<F3>$", 'x')
3971 assert_equal('ASDF', getline(1))
3972
3973 bwipe!
3974 nunmap <F3>
3975enddef
3976
Bram Moolenaar3b309f12021-12-13 18:19:55 +00003977func Test_opfunc_error()
3978 CheckScreendump
3979 call Run_Test_opfunc_error()
3980endfunc
3981
3982def Run_Test_opfunc_error()
3983 # test that the error from Opfunc() is displayed right away
3984 var lines =<< trim END
3985 vim9script
3986
3987 def Opfunc(type: string)
3988 try
3989 eval [][0]
3990 catch /nothing/ # error not caught
3991 endtry
3992 enddef
3993 &operatorfunc = Opfunc
3994 nnoremap <expr> l <SID>L()
3995 def L(): string
3996 return 'l'
3997 enddef
3998 'x'->repeat(10)->setline(1)
3999 feedkeys('g@l', 'n')
4000 feedkeys('llll')
4001 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004002 call writefile(lines, 'XTest_opfunc_error', 'D')
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004003
Bram Moolenaar62aec932022-01-29 21:45:34 +00004004 var buf = g:RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
4005 g:WaitForAssert(() => assert_match('Press ENTER', term_getline(buf, 6)))
Bram Moolenaarec892232022-05-06 17:53:06 +01004006 g:WaitForAssert(() => assert_match('E684: List index out of range: 0', term_getline(buf, 5)))
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004007
4008 # clean up
Bram Moolenaar62aec932022-01-29 21:45:34 +00004009 g:StopVimInTerminal(buf)
Bram Moolenaar3b309f12021-12-13 18:19:55 +00004010enddef
4011
Bram Moolenaar077a4232020-12-22 18:33:27 +01004012" this was crashing on exit
4013def Test_nested_lambda_in_closure()
4014 var lines =<< trim END
4015 vim9script
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004016 command WriteDone writefile(['Done'], 'XnestedDone')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004017 def Outer()
4018 def g:Inner()
4019 echo map([1, 2, 3], {_, v -> v + 1})
4020 enddef
4021 g:Inner()
4022 enddef
4023 defcompile
Bram Moolenaar227c58a2021-04-28 20:40:44 +02004024 # not reached
Bram Moolenaar077a4232020-12-22 18:33:27 +01004025 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004026 if !g:RunVim([], lines, '--clean -c WriteDone -c quit')
Bram Moolenaar077a4232020-12-22 18:33:27 +01004027 return
4028 endif
4029 assert_equal(['Done'], readfile('XnestedDone'))
4030 delete('XnestedDone')
4031enddef
4032
Bram Moolenaar92368aa2022-02-07 17:50:39 +00004033def Test_nested_closure_funcref()
4034 var lines =<< trim END
4035 vim9script
4036 def Func()
4037 var n: number
4038 def Nested()
4039 ++n
4040 enddef
4041 Nested()
4042 g:result_one = n
4043 var Ref = function(Nested)
4044 Ref()
4045 g:result_two = n
4046 enddef
4047 Func()
4048 END
4049 v9.CheckScriptSuccess(lines)
4050 assert_equal(1, g:result_one)
4051 assert_equal(2, g:result_two)
4052 unlet g:result_one g:result_two
4053enddef
4054
Bram Moolenaar7aca5ca2022-02-07 19:56:43 +00004055def Test_nested_closure_in_dict()
4056 var lines =<< trim END
4057 vim9script
4058 def Func(): dict<any>
4059 var n: number
4060 def Inc(): number
4061 ++n
4062 return n
4063 enddef
4064 return {inc: function(Inc)}
4065 enddef
4066 disas Func
4067 var d = Func()
4068 assert_equal(1, d.inc())
4069 assert_equal(2, d.inc())
4070 END
4071 v9.CheckScriptSuccess(lines)
4072enddef
4073
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004074def Test_script_local_other_script()
4075 var lines =<< trim END
4076 function LegacyJob()
4077 let FuncRef = function('s:close_cb')
4078 endfunction
4079 function s:close_cb(...)
4080 endfunction
4081 END
Bram Moolenaarf5fec052022-09-11 11:49:22 +01004082 lines->writefile('Xlegacy.vim', 'D')
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004083 source Xlegacy.vim
4084 g:LegacyJob()
4085 g:LegacyJob()
4086 g:LegacyJob()
4087
4088 delfunc g:LegacyJob
Bram Moolenaarfb43cfc2022-03-11 18:54:17 +00004089enddef
4090
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004091def Test_check_func_arg_types()
4092 var lines =<< trim END
4093 vim9script
4094 def F1(x: string): string
4095 return x
4096 enddef
4097
4098 def F2(x: number): number
4099 return x + 1
4100 enddef
4101
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004102 def G(Fg: func): dict<func>
4103 return {f: Fg}
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004104 enddef
4105
4106 def H(d: dict<func>): string
4107 return d.f('a')
4108 enddef
4109 END
4110
Bram Moolenaar62aec932022-01-29 21:45:34 +00004111 v9.CheckScriptSuccess(lines + ['echo H(G(F1))'])
4112 v9.CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
Bram Moolenaar1d9cef72022-03-17 16:30:03 +00004113
4114 v9.CheckScriptFailure(lines + ['def SomeFunc(ff: func)', 'enddef'], 'E704:')
Bram Moolenaar04947cc2021-03-06 19:26:46 +01004115enddef
4116
Bram Moolenaarbadf04f2022-03-12 21:28:22 +00004117def Test_call_func_with_null()
4118 var lines =<< trim END
4119 def Fstring(v: string)
4120 assert_equal(null_string, v)
4121 enddef
4122 Fstring(null_string)
4123 def Fblob(v: blob)
4124 assert_equal(null_blob, v)
4125 enddef
4126 Fblob(null_blob)
4127 def Flist(v: list<number>)
4128 assert_equal(null_list, v)
4129 enddef
4130 Flist(null_list)
4131 def Fdict(v: dict<number>)
4132 assert_equal(null_dict, v)
4133 enddef
4134 Fdict(null_dict)
4135 def Ffunc(Fv: func(number): number)
4136 assert_equal(null_function, Fv)
4137 enddef
4138 Ffunc(null_function)
4139 if has('channel')
4140 def Fchannel(v: channel)
4141 assert_equal(null_channel, v)
4142 enddef
4143 Fchannel(null_channel)
4144 def Fjob(v: job)
4145 assert_equal(null_job, v)
4146 enddef
4147 Fjob(null_job)
4148 endif
4149 END
4150 v9.CheckDefAndScriptSuccess(lines)
4151enddef
4152
4153def Test_null_default_argument()
4154 var lines =<< trim END
4155 def Fstring(v: string = null_string)
4156 assert_equal(null_string, v)
4157 enddef
4158 Fstring()
4159 def Fblob(v: blob = null_blob)
4160 assert_equal(null_blob, v)
4161 enddef
4162 Fblob()
4163 def Flist(v: list<number> = null_list)
4164 assert_equal(null_list, v)
4165 enddef
4166 Flist()
4167 def Fdict(v: dict<number> = null_dict)
4168 assert_equal(null_dict, v)
4169 enddef
4170 Fdict()
4171 def Ffunc(Fv: func(number): number = null_function)
4172 assert_equal(null_function, Fv)
4173 enddef
4174 Ffunc()
4175 if has('channel')
4176 def Fchannel(v: channel = null_channel)
4177 assert_equal(null_channel, v)
4178 enddef
4179 Fchannel()
4180 def Fjob(v: job = null_job)
4181 assert_equal(null_job, v)
4182 enddef
4183 Fjob()
4184 endif
4185 END
4186 v9.CheckDefAndScriptSuccess(lines)
4187enddef
4188
4189def Test_null_return()
4190 var lines =<< trim END
4191 def Fstring(): string
4192 return null_string
4193 enddef
4194 assert_equal(null_string, Fstring())
4195 def Fblob(): blob
4196 return null_blob
4197 enddef
4198 assert_equal(null_blob, Fblob())
4199 def Flist(): list<number>
4200 return null_list
4201 enddef
4202 assert_equal(null_list, Flist())
4203 def Fdict(): dict<number>
4204 return null_dict
4205 enddef
4206 assert_equal(null_dict, Fdict())
4207 def Ffunc(): func(number): number
4208 return null_function
4209 enddef
4210 assert_equal(null_function, Ffunc())
4211 if has('channel')
4212 def Fchannel(): channel
4213 return null_channel
4214 enddef
4215 assert_equal(null_channel, Fchannel())
4216 def Fjob(): job
4217 return null_job
4218 enddef
4219 assert_equal(null_job, Fjob())
4220 endif
4221 END
4222 v9.CheckDefAndScriptSuccess(lines)
4223enddef
4224
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004225def Test_list_any_type_checked()
4226 var lines =<< trim END
4227 vim9script
4228 def Foo()
4229 --decl--
4230 Bar(l)
4231 enddef
4232 def Bar(ll: list<dict<any>>)
4233 enddef
4234 Foo()
4235 END
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004236 # "any" could be "dict<any>", thus OK
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004237 lines[2] = 'var l: list<any>'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004238 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004239 lines[2] = 'var l: list<any> = []'
Bram Moolenaar2d3ac2e2022-02-03 12:34:05 +00004240 v9.CheckScriptSuccess(lines)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004241
4242 lines[2] = 'var l: list<any> = [11]'
Bram Moolenaar62aec932022-01-29 21:45:34 +00004243 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
Bram Moolenaar6e48b842021-08-10 22:52:02 +02004244enddef
4245
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004246def Test_compile_error()
4247 var lines =<< trim END
4248 def g:Broken()
4249 echo 'a' + {}
4250 enddef
4251 call g:Broken()
4252 END
4253 # First call: compilation error
Bram Moolenaar62aec932022-01-29 21:45:34 +00004254 v9.CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004255
4256 # Second call won't try compiling again
4257 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
Bram Moolenaar599410c2021-04-10 14:03:43 +02004258 delfunc g:Broken
4259
4260 # No error when compiling with :silent!
4261 lines =<< trim END
4262 def g:Broken()
4263 echo 'a' + []
4264 enddef
4265 silent! defcompile
4266 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004267 v9.CheckScriptSuccess(lines)
Bram Moolenaar599410c2021-04-10 14:03:43 +02004268
4269 # Calling the function won't try compiling again
4270 assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
4271 delfunc g:Broken
Bram Moolenaar701cc6c2021-04-10 13:33:48 +02004272enddef
4273
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004274def Test_ignored_argument()
4275 var lines =<< trim END
4276 vim9script
4277 def Ignore(_, _): string
4278 return 'yes'
4279 enddef
4280 assert_equal('yes', Ignore(1, 2))
4281
4282 func Ok(_)
4283 return a:_
4284 endfunc
4285 assert_equal('ok', Ok('ok'))
4286
4287 func Oktoo()
4288 let _ = 'too'
4289 return _
4290 endfunc
4291 assert_equal('too', Oktoo())
Bram Moolenaarda479c72021-04-10 21:01:38 +02004292
4293 assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004294 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004295 v9.CheckScriptSuccess(lines)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004296
4297 lines =<< trim END
4298 def Ignore(_: string): string
4299 return _
4300 enddef
4301 defcompile
4302 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004303 v9.CheckScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004304
4305 lines =<< trim END
4306 var _ = 1
4307 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004308 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Yegappan Lakshmanan34fcb692021-05-25 20:14:00 +02004309
4310 lines =<< trim END
4311 var x = _
4312 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004313 v9.CheckDefAndScriptFailure(lines, 'E1181:', 1)
Bram Moolenaar962c43b2021-04-10 17:18:09 +02004314enddef
4315
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004316def Test_too_many_arguments()
4317 var lines =<< trim END
4318 echo [0, 1, 2]->map(() => 123)
4319 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004320 v9.CheckDefAndScriptFailure(lines, ['E176:', 'E1106: 2 arguments too many'], 1)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004321
4322 lines =<< trim END
4323 echo [0, 1, 2]->map((_) => 123)
4324 END
Bram Moolenaareddd4fc2022-02-20 15:52:28 +00004325 v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
Bram Moolenaar31d99482022-05-26 22:24:43 +01004326
4327 lines =<< trim END
4328 vim9script
4329 def OneArgument(arg: string)
4330 echo arg
4331 enddef
4332 var Ref = OneArgument
4333 Ref('a', 'b')
4334 END
4335 v9.CheckScriptFailure(lines, 'E118:')
4336enddef
4337
4338def Test_funcref_with_base()
4339 var lines =<< trim END
4340 vim9script
4341 def TwoArguments(str: string, nr: number)
4342 echo str nr
4343 enddef
4344 var Ref = TwoArguments
4345 Ref('a', 12)
4346 'b'->Ref(34)
4347 END
4348 v9.CheckScriptSuccess(lines)
4349
4350 lines =<< trim END
4351 vim9script
4352 def TwoArguments(str: string, nr: number)
4353 echo str nr
4354 enddef
4355 var Ref = TwoArguments
4356 'a'->Ref('b')
4357 END
4358 v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
4359
4360 lines =<< trim END
4361 vim9script
4362 def TwoArguments(str: string, nr: number)
4363 echo str nr
4364 enddef
4365 var Ref = TwoArguments
4366 123->Ref(456)
4367 END
4368 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
4369
4370 lines =<< trim END
4371 vim9script
4372 def TwoArguments(nr: number, str: string)
4373 echo str nr
4374 enddef
4375 var Ref = TwoArguments
4376 123->Ref('b')
4377 def AndNowCompiled()
4378 456->Ref('x')
4379 enddef
4380 AndNowCompiled()
4381 END
4382 v9.CheckScriptSuccess(lines)
Bram Moolenaarbb8a7ce2021-04-10 20:10:26 +02004383enddef
Bram Moolenaar077a4232020-12-22 18:33:27 +01004384
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004385def Test_closing_brace_at_start_of_line()
4386 var lines =<< trim END
4387 def Func()
4388 enddef
4389 Func(
4390 )
4391 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004392 v9.CheckDefAndScriptSuccess(lines)
Bram Moolenaara6aa1642021-04-23 19:32:23 +02004393enddef
4394
Bram Moolenaar62aec932022-01-29 21:45:34 +00004395func s:CreateMydict()
Bram Moolenaarb033ee22021-08-15 16:08:36 +02004396 let g:mydict = {}
4397 func g:mydict.afunc()
4398 let g:result = self.key
4399 endfunc
4400endfunc
4401
4402def Test_numbered_function_reference()
4403 CreateMydict()
4404 var output = execute('legacy func g:mydict.afunc')
4405 var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
4406 execute 'function(' .. funcName .. ', [], {key: 42})()'
4407 # check that the function still exists
4408 assert_equal(output, execute('legacy func g:mydict.afunc'))
4409 unlet g:mydict
4410enddef
4411
Bram Moolenaarcfb4d4f2022-09-30 19:19:04 +01004412def Test_numbered_function_call()
4413 var lines =<< trim END
4414 let s:legacyscript = {}
4415 func s:legacyscript.Helper() abort
4416 return "Success"
4417 endfunc
4418 let g:legacyscript = deepcopy(s:legacyscript)
4419
4420 let g:legacy_result = eval("g:legacyscript.Helper()")
4421 vim9cmd g:vim9_result = eval("g:legacyscript.Helper()")
4422 END
4423 v9.CheckScriptSuccess(lines)
4424 assert_equal('Success', g:legacy_result)
4425 assert_equal('Success', g:vim9_result)
4426
4427 unlet g:legacy_result
4428 unlet g:vim9_result
4429enddef
4430
Bram Moolenaard3a11782022-01-05 16:50:40 +00004431def Test_go_beyond_end_of_cmd()
4432 # this was reading the byte after the end of the line
4433 var lines =<< trim END
4434 def F()
4435 cal
4436 enddef
4437 defcompile
4438 END
Bram Moolenaar62aec932022-01-29 21:45:34 +00004439 v9.CheckScriptFailure(lines, 'E476:')
Bram Moolenaard3a11782022-01-05 16:50:40 +00004440enddef
4441
Yegappan Lakshmanan7c7e19c2022-04-09 11:09:07 +01004442" Test for memory allocation failure when defining a new lambda
4443func Test_lambda_allocation_failure()
4444 new
4445 let lines =<< trim END
4446 vim9script
4447 g:Xlambda = (x): number => {
4448 return x + 1
4449 }
4450 END
4451 call setline(1, lines)
4452 call test_alloc_fail(GetAllocId('get_func'), 0, 0)
4453 call assert_fails('source', 'E342:')
4454 call assert_false(exists('g:Xlambda'))
4455 bw!
4456endfunc
4457
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004458def Test_lambda_argument_type_check()
4459 var lines =<< trim END
4460 vim9script
4461
4462 def Scan(ll: list<any>): func(func(any))
4463 return (Emit: func(any)) => {
4464 for e in ll
4465 Emit(e)
4466 endfor
4467 }
4468 enddef
4469
4470 def Sum(Cont: func(func(any))): any
4471 var sum = 0.0
4472 Cont((v: float) => { # <== NOTE: the lambda expects a float
4473 sum += v
4474 })
4475 return sum
4476 enddef
4477
Bram Moolenaar47bba532023-01-20 18:49:46 +00004478 const ml = [3.0, 2, '7']
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004479 echo Scan(ml)->Sum()
4480 END
Bram Moolenaar47bba532023-01-20 18:49:46 +00004481 v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string')
Bram Moolenaar0d89d8a2022-12-31 14:01:24 +00004482enddef
4483
Bram Moolenaarbce69d62022-05-22 13:45:52 +01004484def Test_multiple_funcref()
4485 # This was using a NULL pointer
4486 var lines =<< trim END
4487 vim9script
4488 def A(F: func, ...args: list<any>): func
4489 return funcref(F, args)
4490 enddef
4491
4492 def B(F: func): func
4493 return funcref(A, [F])
4494 enddef
4495
4496 def Test(n: number)
4497 enddef
4498
4499 const X = B(Test)
4500 X(1)
4501 END
4502 v9.CheckScriptSuccess(lines)
4503
4504 # slightly different case
4505 lines =<< trim END
4506 vim9script
4507
4508 def A(F: func, ...args: list<any>): any
4509 return call(F, args)
4510 enddef
4511
4512 def B(F: func): func
4513 return funcref(A, [F])
4514 enddef
4515
4516 def Test(n: number)
4517 enddef
4518
4519 const X = B(Test)
4520 X(1)
4521 END
4522 v9.CheckScriptSuccess(lines)
4523enddef
4524
Bram Moolenaarbd683e32022-07-18 17:49:03 +01004525def Test_cexpr_errmsg_line_number()
4526 var lines =<< trim END
4527 vim9script
4528 def Func()
4529 var qfl = {}
4530 cexpr qfl
4531 enddef
4532 Func()
4533 END
4534 v9.CheckScriptFailure(lines, 'E777', 2)
4535enddef
4536
Bram Moolenaar1d84f762022-09-03 21:35:53 +01004537def AddDefer(s: string)
4538 g:deferred->extend([s])
4539enddef
4540
4541def DeferTwo()
4542 g:deferred->extend(['in Two'])
4543 for n in range(3)
4544 defer g:AddDefer('two' .. n)
4545 endfor
4546 g:deferred->extend(['end Two'])
4547enddef
4548
4549def DeferOne()
4550 g:deferred->extend(['in One'])
4551 defer g:AddDefer('one')
4552 g:DeferTwo()
4553 g:deferred->extend(['end One'])
4554
4555 writefile(['text'], 'XdeferFile')
4556 defer delete('XdeferFile')
4557enddef
4558
4559def Test_defer()
4560 g:deferred = []
4561 g:DeferOne()
4562 assert_equal(['in One', 'in Two', 'end Two', 'two2', 'two1', 'two0', 'end One', 'one'], g:deferred)
4563 unlet g:deferred
4564 assert_equal('', glob('XdeferFile'))
4565enddef
4566
Bram Moolenaar3558afe2022-10-13 16:12:57 +01004567def Test_invalid_redir()
4568 var lines =<< trim END
4569 def Tone()
4570 if 1
4571 redi =>@�0
4572 redi END
4573 endif
4574 enddef
4575 defcompile
4576 END
4577 v9.CheckScriptFailure(lines, 'E354:')
4578 delfunc g:Tone
4579
4580 # this was reading past the end of the line
4581 lines =<< trim END
4582 def Ttwo()
4583 if 0
4584 redi =>@�0
4585 redi END
4586 endif
4587 enddef
4588 defcompile
4589 END
4590 v9.CheckScriptFailure(lines, 'E354:')
4591 delfunc g:Ttwo
4592enddef
4593
Bram Moolenaar39c82ea2023-01-02 13:08:01 +00004594func Test_keytyped_in_nested_function()
4595 CheckRunVimInTerminal
4596
4597 call Run_Test_keytyped_in_nested_function()
4598endfunc
4599
4600def Run_Test_keytyped_in_nested_function()
4601 var lines =<< trim END
4602 vim9script
4603 autocmd CmdlineEnter * sample#Init()
4604
4605 exe 'set rtp=' .. getcwd() .. '/Xrtpdir'
4606 END
4607 writefile(lines, 'Xkeytyped', 'D')
4608
4609 var dir = 'Xrtpdir/autoload'
4610 mkdir(dir, 'pR')
4611
4612 lines =<< trim END
4613 vim9script
4614 export def Init(): void
4615 cnoremap <expr>" <SID>Quote('"')
4616 enddef
4617 def Quote(str: string): string
4618 def InPair(): number
4619 return 0
4620 enddef
4621 return str
4622 enddef
4623 END
4624 writefile(lines, dir .. '/sample.vim')
4625
4626 var buf = g:RunVimInTerminal('-S Xkeytyped', {rows: 6})
4627
4628 term_sendkeys(buf, ':"')
4629 g:VerifyScreenDump(buf, 'Test_keytyped_in_nested_func', {})
4630
4631 # clean up
4632 term_sendkeys(buf, "\<Esc>")
4633 g:StopVimInTerminal(buf)
4634enddef
4635
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004636" The following messes up syntax highlight, keep near the end.
Bram Moolenaar20677332021-06-06 17:02:53 +02004637if has('python3')
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004638 def Test_python3_command()
4639 py3 import vim
Bram Moolenaarf5288c52022-02-15 21:33:29 +00004640 py3 vim.command("g:done = 'yes'")
Bram Moolenaar8b716f52022-02-15 21:17:56 +00004641 assert_equal('yes', g:done)
4642 unlet g:done
4643 enddef
4644
Bram Moolenaar20677332021-06-06 17:02:53 +02004645 def Test_python3_heredoc()
4646 py3 << trim EOF
4647 import vim
4648 vim.vars['didit'] = 'yes'
4649 EOF
4650 assert_equal('yes', g:didit)
4651
4652 python3 << trim EOF
4653 import vim
4654 vim.vars['didit'] = 'again'
4655 EOF
4656 assert_equal('again', g:didit)
4657 enddef
4658endif
4659
Bram Moolenaar20677332021-06-06 17:02:53 +02004660if has('lua')
4661 def Test_lua_heredoc()
4662 g:d = {}
4663 lua << trim EOF
4664 x = vim.eval('g:d')
4665 x['key'] = 'val'
4666 EOF
4667 assert_equal('val', g:d.key)
4668 enddef
Bram Moolenaarefd73ae2022-03-20 18:51:00 +00004669
4670 def Test_lua_heredoc_fails()
4671 var lines = [
4672 'vim9script',
4673 'def ExeLua()',
4674 'lua << trim EOLUA',
4675 "x = vim.eval('g:nodict')",
4676 'EOLUA',
4677 'enddef',
4678 'ExeLua()',
4679 ]
4680 v9.CheckScriptFailure(lines, 'E121: Undefined variable: g:nodict')
4681 enddef
Bram Moolenaar20677332021-06-06 17:02:53 +02004682endif
4683
Bram Moolenaard881d152022-05-13 13:50:36 +01004684if has('perl')
4685 def Test_perl_heredoc_nested()
4686 var lines =<< trim END
4687 vim9script
4688 def F(): string
4689 def G(): string
4690 perl << EOF
4691 EOF
4692 return 'done'
4693 enddef
4694 return G()
4695 enddef
4696 assert_equal('done', F())
4697 END
4698 v9.CheckScriptSuccess(lines)
4699 enddef
4700endif
4701
Bram Moolenaarf7779c62020-05-03 15:38:16 +02004702
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02004703" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker