1" Test various aspects of the Vim9 script language.
2
3source check.vim
4source term_util.vim
5source view_util.vim
6source vim9.vim
7source screendump.vim
8
9func Test_def_basic()
10  def SomeFunc(): string
11    return 'yes'
12  enddef
13  call SomeFunc()->assert_equal('yes')
14endfunc
15
16func Test_compiling_error()
17  " use a terminal to see the whole error message
18  CheckRunVimInTerminal
19
20  call TestCompilingError()
21endfunc
22
23def TestCompilingError()
24  var lines =<< trim END
25    vim9script
26    def Fails()
27      echo nothing
28    enddef
29    defcompile
30  END
31  call writefile(lines, 'XTest_compile_error')
32  var buf = RunVimInTerminal('-S XTest_compile_error',
33              {rows: 10, wait_for_ruler: 0})
34  call WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
35                     Term_getlines(buf, range(1, 9))))
36
37  # clean up
38  call StopVimInTerminal(buf)
39  call delete('XTest_compile_error')
40enddef
41
42def CallRecursive(n: number): number
43  return CallRecursive(n + 1)
44enddef
45
46def CallMapRecursive(l: list<number>): number
47  return map(l, (_, v) => CallMapRecursive([v]))[0]
48enddef
49
50def Test_funcdepth_error()
51  set maxfuncdepth=10
52
53  var caught = false
54  try
55    CallRecursive(1)
56  catch /E132:/
57    caught = true
58  endtry
59  assert_true(caught)
60
61  caught = false
62  try
63    CallMapRecursive([1])
64  catch /E132:/
65    caught = true
66  endtry
67  assert_true(caught)
68
69  set maxfuncdepth&
70enddef
71
72def Test_endfunc_enddef()
73  var lines =<< trim END
74    def Test()
75      echo 'test'
76      endfunc
77    enddef
78  END
79  CheckScriptFailure(lines, 'E1151:', 3)
80
81  lines =<< trim END
82    def Test()
83      func Nested()
84        echo 'test'
85      enddef
86    enddef
87  END
88  CheckScriptFailure(lines, 'E1152:', 4)
89
90  lines =<< trim END
91    def Ok()
92      echo 'hello'
93    enddef | echo 'there'
94    def Bad()
95      echo 'hello'
96    enddef there
97  END
98  CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
99enddef
100
101def Test_missing_endfunc_enddef()
102  var lines =<< trim END
103    vim9script
104    def Test()
105      echo 'test'
106    endef
107  END
108  CheckScriptFailure(lines, 'E1057:', 2)
109
110  lines =<< trim END
111    vim9script
112    func Some()
113      echo 'test'
114    enfffunc
115  END
116  CheckScriptFailure(lines, 'E126:', 2)
117enddef
118
119def Test_white_space_before_paren()
120  var lines =<< trim END
121    vim9script
122    def Test ()
123      echo 'test'
124    enddef
125  END
126  CheckScriptFailure(lines, 'E1068:', 2)
127
128  lines =<< trim END
129    vim9script
130    func Test ()
131      echo 'test'
132    endfunc
133  END
134  CheckScriptFailure(lines, 'E1068:', 2)
135
136  lines =<< trim END
137    def Test ()
138      echo 'test'
139    enddef
140  END
141  CheckScriptFailure(lines, 'E1068:', 1)
142
143  lines =<< trim END
144    func Test ()
145      echo 'test'
146    endfunc
147  END
148  CheckScriptSuccess(lines)
149enddef
150
151def Test_enddef_dict_key()
152  var d = {
153    enddef: 'x',
154    endfunc: 'y',
155  }
156  assert_equal({enddef: 'x', endfunc: 'y'}, d)
157enddef
158
159def ReturnString(): string
160  return 'string'
161enddef
162
163def ReturnNumber(): number
164  return 123
165enddef
166
167let g:notNumber = 'string'
168
169def ReturnGlobal(): number
170  return g:notNumber
171enddef
172
173def Test_return_something()
174  ReturnString()->assert_equal('string')
175  ReturnNumber()->assert_equal(123)
176  assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
177enddef
178
179def Test_check_argument_type()
180  var lines =<< trim END
181      vim9script
182      def Val(a: number, b: number): number
183        return 0
184      enddef
185      def Func()
186        var x: any = true
187        Val(0, x)
188      enddef
189      disass Func
190      Func()
191  END
192  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
193enddef
194
195def Test_missing_return()
196  CheckDefFailure(['def Missing(): number',
197                   '  if g:cond',
198                   '    echo "no return"',
199                   '  else',
200                   '    return 0',
201                   '  endif'
202                   'enddef'], 'E1027:')
203  CheckDefFailure(['def Missing(): number',
204                   '  if g:cond',
205                   '    return 1',
206                   '  else',
207                   '    echo "no return"',
208                   '  endif'
209                   'enddef'], 'E1027:')
210  CheckDefFailure(['def Missing(): number',
211                   '  if g:cond',
212                   '    return 1',
213                   '  else',
214                   '    return 2',
215                   '  endif'
216                   '  return 3'
217                   'enddef'], 'E1095:')
218enddef
219
220def Test_return_bool()
221  var lines =<< trim END
222      vim9script
223      def MenuFilter(id: number, key: string): bool
224        return popup_filter_menu(id, key)
225      enddef
226      def YesnoFilter(id: number, key: string): bool
227        return popup_filter_yesno(id, key)
228      enddef
229      defcompile
230  END
231  CheckScriptSuccess(lines)
232enddef
233
234let s:nothing = 0
235def ReturnNothing()
236  s:nothing = 1
237  if true
238    return
239  endif
240  s:nothing = 2
241enddef
242
243def Test_return_nothing()
244  ReturnNothing()
245  s:nothing->assert_equal(1)
246enddef
247
248def Test_return_invalid()
249  var lines =<< trim END
250    vim9script
251    def Func(): invalid
252      return xxx
253    enddef
254    defcompile
255  END
256  CheckScriptFailure(lines, 'E1010:', 2)
257
258  lines =<< trim END
259      vim9script
260      def Test(Fun: func(number): number): list<number>
261          return map([1, 2, 3], (_, i) => Fun(i))
262      enddef
263      defcompile
264      def Inc(nr: number): nr
265        return nr + 2
266      enddef
267      echo Test(Inc)
268  END
269  # doing this twice was leaking memory
270  CheckScriptFailure(lines, 'E1010:')
271  CheckScriptFailure(lines, 'E1010:')
272enddef
273
274func Increment()
275  let g:counter += 1
276endfunc
277
278def Test_call_ufunc_count()
279  g:counter = 1
280  Increment()
281  Increment()
282  Increment()
283  # works with and without :call
284  g:counter->assert_equal(4)
285  eval g:counter->assert_equal(4)
286  unlet g:counter
287enddef
288
289def MyVarargs(arg: string, ...rest: list<string>): string
290  var res = arg
291  for s in rest
292    res ..= ',' .. s
293  endfor
294  return res
295enddef
296
297def Test_call_varargs()
298  MyVarargs('one')->assert_equal('one')
299  MyVarargs('one', 'two')->assert_equal('one,two')
300  MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
301enddef
302
303def MyDefaultArgs(name = 'string'): string
304  return name
305enddef
306
307def MyDefaultSecond(name: string, second: bool  = true): string
308  return second ? name : 'none'
309enddef
310
311
312def Test_call_default_args()
313  MyDefaultArgs()->assert_equal('string')
314  MyDefaultArgs(v:none)->assert_equal('string')
315  MyDefaultArgs('one')->assert_equal('one')
316  assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
317
318  MyDefaultSecond('test')->assert_equal('test')
319  MyDefaultSecond('test', true)->assert_equal('test')
320  MyDefaultSecond('test', false)->assert_equal('none')
321
322  var lines =<< trim END
323      def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
324        return name .. aa .. bb
325      enddef
326
327      MyDefaultThird('->')->assert_equal('->aabb')
328      MyDefaultThird('->', v:none)->assert_equal('->aabb')
329      MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
330      MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
331      MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
332      MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
333      MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
334  END
335  CheckDefAndScriptSuccess(lines)
336
337  CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
338  delfunc g:Func
339  CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
340  delfunc g:Func
341
342  lines =<< trim END
343      vim9script
344      def Func(a = b == 0 ? 1 : 2, b = 0)
345      enddef
346      defcompile
347  END
348  CheckScriptFailure(lines, 'E1001: Variable not found: b')
349enddef
350
351def FuncWithComment(  # comment
352  a: number, #comment
353  b: bool, # comment
354  c: string) #comment
355  assert_equal(4, a)
356  assert_equal(true, b)
357  assert_equal('yes', c)
358enddef
359
360def Test_func_with_comments()
361  FuncWithComment(4, true, 'yes')
362
363  var lines =<< trim END
364      def Func(# comment
365        arg: string)
366      enddef
367  END
368  CheckScriptFailure(lines, 'E125:', 1)
369
370  lines =<< trim END
371      def Func(
372        arg: string# comment
373        )
374      enddef
375  END
376  CheckScriptFailure(lines, 'E475:', 2)
377
378  lines =<< trim END
379      def Func(
380        arg: string
381        )# comment
382      enddef
383  END
384  CheckScriptFailure(lines, 'E488:', 3)
385enddef
386
387def Test_nested_function()
388  def Nested(arg: string): string
389    return 'nested ' .. arg
390  enddef
391  Nested('function')->assert_equal('nested function')
392
393  CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
394  CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
395
396  CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
397  CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
398  CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
399
400  var lines =<< trim END
401      def Outer()
402        def Inner()
403          # comment
404        enddef
405        def Inner()
406        enddef
407      enddef
408  END
409  CheckDefFailure(lines, 'E1073:')
410
411  lines =<< trim END
412      def Outer()
413        def Inner()
414          # comment
415        enddef
416        def! Inner()
417        enddef
418      enddef
419  END
420  CheckDefFailure(lines, 'E1117:')
421
422  # nested function inside conditional
423  lines =<< trim END
424      vim9script
425      var thecount = 0
426      if true
427        def Test(): number
428          def TheFunc(): number
429            thecount += 1
430            return thecount
431          enddef
432          return TheFunc()
433        enddef
434      endif
435      defcompile
436      assert_equal(1, Test())
437      assert_equal(2, Test())
438  END
439  CheckScriptSuccess(lines)
440
441  # also works when "thecount" is inside the "if" block
442  lines =<< trim END
443      vim9script
444      if true
445        var thecount = 0
446        def Test(): number
447          def TheFunc(): number
448            thecount += 1
449            return thecount
450          enddef
451          return TheFunc()
452        enddef
453      endif
454      defcompile
455      assert_equal(1, Test())
456      assert_equal(2, Test())
457  END
458  CheckScriptSuccess(lines)
459enddef
460
461def Test_not_nested_function()
462  echo printf('%d',
463      function('len')('xxx'))
464enddef
465
466func Test_call_default_args_from_func()
467  call MyDefaultArgs()->assert_equal('string')
468  call MyDefaultArgs('one')->assert_equal('one')
469  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
470endfunc
471
472def Test_nested_global_function()
473  var lines =<< trim END
474      vim9script
475      def Outer()
476          def g:Inner(): string
477              return 'inner'
478          enddef
479      enddef
480      defcompile
481      Outer()
482      g:Inner()->assert_equal('inner')
483      delfunc g:Inner
484      Outer()
485      g:Inner()->assert_equal('inner')
486      delfunc g:Inner
487      Outer()
488      g:Inner()->assert_equal('inner')
489      delfunc g:Inner
490  END
491  CheckScriptSuccess(lines)
492
493  lines =<< trim END
494      vim9script
495      def Outer()
496          def g:Inner(): string
497              return 'inner'
498          enddef
499      enddef
500      defcompile
501      Outer()
502      Outer()
503  END
504  CheckScriptFailure(lines, "E122:")
505  delfunc g:Inner
506
507  lines =<< trim END
508      vim9script
509      def Outer()
510        def g:Inner()
511          echo map([1, 2, 3], (_, v) => v + 1)
512        enddef
513        g:Inner()
514      enddef
515      Outer()
516  END
517  CheckScriptSuccess(lines)
518  delfunc g:Inner
519
520  lines =<< trim END
521      vim9script
522      def Func()
523        echo 'script'
524      enddef
525      def Outer()
526        def Func()
527          echo 'inner'
528        enddef
529      enddef
530      defcompile
531  END
532  CheckScriptFailure(lines, "E1073:")
533enddef
534
535def DefListAll()
536  def
537enddef
538
539def DefListOne()
540  def DefListOne
541enddef
542
543def DefListMatches()
544  def /DefList
545enddef
546
547def Test_nested_def_list()
548  var funcs = split(execute('call DefListAll()'), "\n")
549  assert_true(len(funcs) > 10)
550  assert_true(funcs->index('def DefListAll()') >= 0)
551
552  funcs = split(execute('call DefListOne()'), "\n")
553  assert_equal(['   def DefListOne()', '1    def DefListOne', '   enddef'], funcs)
554
555  funcs = split(execute('call DefListMatches()'), "\n")
556  assert_true(len(funcs) >= 3)
557  assert_true(funcs->index('def DefListAll()') >= 0)
558  assert_true(funcs->index('def DefListOne()') >= 0)
559  assert_true(funcs->index('def DefListMatches()') >= 0)
560
561  var lines =<< trim END
562    vim9script
563    def Func()
564      def +Func+
565    enddef
566    defcompile
567  END
568  CheckScriptFailure(lines, 'E476:', 1)
569enddef
570
571def Test_global_local_function()
572  var lines =<< trim END
573      vim9script
574      def g:Func(): string
575          return 'global'
576      enddef
577      def Func(): string
578          return 'local'
579      enddef
580      g:Func()->assert_equal('global')
581      Func()->assert_equal('local')
582      delfunc g:Func
583  END
584  CheckScriptSuccess(lines)
585
586  lines =<< trim END
587      vim9script
588      def g:Funcy()
589        echo 'funcy'
590      enddef
591      s:Funcy()
592  END
593  CheckScriptFailure(lines, 'E117:')
594enddef
595
596def Test_local_function_shadows_global()
597  var lines =<< trim END
598      vim9script
599      def g:Gfunc(): string
600        return 'global'
601      enddef
602      def AnotherFunc(): number
603        var Gfunc = function('len')
604        return Gfunc('testing')
605      enddef
606      g:Gfunc()->assert_equal('global')
607      AnotherFunc()->assert_equal(7)
608      delfunc g:Gfunc
609  END
610  CheckScriptSuccess(lines)
611
612  lines =<< trim END
613      vim9script
614      def g:Func(): string
615        return 'global'
616      enddef
617      def AnotherFunc()
618        g:Func = function('len')
619      enddef
620      AnotherFunc()
621  END
622  CheckScriptFailure(lines, 'E705:')
623  delfunc g:Func
624enddef
625
626func TakesOneArg(arg)
627  echo a:arg
628endfunc
629
630def Test_call_wrong_args()
631  CheckDefFailure(['TakesOneArg()'], 'E119:')
632  CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
633  CheckDefFailure(['bufnr(xxx)'], 'E1001:')
634  CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
635
636  var lines =<< trim END
637    vim9script
638    def Func(s: string)
639      echo s
640    enddef
641    Func([])
642  END
643  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
644
645  lines =<< trim END
646    vim9script
647    var name = 'piet'
648    def FuncOne(name: string)
649      echo nr
650    enddef
651  END
652  CheckScriptFailure(lines, 'E1168:')
653
654  lines =<< trim END
655    vim9script
656    def FuncOne(nr: number)
657      echo nr
658    enddef
659    def FuncTwo()
660      FuncOne()
661    enddef
662    defcompile
663  END
664  writefile(lines, 'Xscript')
665  var didCatch = false
666  try
667    source Xscript
668  catch
669    assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
670    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
671    didCatch = true
672  endtry
673  assert_true(didCatch)
674
675  lines =<< trim END
676    vim9script
677    def FuncOne(nr: number)
678      echo nr
679    enddef
680    def FuncTwo()
681      FuncOne(1, 2)
682    enddef
683    defcompile
684  END
685  writefile(lines, 'Xscript')
686  didCatch = false
687  try
688    source Xscript
689  catch
690    assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
691    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
692    didCatch = true
693  endtry
694  assert_true(didCatch)
695
696  delete('Xscript')
697enddef
698
699def Test_call_funcref_wrong_args()
700  var head =<< trim END
701      vim9script
702      def Func3(a1: string, a2: number, a3: list<number>)
703        echo a1 .. a2 .. a3[0]
704      enddef
705      def Testme()
706        var funcMap: dict<func> = {func: Func3}
707  END
708  var tail =<< trim END
709      enddef
710      Testme()
711  END
712  CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
713
714  CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
715  CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
716
717  var lines =<< trim END
718      vim9script
719      var Ref: func(number): any
720      Ref = (j) => !j
721      echo Ref(false)
722  END
723  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
724
725  lines =<< trim END
726      vim9script
727      var Ref: func(number): any
728      Ref = (j) => !j
729      call Ref(false)
730  END
731  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
732enddef
733
734def Test_call_lambda_args()
735  CheckDefFailure(['echo ((i) => 0)()'],
736                  'E119: Not enough arguments for function: ((i) => 0)()')
737
738  var lines =<< trim END
739      var Ref = (x: number, y: number) => x + y
740      echo Ref(1, 'x')
741  END
742  CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
743
744  lines =<< trim END
745    var Ref: func(job, string, number)
746    Ref = (x, y) => 0
747  END
748  CheckDefAndScriptFailure(lines, 'E1012:')
749
750  lines =<< trim END
751    var Ref: func(job, string)
752    Ref = (x, y, z) => 0
753  END
754  CheckDefAndScriptFailure(lines, 'E1012:')
755
756  lines =<< trim END
757      var one = 1
758      var l = [1, 2, 3]
759      echo map(l, (one) => one)
760  END
761  CheckDefFailure(lines, 'E1167:')
762  CheckScriptFailure(['vim9script'] + lines, 'E1168:')
763
764  lines =<< trim END
765      def ShadowLocal()
766        var one = 1
767        var l = [1, 2, 3]
768        echo map(l, (one) => one)
769      enddef
770  END
771  CheckDefFailure(lines, 'E1167:')
772
773  lines =<< trim END
774      def Shadowarg(one: number)
775        var l = [1, 2, 3]
776        echo map(l, (one) => one)
777      enddef
778  END
779  CheckDefFailure(lines, 'E1167:')
780enddef
781
782def FilterWithCond(x: string, Cond: func(string): bool): bool
783  return Cond(x)
784enddef
785
786def Test_lambda_return_type()
787  var lines =<< trim END
788    var Ref = (): => 123
789  END
790  CheckDefAndScriptFailure(lines, 'E1157:', 1)
791
792  # this works
793  for x in ['foo', 'boo']
794    echo FilterWithCond(x, (v) => v =~ '^b')
795  endfor
796
797  # this fails
798  lines =<< trim END
799      echo FilterWithCond('foo', (v) => v .. '^b')
800  END
801  CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
802enddef
803
804def Test_lambda_uses_assigned_var()
805  CheckDefSuccess([
806        'var x: any = "aaa"'
807        'x = filter(["bbb"], (_, v) => v =~ x)'])
808enddef
809
810def Test_pass_legacy_lambda_to_def_func()
811  var lines =<< trim END
812      vim9script
813      func Foo()
814        eval s:Bar({x -> 0})
815      endfunc
816      def Bar(y: any)
817      enddef
818      Foo()
819  END
820  CheckScriptSuccess(lines)
821enddef
822
823" Default arg and varargs
824def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
825  var res = one .. ',' .. two
826  for s in rest
827    res ..= ',' .. s
828  endfor
829  return res
830enddef
831
832def Test_call_def_varargs()
833  assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
834  MyDefVarargs('one')->assert_equal('one,foo')
835  MyDefVarargs('one', 'two')->assert_equal('one,two')
836  MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
837  CheckDefFailure(['MyDefVarargs("one", 22)'],
838      'E1013: Argument 2: type mismatch, expected string but got number')
839  CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
840      'E1013: Argument 3: type mismatch, expected string but got number')
841
842  var lines =<< trim END
843      vim9script
844      def Func(...l: list<string>)
845        echo l
846      enddef
847      Func('a', 'b', 'c')
848  END
849  CheckScriptSuccess(lines)
850
851  lines =<< trim END
852      vim9script
853      def Func(...l: list<string>)
854        echo l
855      enddef
856      Func()
857  END
858  CheckScriptSuccess(lines)
859
860  lines =<< trim END
861      vim9script
862      def Func(...l: any)
863        echo l
864      enddef
865      Func(0)
866  END
867  CheckScriptSuccess(lines)
868
869  lines =<< trim END
870      vim9script
871      def Func(..._l: list<string>)
872        echo _l
873      enddef
874      Func('a', 'b', 'c')
875  END
876  CheckScriptSuccess(lines)
877
878  lines =<< trim END
879      vim9script
880      def Func(...l: list<string>)
881        echo l
882      enddef
883      Func(1, 2, 3)
884  END
885  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
886
887  lines =<< trim END
888      vim9script
889      def Func(...l: list<string>)
890        echo l
891      enddef
892      Func('a', 9)
893  END
894  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
895
896  lines =<< trim END
897      vim9script
898      def Func(...l: list<string>)
899        echo l
900      enddef
901      Func(1, 'a')
902  END
903  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
904
905  lines =<< trim END
906      vim9script
907      def Func(  # some comment
908                ...l = []
909                )
910        echo l
911      enddef
912  END
913  CheckScriptFailure(lines, 'E1160:')
914enddef
915
916let s:value = ''
917
918def FuncOneDefArg(opt = 'text')
919  s:value = opt
920enddef
921
922def FuncTwoDefArg(nr = 123, opt = 'text'): string
923  return nr .. opt
924enddef
925
926def FuncVarargs(...arg: list<string>): string
927  return join(arg, ',')
928enddef
929
930def Test_func_type_varargs()
931  var RefDefArg: func(?string)
932  RefDefArg = FuncOneDefArg
933  RefDefArg()
934  s:value->assert_equal('text')
935  RefDefArg('some')
936  s:value->assert_equal('some')
937
938  var RefDef2Arg: func(?number, ?string): string
939  RefDef2Arg = FuncTwoDefArg
940  RefDef2Arg()->assert_equal('123text')
941  RefDef2Arg(99)->assert_equal('99text')
942  RefDef2Arg(77, 'some')->assert_equal('77some')
943
944  CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
945  CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
946
947  var RefVarargs: func(...list<string>): string
948  RefVarargs = FuncVarargs
949  RefVarargs()->assert_equal('')
950  RefVarargs('one')->assert_equal('one')
951  RefVarargs('one', 'two')->assert_equal('one,two')
952
953  CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
954  CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
955enddef
956
957" Only varargs
958def MyVarargsOnly(...args: list<string>): string
959  return join(args, ',')
960enddef
961
962def Test_call_varargs_only()
963  MyVarargsOnly()->assert_equal('')
964  MyVarargsOnly('one')->assert_equal('one')
965  MyVarargsOnly('one', 'two')->assert_equal('one,two')
966  CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
967  CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
968enddef
969
970def Test_using_var_as_arg()
971  writefile(['def Func(x: number)',  'var x = 234', 'enddef', 'defcompile'], 'Xdef')
972  assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
973  delete('Xdef')
974enddef
975
976def DictArg(arg: dict<string>)
977  arg['key'] = 'value'
978enddef
979
980def ListArg(arg: list<string>)
981  arg[0] = 'value'
982enddef
983
984def Test_assign_to_argument()
985  # works for dict and list
986  var d: dict<string> = {}
987  DictArg(d)
988  d['key']->assert_equal('value')
989  var l: list<string> = []
990  ListArg(l)
991  l[0]->assert_equal('value')
992
993  CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
994  delfunc! g:Func
995enddef
996
997" These argument names are reserved in legacy functions.
998def WithReservedNames(firstline: string, lastline: string): string
999  return firstline .. lastline
1000enddef
1001
1002def Test_argument_names()
1003  assert_equal('OK', WithReservedNames('O', 'K'))
1004enddef
1005
1006def Test_call_func_defined_later()
1007  g:DefinedLater('one')->assert_equal('one')
1008  assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
1009enddef
1010
1011func DefinedLater(arg)
1012  return a:arg
1013endfunc
1014
1015def Test_call_funcref()
1016  g:SomeFunc('abc')->assert_equal(3)
1017  assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
1018  assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
1019
1020  var lines =<< trim END
1021    vim9script
1022    def RetNumber(): number
1023      return 123
1024    enddef
1025    var Funcref: func: number = function('RetNumber')
1026    Funcref()->assert_equal(123)
1027  END
1028  CheckScriptSuccess(lines)
1029
1030  lines =<< trim END
1031    vim9script
1032    def RetNumber(): number
1033      return 123
1034    enddef
1035    def Bar(F: func: number): number
1036      return F()
1037    enddef
1038    var Funcref = function('RetNumber')
1039    Bar(Funcref)->assert_equal(123)
1040  END
1041  CheckScriptSuccess(lines)
1042
1043  lines =<< trim END
1044    vim9script
1045    def UseNumber(nr: number)
1046      echo nr
1047    enddef
1048    var Funcref: func(number) = function('UseNumber')
1049    Funcref(123)
1050  END
1051  CheckScriptSuccess(lines)
1052
1053  lines =<< trim END
1054    vim9script
1055    def UseNumber(nr: number)
1056      echo nr
1057    enddef
1058    var Funcref: func(string) = function('UseNumber')
1059  END
1060  CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
1061
1062  lines =<< trim END
1063    vim9script
1064    def EchoNr(nr = 34)
1065      g:echo = nr
1066    enddef
1067    var Funcref: func(?number) = function('EchoNr')
1068    Funcref()
1069    g:echo->assert_equal(34)
1070    Funcref(123)
1071    g:echo->assert_equal(123)
1072  END
1073  CheckScriptSuccess(lines)
1074
1075  lines =<< trim END
1076    vim9script
1077    def EchoList(...l: list<number>)
1078      g:echo = l
1079    enddef
1080    var Funcref: func(...list<number>) = function('EchoList')
1081    Funcref()
1082    g:echo->assert_equal([])
1083    Funcref(1, 2, 3)
1084    g:echo->assert_equal([1, 2, 3])
1085  END
1086  CheckScriptSuccess(lines)
1087
1088  lines =<< trim END
1089    vim9script
1090    def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
1091      g:optarg = opt
1092      g:listarg = l
1093      return nr
1094    enddef
1095    var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
1096    Funcref(10)->assert_equal(10)
1097    g:optarg->assert_equal(12)
1098    g:listarg->assert_equal([])
1099
1100    Funcref(11, 22)->assert_equal(11)
1101    g:optarg->assert_equal(22)
1102    g:listarg->assert_equal([])
1103
1104    Funcref(17, 18, 1, 2, 3)->assert_equal(17)
1105    g:optarg->assert_equal(18)
1106    g:listarg->assert_equal([1, 2, 3])
1107  END
1108  CheckScriptSuccess(lines)
1109enddef
1110
1111let SomeFunc = function('len')
1112let NotAFunc = 'text'
1113
1114def CombineFuncrefTypes()
1115  # same arguments, different return type
1116  var Ref1: func(bool): string
1117  var Ref2: func(bool): number
1118  var Ref3: func(bool): any
1119  Ref3 = g:cond ? Ref1 : Ref2
1120
1121  # different number of arguments
1122  var Refa1: func(bool): number
1123  var Refa2: func(bool, number): number
1124  var Refa3: func: number
1125  Refa3 = g:cond ? Refa1 : Refa2
1126
1127  # different argument types
1128  var Refb1: func(bool, string): number
1129  var Refb2: func(string, number): number
1130  var Refb3: func(any, any): number
1131  Refb3 = g:cond ? Refb1 : Refb2
1132enddef
1133
1134def FuncWithForwardCall()
1135  return g:DefinedEvenLater("yes")
1136enddef
1137
1138def DefinedEvenLater(arg: string): string
1139  return arg
1140enddef
1141
1142def Test_error_in_nested_function()
1143  # Error in called function requires unwinding the call stack.
1144  assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
1145enddef
1146
1147def Test_return_type_wrong()
1148  CheckScriptFailure([
1149        'def Func(): number',
1150        'return "a"',
1151        'enddef',
1152        'defcompile'], 'expected number but got string')
1153  delfunc! g:Func
1154  CheckScriptFailure([
1155        'def Func(): string',
1156        'return 1',
1157        'enddef',
1158        'defcompile'], 'expected string but got number')
1159  delfunc! g:Func
1160  CheckScriptFailure([
1161        'def Func(): void',
1162        'return "a"',
1163        'enddef',
1164        'defcompile'],
1165        'E1096: Returning a value in a function without a return type')
1166  delfunc! g:Func
1167  CheckScriptFailure([
1168        'def Func()',
1169        'return "a"',
1170        'enddef',
1171        'defcompile'],
1172        'E1096: Returning a value in a function without a return type')
1173  delfunc! g:Func
1174
1175  CheckScriptFailure([
1176        'def Func(): number',
1177        'return',
1178        'enddef',
1179        'defcompile'], 'E1003:')
1180  delfunc! g:Func
1181
1182  CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
1183  delfunc! g:Func
1184  CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
1185  delfunc! g:Func
1186  CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
1187  delfunc! g:Func
1188
1189  CheckScriptFailure([
1190        'vim9script',
1191        'def FuncB()',
1192        '  return 123',
1193        'enddef',
1194        'def FuncA()',
1195        '   FuncB()',
1196        'enddef',
1197        'defcompile'], 'E1096:')
1198enddef
1199
1200def Test_arg_type_wrong()
1201  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
1202  CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
1203  CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
1204  CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
1205enddef
1206
1207def Test_white_space_after_comma()
1208  var lines =<< trim END
1209    vim9script
1210    def Func(a: number,b: number)
1211    enddef
1212  END
1213  CheckScriptFailure(lines, 'E1069:')
1214
1215  # OK in legacy function
1216  lines =<< trim END
1217    vim9script
1218    func Func(a,b)
1219    endfunc
1220  END
1221  CheckScriptSuccess(lines)
1222enddef
1223
1224def Test_vim9script_call()
1225  var lines =<< trim END
1226    vim9script
1227    var name = ''
1228    def MyFunc(arg: string)
1229       name = arg
1230    enddef
1231    MyFunc('foobar')
1232    name->assert_equal('foobar')
1233
1234    var str = 'barfoo'
1235    str->MyFunc()
1236    name->assert_equal('barfoo')
1237
1238    g:value = 'value'
1239    g:value->MyFunc()
1240    name->assert_equal('value')
1241
1242    var listvar = []
1243    def ListFunc(arg: list<number>)
1244       listvar = arg
1245    enddef
1246    [1, 2, 3]->ListFunc()
1247    listvar->assert_equal([1, 2, 3])
1248
1249    var dictvar = {}
1250    def DictFunc(arg: dict<number>)
1251       dictvar = arg
1252    enddef
1253    {a: 1, b: 2}->DictFunc()
1254    dictvar->assert_equal({a: 1, b: 2})
1255    def CompiledDict()
1256      {a: 3, b: 4}->DictFunc()
1257    enddef
1258    CompiledDict()
1259    dictvar->assert_equal({a: 3, b: 4})
1260
1261    {a: 3, b: 4}->DictFunc()
1262    dictvar->assert_equal({a: 3, b: 4})
1263
1264    ('text')->MyFunc()
1265    name->assert_equal('text')
1266    ("some")->MyFunc()
1267    name->assert_equal('some')
1268
1269    # line starting with single quote is not a mark
1270    # line starting with double quote can be a method call
1271    'asdfasdf'->MyFunc()
1272    name->assert_equal('asdfasdf')
1273    "xyz"->MyFunc()
1274    name->assert_equal('xyz')
1275
1276    def UseString()
1277      'xyork'->MyFunc()
1278    enddef
1279    UseString()
1280    name->assert_equal('xyork')
1281
1282    def UseString2()
1283      "knife"->MyFunc()
1284    enddef
1285    UseString2()
1286    name->assert_equal('knife')
1287
1288    # prepending a colon makes it a mark
1289    new
1290    setline(1, ['aaa', 'bbb', 'ccc'])
1291    normal! 3Gmt1G
1292    :'t
1293    getcurpos()[1]->assert_equal(3)
1294    bwipe!
1295
1296    MyFunc(
1297        'continued'
1298        )
1299    assert_equal('continued',
1300            name
1301            )
1302
1303    call MyFunc(
1304        'more'
1305          ..
1306          'lines'
1307        )
1308    assert_equal(
1309        'morelines',
1310        name)
1311  END
1312  writefile(lines, 'Xcall.vim')
1313  source Xcall.vim
1314  delete('Xcall.vim')
1315enddef
1316
1317def Test_vim9script_call_fail_decl()
1318  var lines =<< trim END
1319    vim9script
1320    var name = ''
1321    def MyFunc(arg: string)
1322       var name = 123
1323    enddef
1324    defcompile
1325  END
1326  CheckScriptFailure(lines, 'E1054:')
1327enddef
1328
1329def Test_vim9script_call_fail_type()
1330  var lines =<< trim END
1331    vim9script
1332    def MyFunc(arg: string)
1333      echo arg
1334    enddef
1335    MyFunc(1234)
1336  END
1337  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
1338enddef
1339
1340def Test_vim9script_call_fail_const()
1341  var lines =<< trim END
1342    vim9script
1343    const var = ''
1344    def MyFunc(arg: string)
1345       var = 'asdf'
1346    enddef
1347    defcompile
1348  END
1349  writefile(lines, 'Xcall_const.vim')
1350  assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
1351  delete('Xcall_const.vim')
1352
1353  lines =<< trim END
1354      const g:Aconst = 77
1355      def Change()
1356        # comment
1357        g:Aconst = 99
1358      enddef
1359      call Change()
1360      unlet g:Aconst
1361  END
1362  CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
1363enddef
1364
1365" Test that inside :function a Python function can be defined, :def is not
1366" recognized.
1367func Test_function_python()
1368  CheckFeature python3
1369  let py = 'python3'
1370  execute py "<< EOF"
1371def do_something():
1372  return 1
1373EOF
1374endfunc
1375
1376def Test_delfunc()
1377  var lines =<< trim END
1378    vim9script
1379    def g:GoneSoon()
1380      echo 'hello'
1381    enddef
1382
1383    def CallGoneSoon()
1384      GoneSoon()
1385    enddef
1386    defcompile
1387
1388    delfunc g:GoneSoon
1389    CallGoneSoon()
1390  END
1391  writefile(lines, 'XToDelFunc')
1392  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
1393  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
1394
1395  delete('XToDelFunc')
1396enddef
1397
1398def Test_redef_failure()
1399  writefile(['def Func0(): string',  'return "Func0"', 'enddef'], 'Xdef')
1400  so Xdef
1401  writefile(['def Func1(): string',  'return "Func1"', 'enddef'], 'Xdef')
1402  so Xdef
1403  writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
1404  assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
1405  writefile(['def Func2(): string',  'return "Func2"', 'enddef'], 'Xdef')
1406  so Xdef
1407  delete('Xdef')
1408
1409  g:Func0()->assert_equal(0)
1410  g:Func1()->assert_equal('Func1')
1411  g:Func2()->assert_equal('Func2')
1412
1413  delfunc! Func0
1414  delfunc! Func1
1415  delfunc! Func2
1416enddef
1417
1418def Test_vim9script_func()
1419  var lines =<< trim END
1420    vim9script
1421    func Func(arg)
1422      echo a:arg
1423    endfunc
1424    Func('text')
1425  END
1426  writefile(lines, 'XVim9Func')
1427  so XVim9Func
1428
1429  delete('XVim9Func')
1430enddef
1431
1432let s:funcResult = 0
1433
1434def FuncNoArgNoRet()
1435  s:funcResult = 11
1436enddef
1437
1438def FuncNoArgRetNumber(): number
1439  s:funcResult = 22
1440  return 1234
1441enddef
1442
1443def FuncNoArgRetString(): string
1444  s:funcResult = 45
1445  return 'text'
1446enddef
1447
1448def FuncOneArgNoRet(arg: number)
1449  s:funcResult = arg
1450enddef
1451
1452def FuncOneArgRetNumber(arg: number): number
1453  s:funcResult = arg
1454  return arg
1455enddef
1456
1457def FuncTwoArgNoRet(one: bool, two: number)
1458  s:funcResult = two
1459enddef
1460
1461def FuncOneArgRetString(arg: string): string
1462  return arg
1463enddef
1464
1465def FuncOneArgRetAny(arg: any): any
1466  return arg
1467enddef
1468
1469def Test_func_type()
1470  var Ref1: func()
1471  s:funcResult = 0
1472  Ref1 = FuncNoArgNoRet
1473  Ref1()
1474  s:funcResult->assert_equal(11)
1475
1476  var Ref2: func
1477  s:funcResult = 0
1478  Ref2 = FuncNoArgNoRet
1479  Ref2()
1480  s:funcResult->assert_equal(11)
1481
1482  s:funcResult = 0
1483  Ref2 = FuncOneArgNoRet
1484  Ref2(12)
1485  s:funcResult->assert_equal(12)
1486
1487  s:funcResult = 0
1488  Ref2 = FuncNoArgRetNumber
1489  Ref2()->assert_equal(1234)
1490  s:funcResult->assert_equal(22)
1491
1492  s:funcResult = 0
1493  Ref2 = FuncOneArgRetNumber
1494  Ref2(13)->assert_equal(13)
1495  s:funcResult->assert_equal(13)
1496enddef
1497
1498def Test_repeat_return_type()
1499  var res = 0
1500  for n in repeat([1], 3)
1501    res += n
1502  endfor
1503  res->assert_equal(3)
1504
1505  res = 0
1506  for n in add([1, 2], 3)
1507    res += n
1508  endfor
1509  res->assert_equal(6)
1510enddef
1511
1512def Test_argv_return_type()
1513  next fileone filetwo
1514  var res = ''
1515  for name in argv()
1516    res ..= name
1517  endfor
1518  res->assert_equal('fileonefiletwo')
1519enddef
1520
1521def Test_func_type_part()
1522  var RefVoid: func: void
1523  RefVoid = FuncNoArgNoRet
1524  RefVoid = FuncOneArgNoRet
1525  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1526  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
1527
1528  var RefAny: func(): any
1529  RefAny = FuncNoArgRetNumber
1530  RefAny = FuncNoArgRetString
1531  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1532  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
1533
1534  var RefAnyNoArgs: func: any = RefAny
1535
1536  var RefNr: func: number
1537  RefNr = FuncNoArgRetNumber
1538  RefNr = FuncOneArgRetNumber
1539  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1540  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
1541
1542  var RefStr: func: string
1543  RefStr = FuncNoArgRetString
1544  RefStr = FuncOneArgRetString
1545  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1546  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
1547enddef
1548
1549def Test_func_type_fails()
1550  CheckDefFailure(['var ref1: func()'], 'E704:')
1551
1552  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1553  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1554  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1555  CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1556  CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1557  CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
1558
1559  CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1560  CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1561  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:')
1562  CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
1563enddef
1564
1565def Test_func_return_type()
1566  var nr: number
1567  nr = FuncNoArgRetNumber()
1568  nr->assert_equal(1234)
1569
1570  nr = FuncOneArgRetAny(122)
1571  nr->assert_equal(122)
1572
1573  var str: string
1574  str = FuncOneArgRetAny('yes')
1575  str->assert_equal('yes')
1576
1577  CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
1578enddef
1579
1580def Test_func_common_type()
1581  def FuncOne(n: number): number
1582    return n
1583  enddef
1584  def FuncTwo(s: string): number
1585    return len(s)
1586  enddef
1587  def FuncThree(n: number, s: string): number
1588    return n + len(s)
1589  enddef
1590  var list = [FuncOne, FuncTwo, FuncThree]
1591  assert_equal(8, list[0](8))
1592  assert_equal(4, list[1]('word'))
1593  assert_equal(7, list[2](3, 'word'))
1594enddef
1595
1596def MultiLine(
1597    arg1: string,
1598    arg2 = 1234,
1599    ...rest: list<string>
1600      ): string
1601  return arg1 .. arg2 .. join(rest, '-')
1602enddef
1603
1604def MultiLineComment(
1605    arg1: string, # comment
1606    arg2 = 1234, # comment
1607    ...rest: list<string> # comment
1608      ): string # comment
1609  return arg1 .. arg2 .. join(rest, '-')
1610enddef
1611
1612def Test_multiline()
1613  MultiLine('text')->assert_equal('text1234')
1614  MultiLine('text', 777)->assert_equal('text777')
1615  MultiLine('text', 777, 'one')->assert_equal('text777one')
1616  MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
1617enddef
1618
1619func Test_multiline_not_vim9()
1620  call MultiLine('text')->assert_equal('text1234')
1621  call MultiLine('text', 777)->assert_equal('text777')
1622  call MultiLine('text', 777, 'one')->assert_equal('text777one')
1623  call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
1624endfunc
1625
1626
1627" When using CheckScriptFailure() for the below test, E1010 is generated instead
1628" of E1056.
1629func Test_E1056_1059()
1630  let caught_1056 = 0
1631  try
1632    def F():
1633      return 1
1634    enddef
1635  catch /E1056:/
1636    let caught_1056 = 1
1637  endtry
1638  eval caught_1056->assert_equal(1)
1639
1640  let caught_1059 = 0
1641  try
1642    def F5(items : list)
1643      echo 'a'
1644    enddef
1645  catch /E1059:/
1646    let caught_1059 = 1
1647  endtry
1648  eval caught_1059->assert_equal(1)
1649endfunc
1650
1651func DelMe()
1652  echo 'DelMe'
1653endfunc
1654
1655def Test_error_reporting()
1656  # comment lines at the start of the function
1657  var lines =<< trim END
1658    " comment
1659    def Func()
1660      # comment
1661      # comment
1662      invalid
1663    enddef
1664    defcompile
1665  END
1666  writefile(lines, 'Xdef')
1667  try
1668    source Xdef
1669    assert_report('should have failed')
1670  catch /E476:/
1671    v:exception->assert_match('Invalid command: invalid')
1672    v:throwpoint->assert_match(', line 3$')
1673  endtry
1674  delfunc! g:Func
1675
1676  # comment lines after the start of the function
1677  lines =<< trim END
1678    " comment
1679    def Func()
1680      var x = 1234
1681      # comment
1682      # comment
1683      invalid
1684    enddef
1685    defcompile
1686  END
1687  writefile(lines, 'Xdef')
1688  try
1689    source Xdef
1690    assert_report('should have failed')
1691  catch /E476:/
1692    v:exception->assert_match('Invalid command: invalid')
1693    v:throwpoint->assert_match(', line 4$')
1694  endtry
1695  delfunc! g:Func
1696
1697  lines =<< trim END
1698    vim9script
1699    def Func()
1700      var db = {foo: 1, bar: 2}
1701      # comment
1702      var x = db.asdf
1703    enddef
1704    defcompile
1705    Func()
1706  END
1707  writefile(lines, 'Xdef')
1708  try
1709    source Xdef
1710    assert_report('should have failed')
1711  catch /E716:/
1712    v:throwpoint->assert_match('_Func, line 3$')
1713  endtry
1714  delfunc! g:Func
1715
1716  delete('Xdef')
1717enddef
1718
1719def Test_deleted_function()
1720  CheckDefExecFailure([
1721      'var RefMe: func = function("g:DelMe")',
1722      'delfunc g:DelMe',
1723      'echo RefMe()'], 'E117:')
1724enddef
1725
1726def Test_unknown_function()
1727  CheckDefExecFailure([
1728      'var Ref: func = function("NotExist")',
1729      'delfunc g:NotExist'], 'E700:')
1730enddef
1731
1732def RefFunc(Ref: func(any): any): string
1733  return Ref('more')
1734enddef
1735
1736def Test_closure_simple()
1737  var local = 'some '
1738  RefFunc((s) => local .. s)->assert_equal('some more')
1739enddef
1740
1741def MakeRef()
1742  var local = 'some '
1743  g:Ref = (s) => local .. s
1744enddef
1745
1746def Test_closure_ref_after_return()
1747  MakeRef()
1748  g:Ref('thing')->assert_equal('some thing')
1749  unlet g:Ref
1750enddef
1751
1752def MakeTwoRefs()
1753  var local = ['some']
1754  g:Extend = (s) => local->add(s)
1755  g:Read = () => local
1756enddef
1757
1758def Test_closure_two_refs()
1759  MakeTwoRefs()
1760  join(g:Read(), ' ')->assert_equal('some')
1761  g:Extend('more')
1762  join(g:Read(), ' ')->assert_equal('some more')
1763  g:Extend('even')
1764  join(g:Read(), ' ')->assert_equal('some more even')
1765
1766  unlet g:Extend
1767  unlet g:Read
1768enddef
1769
1770def ReadRef(Ref: func(): list<string>): string
1771  return join(Ref(), ' ')
1772enddef
1773
1774def ExtendRef(Ref: func(string): list<string>, add: string)
1775  Ref(add)
1776enddef
1777
1778def Test_closure_two_indirect_refs()
1779  MakeTwoRefs()
1780  ReadRef(g:Read)->assert_equal('some')
1781  ExtendRef(g:Extend, 'more')
1782  ReadRef(g:Read)->assert_equal('some more')
1783  ExtendRef(g:Extend, 'even')
1784  ReadRef(g:Read)->assert_equal('some more even')
1785
1786  unlet g:Extend
1787  unlet g:Read
1788enddef
1789
1790def MakeArgRefs(theArg: string)
1791  var local = 'loc_val'
1792  g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
1793enddef
1794
1795def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
1796  var local = 'the_loc'
1797  g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
1798enddef
1799
1800def Test_closure_using_argument()
1801  MakeArgRefs('arg_val')
1802  g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
1803
1804  MakeArgRefsVarargs('arg_val', 'one', 'two')
1805  g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
1806
1807  unlet g:UseArg
1808  unlet g:UseVararg
1809
1810  var lines =<< trim END
1811      vim9script
1812      def Test(Fun: func(number): number): list<number>
1813        return map([1, 2, 3], (_, i) => Fun(i))
1814      enddef
1815      def Inc(nr: number): number
1816        return nr + 2
1817      enddef
1818      assert_equal([3, 4, 5], Test(Inc))
1819  END
1820  CheckScriptSuccess(lines)
1821enddef
1822
1823def MakeGetAndAppendRefs()
1824  var local = 'a'
1825
1826  def Append(arg: string)
1827    local ..= arg
1828  enddef
1829  g:Append = Append
1830
1831  def Get(): string
1832    return local
1833  enddef
1834  g:Get = Get
1835enddef
1836
1837def Test_closure_append_get()
1838  MakeGetAndAppendRefs()
1839  g:Get()->assert_equal('a')
1840  g:Append('-b')
1841  g:Get()->assert_equal('a-b')
1842  g:Append('-c')
1843  g:Get()->assert_equal('a-b-c')
1844
1845  unlet g:Append
1846  unlet g:Get
1847enddef
1848
1849def Test_nested_closure()
1850  var local = 'text'
1851  def Closure(arg: string): string
1852    return local .. arg
1853  enddef
1854  Closure('!!!')->assert_equal('text!!!')
1855enddef
1856
1857func GetResult(Ref)
1858  return a:Ref('some')
1859endfunc
1860
1861def Test_call_closure_not_compiled()
1862  var text = 'text'
1863  g:Ref = (s) =>  s .. text
1864  GetResult(g:Ref)->assert_equal('sometext')
1865enddef
1866
1867def Test_double_closure_fails()
1868  var lines =<< trim END
1869    vim9script
1870    def Func()
1871      var name = 0
1872      for i in range(2)
1873          timer_start(0, () => name)
1874      endfor
1875    enddef
1876    Func()
1877  END
1878  CheckScriptSuccess(lines)
1879enddef
1880
1881def Test_nested_closure_used()
1882  var lines =<< trim END
1883      vim9script
1884      def Func()
1885        var x = 'hello'
1886        var Closure = () => x
1887        g:Myclosure = () => Closure()
1888      enddef
1889      Func()
1890      assert_equal('hello', g:Myclosure())
1891  END
1892  CheckScriptSuccess(lines)
1893enddef
1894
1895def Test_nested_closure_fails()
1896  var lines =<< trim END
1897    vim9script
1898    def FuncA()
1899      FuncB(0)
1900    enddef
1901    def FuncB(n: number): list<string>
1902      return map([0], (_, v) => n)
1903    enddef
1904    FuncA()
1905  END
1906  CheckScriptFailure(lines, 'E1012:')
1907enddef
1908
1909def Test_global_closure()
1910  var lines =<< trim END
1911      vim9script
1912      def ReverseEveryNLines(n: number, line1: number, line2: number)
1913        var mods = 'sil keepj keepp lockm '
1914        var range = ':' .. line1 .. ',' .. line2
1915        def g:Offset(): number
1916            var offset = (line('.') - line1 + 1) % n
1917            return offset != 0 ? offset : n
1918        enddef
1919        exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
1920      enddef
1921
1922      new
1923      repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
1924      ReverseEveryNLines(3, 1, 9)
1925  END
1926  CheckScriptSuccess(lines)
1927  var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
1928  assert_equal(expected, getline(1, 9))
1929  bwipe!
1930enddef
1931
1932def Test_global_closure_called_directly()
1933  var lines =<< trim END
1934      vim9script
1935      def Outer()
1936        var x = 1
1937        def g:Inner()
1938          var y = x
1939          x += 1
1940          assert_equal(1, y)
1941        enddef
1942        g:Inner()
1943        assert_equal(2, x)
1944      enddef
1945      Outer()
1946  END
1947  CheckScriptSuccess(lines)
1948  delfunc g:Inner
1949enddef
1950
1951def Test_failure_in_called_function()
1952  # this was using the frame index as the return value
1953  var lines =<< trim END
1954      vim9script
1955      au TerminalWinOpen * eval [][0]
1956      def PopupTerm(a: any)
1957        # make sure typvals on stack are string
1958        ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
1959        FireEvent()
1960      enddef
1961      def FireEvent()
1962          do TerminalWinOpen
1963      enddef
1964      # use try/catch to make eval fail
1965      try
1966          call PopupTerm(0)
1967      catch
1968      endtry
1969      au! TerminalWinOpen
1970  END
1971  CheckScriptSuccess(lines)
1972enddef
1973
1974def Test_nested_lambda()
1975  var lines =<< trim END
1976    vim9script
1977    def Func()
1978      var x = 4
1979      var Lambda1 = () => 7
1980      var Lambda2 = () => [Lambda1(), x]
1981      var res = Lambda2()
1982      assert_equal([7, 4], res)
1983    enddef
1984    Func()
1985  END
1986  CheckScriptSuccess(lines)
1987enddef
1988
1989def Shadowed(): list<number>
1990  var FuncList: list<func: number> = [() => 42]
1991  return FuncList->mapnew((_, Shadowed) => Shadowed())
1992enddef
1993
1994def Test_lambda_arg_shadows_func()
1995  assert_equal([42], Shadowed())
1996enddef
1997
1998def Line_continuation_in_def(dir: string = ''): string
1999  var path: string = empty(dir)
2000          \ ? 'empty'
2001          \ : 'full'
2002  return path
2003enddef
2004
2005def Test_line_continuation_in_def()
2006  Line_continuation_in_def('.')->assert_equal('full')
2007enddef
2008
2009def Test_script_var_in_lambda()
2010  var lines =<< trim END
2011      vim9script
2012      var script = 'test'
2013      assert_equal(['test'], map(['one'], () => script))
2014  END
2015  CheckScriptSuccess(lines)
2016enddef
2017
2018def Line_continuation_in_lambda(): list<string>
2019  var x = range(97, 100)
2020      ->mapnew((_, v) => nr2char(v)
2021          ->toupper())
2022      ->reverse()
2023  return x
2024enddef
2025
2026def Test_line_continuation_in_lambda()
2027  Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
2028
2029  var lines =<< trim END
2030      vim9script
2031      var res = [{n: 1, m: 2, s: 'xxx'}]
2032                ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
2033                    v.n,
2034                    v.m,
2035                    substitute(v.s, '.*', 'yyy', '')
2036                    ))
2037      assert_equal(['1:2:yyy'], res)
2038  END
2039  CheckScriptSuccess(lines)
2040enddef
2041
2042def Test_list_lambda()
2043  timer_start(1000, (_) => 0)
2044  var body = execute(timer_info()[0].callback
2045         ->string()
2046         ->substitute("('", ' ', '')
2047         ->substitute("')", '', '')
2048         ->substitute('function\zs', ' ', ''))
2049  assert_match('def <lambda>\d\+(_: any, ...): number\n1  return 0\n   enddef', body)
2050enddef
2051
2052def DoFilterThis(a: string): list<string>
2053  # closure nested inside another closure using argument
2054  var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
2055  return ['x', 'y', 'a', 'x2', 'c']->Filter()
2056enddef
2057
2058def Test_nested_closure_using_argument()
2059  assert_equal(['x', 'x2'], DoFilterThis('x'))
2060enddef
2061
2062def Test_triple_nested_closure()
2063  var what = 'x'
2064  var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
2065  var Filter = (l) => filter(l, (_, v) => Match(v, what))
2066  assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
2067enddef
2068
2069func Test_silent_echo()
2070  CheckScreendump
2071
2072  let lines =<< trim END
2073    vim9script
2074    def EchoNothing()
2075      silent echo ''
2076    enddef
2077    defcompile
2078  END
2079  call writefile(lines, 'XTest_silent_echo')
2080
2081  " Check that the balloon shows up after a mouse move
2082  let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
2083  call term_sendkeys(buf, ":abc")
2084  call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
2085
2086  " clean up
2087  call StopVimInTerminal(buf)
2088  call delete('XTest_silent_echo')
2089endfunc
2090
2091def SilentlyError()
2092  execute('silent! invalid')
2093  g:did_it = 'yes'
2094enddef
2095
2096func UserError()
2097  silent! invalid
2098endfunc
2099
2100def SilentlyUserError()
2101  UserError()
2102  g:did_it = 'yes'
2103enddef
2104
2105" This can't be a :def function, because the assert would not be reached.
2106func Test_ignore_silent_error()
2107  let g:did_it = 'no'
2108  call SilentlyError()
2109  call assert_equal('yes', g:did_it)
2110
2111  let g:did_it = 'no'
2112  call SilentlyUserError()
2113  call assert_equal('yes', g:did_it)
2114
2115  unlet g:did_it
2116endfunc
2117
2118def Test_ignore_silent_error_in_filter()
2119  var lines =<< trim END
2120      vim9script
2121      def Filter(winid: number, key: string): bool
2122          if key == 'o'
2123              silent! eval [][0]
2124              return true
2125          endif
2126          return popup_filter_menu(winid, key)
2127      enddef
2128
2129      popup_create('popup', {filter: Filter})
2130      feedkeys("o\r", 'xnt')
2131  END
2132  CheckScriptSuccess(lines)
2133enddef
2134
2135def Fibonacci(n: number): number
2136  if n < 2
2137    return n
2138  else
2139    return Fibonacci(n - 1) + Fibonacci(n - 2)
2140  endif
2141enddef
2142
2143def Test_recursive_call()
2144  Fibonacci(20)->assert_equal(6765)
2145enddef
2146
2147def TreeWalk(dir: string): list<any>
2148  return readdir(dir)->mapnew((_, val) =>
2149            fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
2150               ? {[val]: TreeWalk(dir .. '/' .. val)}
2151               : val
2152             )
2153enddef
2154
2155def Test_closure_in_map()
2156  mkdir('XclosureDir/tdir', 'p')
2157  writefile(['111'], 'XclosureDir/file1')
2158  writefile(['222'], 'XclosureDir/file2')
2159  writefile(['333'], 'XclosureDir/tdir/file3')
2160
2161  TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
2162
2163  delete('XclosureDir', 'rf')
2164enddef
2165
2166def Test_invalid_function_name()
2167  var lines =<< trim END
2168      vim9script
2169      def s: list<string>
2170  END
2171  CheckScriptFailure(lines, 'E129:')
2172
2173  lines =<< trim END
2174      vim9script
2175      def g: list<string>
2176  END
2177  CheckScriptFailure(lines, 'E129:')
2178
2179  lines =<< trim END
2180      vim9script
2181      def <SID>: list<string>
2182  END
2183  CheckScriptFailure(lines, 'E884:')
2184
2185  lines =<< trim END
2186      vim9script
2187      def F list<string>
2188  END
2189  CheckScriptFailure(lines, 'E488:')
2190enddef
2191
2192def Test_partial_call()
2193  var Xsetlist = function('setloclist', [0])
2194  Xsetlist([], ' ', {title: 'test'})
2195  getloclist(0, {title: 1})->assert_equal({title: 'test'})
2196
2197  Xsetlist = function('setloclist', [0, [], ' '])
2198  Xsetlist({title: 'test'})
2199  getloclist(0, {title: 1})->assert_equal({title: 'test'})
2200
2201  Xsetlist = function('setqflist')
2202  Xsetlist([], ' ', {title: 'test'})
2203  getqflist({title: 1})->assert_equal({title: 'test'})
2204
2205  Xsetlist = function('setqflist', [[], ' '])
2206  Xsetlist({title: 'test'})
2207  getqflist({title: 1})->assert_equal({title: 'test'})
2208
2209  var Len: func: number = function('len', ['word'])
2210  assert_equal(4, Len())
2211enddef
2212
2213def Test_cmd_modifier()
2214  tab echo '0'
2215  CheckDefFailure(['5tab echo 3'], 'E16:')
2216enddef
2217
2218def Test_restore_modifiers()
2219  # check that when compiling a :def function command modifiers are not messed
2220  # up.
2221  var lines =<< trim END
2222      vim9script
2223      set eventignore=
2224      autocmd QuickFixCmdPost * copen
2225      def AutocmdsDisabled()
2226        eval 0
2227      enddef
2228      func Func()
2229        noautocmd call s:AutocmdsDisabled()
2230        let g:ei_after = &eventignore
2231      endfunc
2232      Func()
2233  END
2234  CheckScriptSuccess(lines)
2235  g:ei_after->assert_equal('')
2236enddef
2237
2238def StackTop()
2239  eval 1
2240  eval 2
2241  # call not on fourth line
2242  StackBot()
2243enddef
2244
2245def StackBot()
2246  # throw an error
2247  eval [][0]
2248enddef
2249
2250def Test_callstack_def()
2251  try
2252    StackTop()
2253  catch
2254    v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
2255  endtry
2256enddef
2257
2258" Re-using spot for variable used in block
2259def Test_block_scoped_var()
2260  var lines =<< trim END
2261      vim9script
2262      def Func()
2263        var x = ['a', 'b', 'c']
2264        if 1
2265          var y = 'x'
2266          map(x, () => y)
2267        endif
2268        var z = x
2269        assert_equal(['x', 'x', 'x'], z)
2270      enddef
2271      Func()
2272  END
2273  CheckScriptSuccess(lines)
2274enddef
2275
2276def Test_reset_did_emsg()
2277  var lines =<< trim END
2278      @s = 'blah'
2279      au BufWinLeave * #
2280      def Func()
2281        var winid = popup_create('popup', {})
2282        exe '*s'
2283        popup_close(winid)
2284      enddef
2285      Func()
2286  END
2287  CheckScriptFailure(lines, 'E492:', 8)
2288  delfunc! g:Func
2289enddef
2290
2291def Test_did_emsg_reset()
2292  # executing an autocommand resets did_emsg, this should not result in a
2293  # builtin function considered failing
2294  var lines =<< trim END
2295      vim9script
2296      au BufWinLeave * #
2297      def Func()
2298          popup_menu('', {callback: () => popup_create('', {})->popup_close()})
2299          eval [][0]
2300      enddef
2301      nno <F3> <cmd>call <sid>Func()<cr>
2302      feedkeys("\<F3>\e", 'xt')
2303  END
2304  writefile(lines, 'XemsgReset')
2305  assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
2306  delete('XemsgReset')
2307  nunmap <F3>
2308  au! BufWinLeave
2309enddef
2310
2311def Test_abort_with_silent_call()
2312  var lines =<< trim END
2313      vim9script
2314      g:result = 'none'
2315      def Func()
2316        g:result += 3
2317        g:result = 'yes'
2318      enddef
2319      # error is silenced, but function aborts on error
2320      silent! Func()
2321      assert_equal('none', g:result)
2322      unlet g:result
2323  END
2324  CheckScriptSuccess(lines)
2325enddef
2326
2327def Test_continues_with_silent_error()
2328  var lines =<< trim END
2329      vim9script
2330      g:result = 'none'
2331      def Func()
2332        silent!  g:result += 3
2333        g:result = 'yes'
2334      enddef
2335      # error is silenced, function does not abort
2336      Func()
2337      assert_equal('yes', g:result)
2338      unlet g:result
2339  END
2340  CheckScriptSuccess(lines)
2341enddef
2342
2343def Test_abort_even_with_silent()
2344  var lines =<< trim END
2345      vim9script
2346      g:result = 'none'
2347      def Func()
2348        eval {-> ''}() .. '' .. {}['X']
2349        g:result = 'yes'
2350      enddef
2351      silent! Func()
2352      assert_equal('none', g:result)
2353      unlet g:result
2354  END
2355  CheckScriptSuccess(lines)
2356enddef
2357
2358def Test_cmdmod_silent_restored()
2359  var lines =<< trim END
2360      vim9script
2361      def Func()
2362        g:result = 'none'
2363        silent! g:result += 3
2364        g:result = 'none'
2365        g:result += 3
2366      enddef
2367      Func()
2368  END
2369  # can't use CheckScriptFailure, it ignores the :silent!
2370  var fname = 'Xdefsilent'
2371  writefile(lines, fname)
2372  var caught = 'no'
2373  try
2374    exe 'source ' .. fname
2375  catch /E1030:/
2376    caught = 'yes'
2377    assert_match('Func, line 4', v:throwpoint)
2378  endtry
2379  assert_equal('yes', caught)
2380  delete(fname)
2381enddef
2382
2383def Test_cmdmod_silent_nested()
2384  var lines =<< trim END
2385      vim9script
2386      var result = ''
2387
2388      def Error()
2389          result ..= 'Eb'
2390          eval [][0]
2391          result ..= 'Ea'
2392      enddef
2393
2394      def Crash()
2395          result ..= 'Cb'
2396          sil! Error()
2397          result ..= 'Ca'
2398      enddef
2399
2400      Crash()
2401      assert_equal('CbEbEaCa', result)
2402  END
2403  CheckScriptSuccess(lines)
2404enddef
2405
2406def Test_dict_member_with_silent()
2407  var lines =<< trim END
2408      vim9script
2409      g:result = 'none'
2410      var d: dict<any>
2411      def Func()
2412        try
2413          g:result = map([], (_, v) => ({}[v]))->join() .. d['']
2414        catch
2415        endtry
2416      enddef
2417      silent! Func()
2418      assert_equal('0', g:result)
2419      unlet g:result
2420  END
2421  CheckScriptSuccess(lines)
2422enddef
2423
2424def Test_skip_cmds_with_silent()
2425  var lines =<< trim END
2426      vim9script
2427
2428      def Func(b: bool)
2429        Crash()
2430      enddef
2431
2432      def Crash()
2433        sil! :/not found/d _
2434        sil! :/not found/put _
2435      enddef
2436
2437      Func(true)
2438  END
2439  CheckScriptSuccess(lines)
2440enddef
2441
2442def Test_opfunc()
2443  nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
2444  def g:Opfunc(_: any): string
2445    setline(1, 'ASDF')
2446    return ''
2447  enddef
2448  new
2449  setline(1, 'asdf')
2450  feedkeys("\<F3>$", 'x')
2451  assert_equal('ASDF', getline(1))
2452
2453  bwipe!
2454  nunmap <F3>
2455enddef
2456
2457" this was crashing on exit
2458def Test_nested_lambda_in_closure()
2459  var lines =<< trim END
2460      vim9script
2461      def Outer()
2462          def g:Inner()
2463              echo map([1, 2, 3], {_, v -> v + 1})
2464          enddef
2465          g:Inner()
2466      enddef
2467      defcompile
2468      writefile(['Done'], 'XnestedDone')
2469      quit
2470  END
2471  if !RunVim([], lines, '--clean')
2472    return
2473  endif
2474  assert_equal(['Done'], readfile('XnestedDone'))
2475  delete('XnestedDone')
2476enddef
2477
2478def Test_check_func_arg_types()
2479  var lines =<< trim END
2480      vim9script
2481      def F1(x: string): string
2482        return x
2483      enddef
2484
2485      def F2(x: number): number
2486        return x + 1
2487      enddef
2488
2489      def G(g: func): dict<func>
2490        return {f: g}
2491      enddef
2492
2493      def H(d: dict<func>): string
2494        return d.f('a')
2495      enddef
2496  END
2497
2498  CheckScriptSuccess(lines + ['echo H(G(F1))'])
2499  CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
2500enddef
2501
2502
2503
2504" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
2505