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  var text = ''
35  for loop in range(100)
36    text = ''
37    for i in range(1, 9)
38      text ..= term_getline(buf, i)
39    endfor
40    if text =~ 'Error detected'
41      break
42    endif
43    sleep 20m
44  endfor
45  assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text)
46
47  # clean up
48  call StopVimInTerminal(buf)
49  call delete('XTest_compile_error')
50enddef
51
52def ReturnString(): string
53  return 'string'
54enddef
55
56def ReturnNumber(): number
57  return 123
58enddef
59
60let g:notNumber = 'string'
61
62def ReturnGlobal(): number
63  return g:notNumber
64enddef
65
66def Test_return_something()
67  ReturnString()->assert_equal('string')
68  ReturnNumber()->assert_equal(123)
69  assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
70enddef
71
72def Test_missing_return()
73  CheckDefFailure(['def Missing(): number',
74                   '  if g:cond',
75                   '    echo "no return"',
76                   '  else',
77                   '    return 0',
78                   '  endif'
79                   'enddef'], 'E1027:')
80  CheckDefFailure(['def Missing(): number',
81                   '  if g:cond',
82                   '    return 1',
83                   '  else',
84                   '    echo "no return"',
85                   '  endif'
86                   'enddef'], 'E1027:')
87  CheckDefFailure(['def Missing(): number',
88                   '  if g:cond',
89                   '    return 1',
90                   '  else',
91                   '    return 2',
92                   '  endif'
93                   '  return 3'
94                   'enddef'], 'E1095:')
95enddef
96
97def Test_return_bool()
98  var lines =<< trim END
99      vim9script
100      def MenuFilter(id: number, key: string): bool
101        return popup_filter_menu(id, key)
102      enddef
103      def YesnoFilter(id: number, key: string): bool
104        return popup_filter_yesno(id, key)
105      enddef
106      defcompile
107  END
108  CheckScriptSuccess(lines)
109enddef
110
111let s:nothing = 0
112def ReturnNothing()
113  s:nothing = 1
114  if true
115    return
116  endif
117  s:nothing = 2
118enddef
119
120def Test_return_nothing()
121  ReturnNothing()
122  s:nothing->assert_equal(1)
123enddef
124
125func Increment()
126  let g:counter += 1
127endfunc
128
129def Test_call_ufunc_count()
130  g:counter = 1
131  Increment()
132  Increment()
133  Increment()
134  # works with and without :call
135  g:counter->assert_equal(4)
136  eval g:counter->assert_equal(4)
137  unlet g:counter
138enddef
139
140def MyVarargs(arg: string, ...rest: list<string>): string
141  var res = arg
142  for s in rest
143    res ..= ',' .. s
144  endfor
145  return res
146enddef
147
148def Test_call_varargs()
149  MyVarargs('one')->assert_equal('one')
150  MyVarargs('one', 'two')->assert_equal('one,two')
151  MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
152enddef
153
154def MyDefaultArgs(name = 'string'): string
155  return name
156enddef
157
158def MyDefaultSecond(name: string, second: bool  = true): string
159  return second ? name : 'none'
160enddef
161
162def Test_call_default_args()
163  MyDefaultArgs()->assert_equal('string')
164  MyDefaultArgs('one')->assert_equal('one')
165  assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
166
167  MyDefaultSecond('test')->assert_equal('test')
168  MyDefaultSecond('test', true)->assert_equal('test')
169  MyDefaultSecond('test', false)->assert_equal('none')
170
171  CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
172  CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
173enddef
174
175def Test_nested_function()
176  def Nested(arg: string): string
177    return 'nested ' .. arg
178  enddef
179  Nested('function')->assert_equal('nested function')
180
181  CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
182  CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
183
184  CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
185  CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
186  CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
187
188  CheckDefFailure([
189        'def Outer()',
190        '  def Inner()',
191        '    # comment',
192        '  enddef',
193        '  def Inner()',
194        '  enddef',
195        'enddef'], 'E1073:')
196  CheckDefFailure([
197        'def Outer()',
198        '  def Inner()',
199        '    # comment',
200        '  enddef',
201        '  def! Inner()',
202        '  enddef',
203        'enddef'], 'E1117:')
204enddef
205
206func Test_call_default_args_from_func()
207  call MyDefaultArgs()->assert_equal('string')
208  call MyDefaultArgs('one')->assert_equal('one')
209  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
210endfunc
211
212def Test_nested_global_function()
213  var lines =<< trim END
214      vim9script
215      def Outer()
216          def g:Inner(): string
217              return 'inner'
218          enddef
219      enddef
220      defcompile
221      Outer()
222      g:Inner()->assert_equal('inner')
223      delfunc g:Inner
224      Outer()
225      g:Inner()->assert_equal('inner')
226      delfunc g:Inner
227      Outer()
228      g:Inner()->assert_equal('inner')
229      delfunc g:Inner
230  END
231  CheckScriptSuccess(lines)
232
233  lines =<< trim END
234      vim9script
235      def Outer()
236          def g:Inner(): string
237              return 'inner'
238          enddef
239      enddef
240      defcompile
241      Outer()
242      Outer()
243  END
244  CheckScriptFailure(lines, "E122:")
245
246  lines =<< trim END
247      vim9script
248      def Func()
249        echo 'script'
250      enddef
251      def Outer()
252        def Func()
253          echo 'inner'
254        enddef
255      enddef
256      defcompile
257  END
258  CheckScriptFailure(lines, "E1073:")
259enddef
260
261def Test_global_local_function()
262  var lines =<< trim END
263      vim9script
264      def g:Func(): string
265          return 'global'
266      enddef
267      def Func(): string
268          return 'local'
269      enddef
270      g:Func()->assert_equal('global')
271      Func()->assert_equal('local')
272  END
273  CheckScriptSuccess(lines)
274
275  lines =<< trim END
276      vim9script
277      def g:Funcy()
278        echo 'funcy'
279      enddef
280      s:Funcy()
281  END
282  CheckScriptFailure(lines, 'E117:')
283enddef
284
285def Test_local_function_shadows_global()
286  var lines =<< trim END
287      vim9script
288      def g:Gfunc(): string
289        return 'global'
290      enddef
291      def AnotherFunc(): number
292        var Gfunc = function('len')
293        return Gfunc('testing')
294      enddef
295      g:Gfunc()->assert_equal('global')
296      AnotherFunc()->assert_equal(7)
297      delfunc g:Gfunc
298  END
299  CheckScriptSuccess(lines)
300
301  lines =<< trim END
302      vim9script
303      def g:Func(): string
304        return 'global'
305      enddef
306      def AnotherFunc()
307        g:Func = function('len')
308      enddef
309      AnotherFunc()
310  END
311  CheckScriptFailure(lines, 'E705:')
312  delfunc g:Func
313enddef
314
315func TakesOneArg(arg)
316  echo a:arg
317endfunc
318
319def Test_call_wrong_args()
320  CheckDefFailure(['TakesOneArg()'], 'E119:')
321  CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
322  CheckDefFailure(['bufnr(xxx)'], 'E1001:')
323  CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
324
325  var lines =<< trim END
326    vim9script
327    def Func(s: string)
328      echo s
329    enddef
330    Func([])
331  END
332  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
333
334  lines =<< trim END
335    vim9script
336    def FuncOne(nr: number)
337      echo nr
338    enddef
339    def FuncTwo()
340      FuncOne()
341    enddef
342    defcompile
343  END
344  writefile(lines, 'Xscript')
345  var didCatch = false
346  try
347    source Xscript
348  catch
349    assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
350    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
351    didCatch = true
352  endtry
353  assert_true(didCatch)
354
355  lines =<< trim END
356    vim9script
357    def FuncOne(nr: number)
358      echo nr
359    enddef
360    def FuncTwo()
361      FuncOne(1, 2)
362    enddef
363    defcompile
364  END
365  writefile(lines, 'Xscript')
366  didCatch = false
367  try
368    source Xscript
369  catch
370    assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
371    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
372    didCatch = true
373  endtry
374  assert_true(didCatch)
375
376  delete('Xscript')
377enddef
378
379def Test_call_lambda_args()
380  CheckDefFailure(['echo {i -> 0}()'],
381                  'E119: Not enough arguments for function: {i -> 0}()')
382
383  var lines =<< trim END
384      var Ref = {x: number, y: number -> x + y}
385      echo Ref(1, 'x')
386  END
387  CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
388enddef
389
390" Default arg and varargs
391def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
392  var res = one .. ',' .. two
393  for s in rest
394    res ..= ',' .. s
395  endfor
396  return res
397enddef
398
399def Test_call_def_varargs()
400  assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
401  MyDefVarargs('one')->assert_equal('one,foo')
402  MyDefVarargs('one', 'two')->assert_equal('one,two')
403  MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
404  CheckDefFailure(['MyDefVarargs("one", 22)'],
405      'E1013: Argument 2: type mismatch, expected string but got number')
406  CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
407      'E1013: Argument 3: type mismatch, expected string but got number')
408
409  var lines =<< trim END
410      vim9script
411      def Func(...l: list<string>)
412        echo l
413      enddef
414      Func('a', 'b', 'c')
415  END
416  CheckScriptSuccess(lines)
417
418  lines =<< trim END
419      vim9script
420      def Func(...l: list<string>)
421        echo l
422      enddef
423      Func()
424  END
425  CheckScriptSuccess(lines)
426
427  lines =<< trim END
428      vim9script
429      def Func(...l: any)
430        echo l
431      enddef
432      Func(0)
433  END
434  CheckScriptSuccess(lines)
435
436  lines =<< trim END
437      vim9script
438      def Func(..._l: list<string>)
439        echo _l
440      enddef
441      Func('a', 'b', 'c')
442  END
443  CheckScriptSuccess(lines)
444
445  lines =<< trim END
446      vim9script
447      def Func(...l: list<string>)
448        echo l
449      enddef
450      Func(1, 2, 3)
451  END
452  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
453
454  lines =<< trim END
455      vim9script
456      def Func(...l: list<string>)
457        echo l
458      enddef
459      Func('a', 9)
460  END
461  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
462
463  lines =<< trim END
464      vim9script
465      def Func(...l: list<string>)
466        echo l
467      enddef
468      Func(1, 'a')
469  END
470  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
471enddef
472
473let s:value = ''
474
475def FuncOneDefArg(opt = 'text')
476  s:value = opt
477enddef
478
479def FuncTwoDefArg(nr = 123, opt = 'text'): string
480  return nr .. opt
481enddef
482
483def FuncVarargs(...arg: list<string>): string
484  return join(arg, ',')
485enddef
486
487def Test_func_type_varargs()
488  var RefDefArg: func(?string)
489  RefDefArg = FuncOneDefArg
490  RefDefArg()
491  s:value->assert_equal('text')
492  RefDefArg('some')
493  s:value->assert_equal('some')
494
495  var RefDef2Arg: func(?number, ?string): string
496  RefDef2Arg = FuncTwoDefArg
497  RefDef2Arg()->assert_equal('123text')
498  RefDef2Arg(99)->assert_equal('99text')
499  RefDef2Arg(77, 'some')->assert_equal('77some')
500
501  CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
502  CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
503
504  var RefVarargs: func(...list<string>): string
505  RefVarargs = FuncVarargs
506  RefVarargs()->assert_equal('')
507  RefVarargs('one')->assert_equal('one')
508  RefVarargs('one', 'two')->assert_equal('one,two')
509
510  CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
511  CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
512enddef
513
514" Only varargs
515def MyVarargsOnly(...args: list<string>): string
516  return join(args, ',')
517enddef
518
519def Test_call_varargs_only()
520  MyVarargsOnly()->assert_equal('')
521  MyVarargsOnly('one')->assert_equal('one')
522  MyVarargsOnly('one', 'two')->assert_equal('one,two')
523  CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
524  CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
525enddef
526
527def Test_using_var_as_arg()
528  writefile(['def Func(x: number)',  'var x = 234', 'enddef', 'defcompile'], 'Xdef')
529  assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
530  delete('Xdef')
531enddef
532
533def DictArg(arg: dict<string>)
534  arg['key'] = 'value'
535enddef
536
537def ListArg(arg: list<string>)
538  arg[0] = 'value'
539enddef
540
541def Test_assign_to_argument()
542  # works for dict and list
543  var d: dict<string> = {}
544  DictArg(d)
545  d['key']->assert_equal('value')
546  var l: list<string> = []
547  ListArg(l)
548  l[0]->assert_equal('value')
549
550  CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
551enddef
552
553" These argument names are reserved in legacy functions.
554def WithReservedNames(firstline: string, lastline: string): string
555  return firstline .. lastline
556enddef
557
558def Test_argument_names()
559  assert_equal('OK', WithReservedNames('O', 'K'))
560enddef
561
562def Test_call_func_defined_later()
563  g:DefinedLater('one')->assert_equal('one')
564  assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
565enddef
566
567func DefinedLater(arg)
568  return a:arg
569endfunc
570
571def Test_call_funcref()
572  g:SomeFunc('abc')->assert_equal(3)
573  assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
574  assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
575
576  var lines =<< trim END
577    vim9script
578    def RetNumber(): number
579      return 123
580    enddef
581    var Funcref: func: number = function('RetNumber')
582    Funcref()->assert_equal(123)
583  END
584  CheckScriptSuccess(lines)
585
586  lines =<< trim END
587    vim9script
588    def RetNumber(): number
589      return 123
590    enddef
591    def Bar(F: func: number): number
592      return F()
593    enddef
594    var Funcref = function('RetNumber')
595    Bar(Funcref)->assert_equal(123)
596  END
597  CheckScriptSuccess(lines)
598
599  lines =<< trim END
600    vim9script
601    def UseNumber(nr: number)
602      echo nr
603    enddef
604    var Funcref: func(number) = function('UseNumber')
605    Funcref(123)
606  END
607  CheckScriptSuccess(lines)
608
609  lines =<< trim END
610    vim9script
611    def UseNumber(nr: number)
612      echo nr
613    enddef
614    var Funcref: func(string) = function('UseNumber')
615  END
616  CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
617
618  lines =<< trim END
619    vim9script
620    def EchoNr(nr = 34)
621      g:echo = nr
622    enddef
623    var Funcref: func(?number) = function('EchoNr')
624    Funcref()
625    g:echo->assert_equal(34)
626    Funcref(123)
627    g:echo->assert_equal(123)
628  END
629  CheckScriptSuccess(lines)
630
631  lines =<< trim END
632    vim9script
633    def EchoList(...l: list<number>)
634      g:echo = l
635    enddef
636    var Funcref: func(...list<number>) = function('EchoList')
637    Funcref()
638    g:echo->assert_equal([])
639    Funcref(1, 2, 3)
640    g:echo->assert_equal([1, 2, 3])
641  END
642  CheckScriptSuccess(lines)
643
644  lines =<< trim END
645    vim9script
646    def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
647      g:optarg = opt
648      g:listarg = l
649      return nr
650    enddef
651    var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
652    Funcref(10)->assert_equal(10)
653    g:optarg->assert_equal(12)
654    g:listarg->assert_equal([])
655
656    Funcref(11, 22)->assert_equal(11)
657    g:optarg->assert_equal(22)
658    g:listarg->assert_equal([])
659
660    Funcref(17, 18, 1, 2, 3)->assert_equal(17)
661    g:optarg->assert_equal(18)
662    g:listarg->assert_equal([1, 2, 3])
663  END
664  CheckScriptSuccess(lines)
665enddef
666
667let SomeFunc = function('len')
668let NotAFunc = 'text'
669
670def CombineFuncrefTypes()
671  # same arguments, different return type
672  var Ref1: func(bool): string
673  var Ref2: func(bool): number
674  var Ref3: func(bool): any
675  Ref3 = g:cond ? Ref1 : Ref2
676
677  # different number of arguments
678  var Refa1: func(bool): number
679  var Refa2: func(bool, number): number
680  var Refa3: func: number
681  Refa3 = g:cond ? Refa1 : Refa2
682
683  # different argument types
684  var Refb1: func(bool, string): number
685  var Refb2: func(string, number): number
686  var Refb3: func(any, any): number
687  Refb3 = g:cond ? Refb1 : Refb2
688enddef
689
690def FuncWithForwardCall()
691  return g:DefinedEvenLater("yes")
692enddef
693
694def DefinedEvenLater(arg: string): string
695  return arg
696enddef
697
698def Test_error_in_nested_function()
699  # Error in called function requires unwinding the call stack.
700  assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
701enddef
702
703def Test_return_type_wrong()
704  CheckScriptFailure([
705        'def Func(): number',
706        'return "a"',
707        'enddef',
708        'defcompile'], 'expected number but got string')
709  CheckScriptFailure([
710        'def Func(): string',
711        'return 1',
712        'enddef',
713        'defcompile'], 'expected string but got number')
714  CheckScriptFailure([
715        'def Func(): void',
716        'return "a"',
717        'enddef',
718        'defcompile'],
719        'E1096: Returning a value in a function without a return type')
720  CheckScriptFailure([
721        'def Func()',
722        'return "a"',
723        'enddef',
724        'defcompile'],
725        'E1096: Returning a value in a function without a return type')
726
727  CheckScriptFailure([
728        'def Func(): number',
729        'return',
730        'enddef',
731        'defcompile'], 'E1003:')
732
733  CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
734  CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
735  CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
736
737  CheckScriptFailure([
738        'vim9script',
739        'def FuncB()',
740        '  return 123',
741        'enddef',
742        'def FuncA()',
743        '   FuncB()',
744        'enddef',
745        'defcompile'], 'E1096:')
746enddef
747
748def Test_arg_type_wrong()
749  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
750  CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
751  CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
752  CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
753enddef
754
755def Test_vim9script_call()
756  var lines =<< trim END
757    vim9script
758    var name = ''
759    def MyFunc(arg: string)
760       name = arg
761    enddef
762    MyFunc('foobar')
763    name->assert_equal('foobar')
764
765    var str = 'barfoo'
766    str->MyFunc()
767    name->assert_equal('barfoo')
768
769    g:value = 'value'
770    g:value->MyFunc()
771    name->assert_equal('value')
772
773    var listvar = []
774    def ListFunc(arg: list<number>)
775       listvar = arg
776    enddef
777    [1, 2, 3]->ListFunc()
778    listvar->assert_equal([1, 2, 3])
779
780    var dictvar = {}
781    def DictFunc(arg: dict<number>)
782       dictvar = arg
783    enddef
784    {'a': 1, 'b': 2}->DictFunc()
785    dictvar->assert_equal(#{a: 1, b: 2})
786    def CompiledDict()
787      {'a': 3, 'b': 4}->DictFunc()
788    enddef
789    CompiledDict()
790    dictvar->assert_equal(#{a: 3, b: 4})
791
792    #{a: 3, b: 4}->DictFunc()
793    dictvar->assert_equal(#{a: 3, b: 4})
794
795    ('text')->MyFunc()
796    name->assert_equal('text')
797    ("some")->MyFunc()
798    name->assert_equal('some')
799
800    # line starting with single quote is not a mark
801    # line starting with double quote can be a method call
802    'asdfasdf'->MyFunc()
803    name->assert_equal('asdfasdf')
804    "xyz"->MyFunc()
805    name->assert_equal('xyz')
806
807    def UseString()
808      'xyork'->MyFunc()
809    enddef
810    UseString()
811    name->assert_equal('xyork')
812
813    def UseString2()
814      "knife"->MyFunc()
815    enddef
816    UseString2()
817    name->assert_equal('knife')
818
819    # prepending a colon makes it a mark
820    new
821    setline(1, ['aaa', 'bbb', 'ccc'])
822    normal! 3Gmt1G
823    :'t
824    getcurpos()[1]->assert_equal(3)
825    bwipe!
826
827    MyFunc(
828        'continued'
829        )
830    assert_equal('continued',
831            name
832            )
833
834    call MyFunc(
835        'more'
836          ..
837          'lines'
838        )
839    assert_equal(
840        'morelines',
841        name)
842  END
843  writefile(lines, 'Xcall.vim')
844  source Xcall.vim
845  delete('Xcall.vim')
846enddef
847
848def Test_vim9script_call_fail_decl()
849  var lines =<< trim END
850    vim9script
851    var name = ''
852    def MyFunc(arg: string)
853       var name = 123
854    enddef
855    defcompile
856  END
857  CheckScriptFailure(lines, 'E1054:')
858enddef
859
860def Test_vim9script_call_fail_type()
861  var lines =<< trim END
862    vim9script
863    def MyFunc(arg: string)
864      echo arg
865    enddef
866    MyFunc(1234)
867  END
868  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
869enddef
870
871def Test_vim9script_call_fail_const()
872  var lines =<< trim END
873    vim9script
874    const var = ''
875    def MyFunc(arg: string)
876       var = 'asdf'
877    enddef
878    defcompile
879  END
880  writefile(lines, 'Xcall_const.vim')
881  assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
882  delete('Xcall_const.vim')
883enddef
884
885" Test that inside :function a Python function can be defined, :def is not
886" recognized.
887func Test_function_python()
888  CheckFeature python3
889  let py = 'python3'
890  execute py "<< EOF"
891def do_something():
892  return 1
893EOF
894endfunc
895
896def Test_delfunc()
897  var lines =<< trim END
898    vim9script
899    def g:GoneSoon()
900      echo 'hello'
901    enddef
902
903    def CallGoneSoon()
904      GoneSoon()
905    enddef
906    defcompile
907
908    delfunc g:GoneSoon
909    CallGoneSoon()
910  END
911  writefile(lines, 'XToDelFunc')
912  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
913  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
914
915  delete('XToDelFunc')
916enddef
917
918def Test_redef_failure()
919  writefile(['def Func0(): string',  'return "Func0"', 'enddef'], 'Xdef')
920  so Xdef
921  writefile(['def Func1(): string',  'return "Func1"', 'enddef'], 'Xdef')
922  so Xdef
923  writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
924  assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
925  writefile(['def Func2(): string',  'return "Func2"', 'enddef'], 'Xdef')
926  so Xdef
927  delete('Xdef')
928
929  g:Func0()->assert_equal(0)
930  g:Func1()->assert_equal('Func1')
931  g:Func2()->assert_equal('Func2')
932
933  delfunc! Func0
934  delfunc! Func1
935  delfunc! Func2
936enddef
937
938def Test_vim9script_func()
939  var lines =<< trim END
940    vim9script
941    func Func(arg)
942      echo a:arg
943    endfunc
944    Func('text')
945  END
946  writefile(lines, 'XVim9Func')
947  so XVim9Func
948
949  delete('XVim9Func')
950enddef
951
952let s:funcResult = 0
953
954def FuncNoArgNoRet()
955  s:funcResult = 11
956enddef
957
958def FuncNoArgRetNumber(): number
959  s:funcResult = 22
960  return 1234
961enddef
962
963def FuncNoArgRetString(): string
964  s:funcResult = 45
965  return 'text'
966enddef
967
968def FuncOneArgNoRet(arg: number)
969  s:funcResult = arg
970enddef
971
972def FuncOneArgRetNumber(arg: number): number
973  s:funcResult = arg
974  return arg
975enddef
976
977def FuncTwoArgNoRet(one: bool, two: number)
978  s:funcResult = two
979enddef
980
981def FuncOneArgRetString(arg: string): string
982  return arg
983enddef
984
985def FuncOneArgRetAny(arg: any): any
986  return arg
987enddef
988
989def Test_func_type()
990  var Ref1: func()
991  s:funcResult = 0
992  Ref1 = FuncNoArgNoRet
993  Ref1()
994  s:funcResult->assert_equal(11)
995
996  var Ref2: func
997  s:funcResult = 0
998  Ref2 = FuncNoArgNoRet
999  Ref2()
1000  s:funcResult->assert_equal(11)
1001
1002  s:funcResult = 0
1003  Ref2 = FuncOneArgNoRet
1004  Ref2(12)
1005  s:funcResult->assert_equal(12)
1006
1007  s:funcResult = 0
1008  Ref2 = FuncNoArgRetNumber
1009  Ref2()->assert_equal(1234)
1010  s:funcResult->assert_equal(22)
1011
1012  s:funcResult = 0
1013  Ref2 = FuncOneArgRetNumber
1014  Ref2(13)->assert_equal(13)
1015  s:funcResult->assert_equal(13)
1016enddef
1017
1018def Test_repeat_return_type()
1019  var res = 0
1020  for n in repeat([1], 3)
1021    res += n
1022  endfor
1023  res->assert_equal(3)
1024
1025  res = 0
1026  for n in add([1, 2], 3)
1027    res += n
1028  endfor
1029  res->assert_equal(6)
1030enddef
1031
1032def Test_argv_return_type()
1033  next fileone filetwo
1034  var res = ''
1035  for name in argv()
1036    res ..= name
1037  endfor
1038  res->assert_equal('fileonefiletwo')
1039enddef
1040
1041def Test_func_type_part()
1042  var RefVoid: func: void
1043  RefVoid = FuncNoArgNoRet
1044  RefVoid = FuncOneArgNoRet
1045  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1046  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
1047
1048  var RefAny: func(): any
1049  RefAny = FuncNoArgRetNumber
1050  RefAny = FuncNoArgRetString
1051  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1052  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
1053
1054  var RefAnyNoArgs: func: any = RefAny
1055
1056  var RefNr: func: number
1057  RefNr = FuncNoArgRetNumber
1058  RefNr = FuncOneArgRetNumber
1059  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1060  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
1061
1062  var RefStr: func: string
1063  RefStr = FuncNoArgRetString
1064  RefStr = FuncOneArgRetString
1065  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1066  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
1067enddef
1068
1069def Test_func_type_fails()
1070  CheckDefFailure(['var ref1: func()'], 'E704:')
1071
1072  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1073  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1074  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1075  CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1076  CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1077  CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
1078
1079  CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1080  CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1081  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:')
1082  CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
1083enddef
1084
1085def Test_func_return_type()
1086  var nr: number
1087  nr = FuncNoArgRetNumber()
1088  nr->assert_equal(1234)
1089
1090  nr = FuncOneArgRetAny(122)
1091  nr->assert_equal(122)
1092
1093  var str: string
1094  str = FuncOneArgRetAny('yes')
1095  str->assert_equal('yes')
1096
1097  CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
1098enddef
1099
1100def Test_func_common_type()
1101  def FuncOne(n: number): number
1102    return n
1103  enddef
1104  def FuncTwo(s: string): number
1105    return len(s)
1106  enddef
1107  def FuncThree(n: number, s: string): number
1108    return n + len(s)
1109  enddef
1110  var list = [FuncOne, FuncTwo, FuncThree]
1111  assert_equal(8, list[0](8))
1112  assert_equal(4, list[1]('word'))
1113  assert_equal(7, list[2](3, 'word'))
1114enddef
1115
1116def MultiLine(
1117    arg1: string,
1118    arg2 = 1234,
1119    ...rest: list<string>
1120      ): string
1121  return arg1 .. arg2 .. join(rest, '-')
1122enddef
1123
1124def MultiLineComment(
1125    arg1: string, # comment
1126    arg2 = 1234, # comment
1127    ...rest: list<string> # comment
1128      ): string # comment
1129  return arg1 .. arg2 .. join(rest, '-')
1130enddef
1131
1132def Test_multiline()
1133  MultiLine('text')->assert_equal('text1234')
1134  MultiLine('text', 777)->assert_equal('text777')
1135  MultiLine('text', 777, 'one')->assert_equal('text777one')
1136  MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
1137enddef
1138
1139func Test_multiline_not_vim9()
1140  call MultiLine('text')->assert_equal('text1234')
1141  call MultiLine('text', 777)->assert_equal('text777')
1142  call MultiLine('text', 777, 'one')->assert_equal('text777one')
1143  call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
1144endfunc
1145
1146
1147" When using CheckScriptFailure() for the below test, E1010 is generated instead
1148" of E1056.
1149func Test_E1056_1059()
1150  let caught_1056 = 0
1151  try
1152    def F():
1153      return 1
1154    enddef
1155  catch /E1056:/
1156    let caught_1056 = 1
1157  endtry
1158  eval caught_1056->assert_equal(1)
1159
1160  let caught_1059 = 0
1161  try
1162    def F5(items : list)
1163      echo 'a'
1164    enddef
1165  catch /E1059:/
1166    let caught_1059 = 1
1167  endtry
1168  eval caught_1059->assert_equal(1)
1169endfunc
1170
1171func DelMe()
1172  echo 'DelMe'
1173endfunc
1174
1175def Test_error_reporting()
1176  # comment lines at the start of the function
1177  var lines =<< trim END
1178    " comment
1179    def Func()
1180      # comment
1181      # comment
1182      invalid
1183    enddef
1184    defcompile
1185  END
1186  writefile(lines, 'Xdef')
1187  try
1188    source Xdef
1189    assert_report('should have failed')
1190  catch /E476:/
1191    v:exception->assert_match('Invalid command: invalid')
1192    v:throwpoint->assert_match(', line 3$')
1193  endtry
1194
1195  # comment lines after the start of the function
1196  lines =<< trim END
1197    " comment
1198    def Func()
1199      var x = 1234
1200      # comment
1201      # comment
1202      invalid
1203    enddef
1204    defcompile
1205  END
1206  writefile(lines, 'Xdef')
1207  try
1208    source Xdef
1209    assert_report('should have failed')
1210  catch /E476:/
1211    v:exception->assert_match('Invalid command: invalid')
1212    v:throwpoint->assert_match(', line 4$')
1213  endtry
1214
1215  lines =<< trim END
1216    vim9script
1217    def Func()
1218      var db = #{foo: 1, bar: 2}
1219      # comment
1220      var x = db.asdf
1221    enddef
1222    defcompile
1223    Func()
1224  END
1225  writefile(lines, 'Xdef')
1226  try
1227    source Xdef
1228    assert_report('should have failed')
1229  catch /E716:/
1230    v:throwpoint->assert_match('_Func, line 3$')
1231  endtry
1232
1233  delete('Xdef')
1234enddef
1235
1236def Test_deleted_function()
1237  CheckDefExecFailure([
1238      'var RefMe: func = function("g:DelMe")',
1239      'delfunc g:DelMe',
1240      'echo RefMe()'], 'E117:')
1241enddef
1242
1243def Test_unknown_function()
1244  CheckDefExecFailure([
1245      'var Ref: func = function("NotExist")',
1246      'delfunc g:NotExist'], 'E700:')
1247enddef
1248
1249def RefFunc(Ref: func(string): string): string
1250  return Ref('more')
1251enddef
1252
1253def Test_closure_simple()
1254  var local = 'some '
1255  RefFunc({s -> local .. s})->assert_equal('some more')
1256enddef
1257
1258def MakeRef()
1259  var local = 'some '
1260  g:Ref = {s -> local .. s}
1261enddef
1262
1263def Test_closure_ref_after_return()
1264  MakeRef()
1265  g:Ref('thing')->assert_equal('some thing')
1266  unlet g:Ref
1267enddef
1268
1269def MakeTwoRefs()
1270  var local = ['some']
1271  g:Extend = {s -> local->add(s)}
1272  g:Read = {-> local}
1273enddef
1274
1275def Test_closure_two_refs()
1276  MakeTwoRefs()
1277  join(g:Read(), ' ')->assert_equal('some')
1278  g:Extend('more')
1279  join(g:Read(), ' ')->assert_equal('some more')
1280  g:Extend('even')
1281  join(g:Read(), ' ')->assert_equal('some more even')
1282
1283  unlet g:Extend
1284  unlet g:Read
1285enddef
1286
1287def ReadRef(Ref: func(): list<string>): string
1288  return join(Ref(), ' ')
1289enddef
1290
1291def ExtendRef(Ref: func(string): list<string>, add: string)
1292  Ref(add)
1293enddef
1294
1295def Test_closure_two_indirect_refs()
1296  MakeTwoRefs()
1297  ReadRef(g:Read)->assert_equal('some')
1298  ExtendRef(g:Extend, 'more')
1299  ReadRef(g:Read)->assert_equal('some more')
1300  ExtendRef(g:Extend, 'even')
1301  ReadRef(g:Read)->assert_equal('some more even')
1302
1303  unlet g:Extend
1304  unlet g:Read
1305enddef
1306
1307def MakeArgRefs(theArg: string)
1308  var local = 'loc_val'
1309  g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1310enddef
1311
1312def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
1313  var local = 'the_loc'
1314  g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1315enddef
1316
1317def Test_closure_using_argument()
1318  MakeArgRefs('arg_val')
1319  g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
1320
1321  MakeArgRefsVarargs('arg_val', 'one', 'two')
1322  g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
1323
1324  unlet g:UseArg
1325  unlet g:UseVararg
1326enddef
1327
1328def MakeGetAndAppendRefs()
1329  var local = 'a'
1330
1331  def Append(arg: string)
1332    local ..= arg
1333  enddef
1334  g:Append = Append
1335
1336  def Get(): string
1337    return local
1338  enddef
1339  g:Get = Get
1340enddef
1341
1342def Test_closure_append_get()
1343  MakeGetAndAppendRefs()
1344  g:Get()->assert_equal('a')
1345  g:Append('-b')
1346  g:Get()->assert_equal('a-b')
1347  g:Append('-c')
1348  g:Get()->assert_equal('a-b-c')
1349
1350  unlet g:Append
1351  unlet g:Get
1352enddef
1353
1354def Test_nested_closure()
1355  var local = 'text'
1356  def Closure(arg: string): string
1357    return local .. arg
1358  enddef
1359  Closure('!!!')->assert_equal('text!!!')
1360enddef
1361
1362func GetResult(Ref)
1363  return a:Ref('some')
1364endfunc
1365
1366def Test_call_closure_not_compiled()
1367  var text = 'text'
1368  g:Ref = {s ->  s .. text}
1369  GetResult(g:Ref)->assert_equal('sometext')
1370enddef
1371
1372def Test_double_closure_fails()
1373  var lines =<< trim END
1374    vim9script
1375    def Func()
1376      var name = 0
1377      for i in range(2)
1378          timer_start(0, {-> name})
1379      endfor
1380    enddef
1381    Func()
1382  END
1383  CheckScriptSuccess(lines)
1384enddef
1385
1386def Test_nested_closure_used()
1387  var lines =<< trim END
1388      vim9script
1389      def Func()
1390        var x = 'hello'
1391        var Closure = {-> x}
1392        g:Myclosure = {-> Closure()}
1393      enddef
1394      Func()
1395      assert_equal('hello', g:Myclosure())
1396  END
1397  CheckScriptSuccess(lines)
1398enddef
1399
1400def Test_nested_closure_fails()
1401  var lines =<< trim END
1402    vim9script
1403    def FuncA()
1404      FuncB(0)
1405    enddef
1406    def FuncB(n: number): list<string>
1407      return map([0], {_, v -> n})
1408    enddef
1409    FuncA()
1410  END
1411  CheckScriptFailure(lines, 'E1012:')
1412enddef
1413
1414def Test_nested_lambda()
1415  var lines =<< trim END
1416    vim9script
1417    def Func()
1418      var x = 4
1419      var Lambda1 = {-> 7}
1420      var Lambda2 = {-> [Lambda1(), x]}
1421      var res = Lambda2()
1422      assert_equal([7, 4], res)
1423    enddef
1424    Func()
1425  END
1426  CheckScriptSuccess(lines)
1427enddef
1428
1429def Line_continuation_in_def(dir: string = ''): string
1430  var path: string = empty(dir)
1431          \ ? 'empty'
1432          \ : 'full'
1433  return path
1434enddef
1435
1436def Test_line_continuation_in_def()
1437  Line_continuation_in_def('.')->assert_equal('full')
1438enddef
1439
1440def Line_continuation_in_lambda(): list<string>
1441  var x = range(97, 100)
1442      ->map({_, v -> nr2char(v)
1443          ->toupper()})
1444      ->reverse()
1445  return x
1446enddef
1447
1448def Test_line_continuation_in_lambda()
1449  Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
1450enddef
1451
1452func Test_silent_echo()
1453  CheckScreendump
1454
1455  let lines =<< trim END
1456    vim9script
1457    def EchoNothing()
1458      silent echo ''
1459    enddef
1460    defcompile
1461  END
1462  call writefile(lines, 'XTest_silent_echo')
1463
1464  " Check that the balloon shows up after a mouse move
1465  let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
1466  call term_sendkeys(buf, ":abc")
1467  call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1468
1469  " clean up
1470  call StopVimInTerminal(buf)
1471  call delete('XTest_silent_echo')
1472endfunc
1473
1474def SilentlyError()
1475  execute('silent! invalid')
1476  g:did_it = 'yes'
1477enddef
1478
1479func UserError()
1480  silent! invalid
1481endfunc
1482
1483def SilentlyUserError()
1484  UserError()
1485  g:did_it = 'yes'
1486enddef
1487
1488" This can't be a :def function, because the assert would not be reached.
1489func Test_ignore_silent_error()
1490  let g:did_it = 'no'
1491  call SilentlyError()
1492  call assert_equal('yes', g:did_it)
1493
1494  let g:did_it = 'no'
1495  call SilentlyUserError()
1496  call assert_equal('yes', g:did_it)
1497
1498  unlet g:did_it
1499endfunc
1500
1501def Test_ignore_silent_error_in_filter()
1502  var lines =<< trim END
1503      vim9script
1504      def Filter(winid: number, key: string): bool
1505          if key == 'o'
1506              silent! eval [][0]
1507              return true
1508          endif
1509          return popup_filter_menu(winid, key)
1510      enddef
1511
1512      popup_create('popup', #{filter: Filter})
1513      feedkeys("o\r", 'xnt')
1514  END
1515  CheckScriptSuccess(lines)
1516enddef
1517
1518def Fibonacci(n: number): number
1519  if n < 2
1520    return n
1521  else
1522    return Fibonacci(n - 1) + Fibonacci(n - 2)
1523  endif
1524enddef
1525
1526def Test_recursive_call()
1527  Fibonacci(20)->assert_equal(6765)
1528enddef
1529
1530def TreeWalk(dir: string): list<any>
1531  return readdir(dir)->map({_, val ->
1532            fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
1533               ? {val: TreeWalk(dir .. '/' .. val)}
1534               : val
1535             })
1536enddef
1537
1538def Test_closure_in_map()
1539  mkdir('XclosureDir/tdir', 'p')
1540  writefile(['111'], 'XclosureDir/file1')
1541  writefile(['222'], 'XclosureDir/file2')
1542  writefile(['333'], 'XclosureDir/tdir/file3')
1543
1544  TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
1545
1546  delete('XclosureDir', 'rf')
1547enddef
1548
1549def Test_invalid_function_name()
1550  var lines =<< trim END
1551      vim9script
1552      def s: list<string>
1553  END
1554  CheckScriptFailure(lines, 'E129:')
1555
1556  lines =<< trim END
1557      vim9script
1558      def g: list<string>
1559  END
1560  CheckScriptFailure(lines, 'E129:')
1561
1562  lines =<< trim END
1563      vim9script
1564      def <SID>: list<string>
1565  END
1566  CheckScriptFailure(lines, 'E884:')
1567
1568  lines =<< trim END
1569      vim9script
1570      def F list<string>
1571  END
1572  CheckScriptFailure(lines, 'E488:')
1573enddef
1574
1575def Test_partial_call()
1576  var Xsetlist = function('setloclist', [0])
1577  Xsetlist([], ' ', {'title': 'test'})
1578  getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
1579
1580  Xsetlist = function('setloclist', [0, [], ' '])
1581  Xsetlist({'title': 'test'})
1582  getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
1583
1584  Xsetlist = function('setqflist')
1585  Xsetlist([], ' ', {'title': 'test'})
1586  getqflist({'title': 1})->assert_equal({'title': 'test'})
1587
1588  Xsetlist = function('setqflist', [[], ' '])
1589  Xsetlist({'title': 'test'})
1590  getqflist({'title': 1})->assert_equal({'title': 'test'})
1591
1592  var Len: func: number = function('len', ['word'])
1593  assert_equal(4, Len())
1594enddef
1595
1596def Test_cmd_modifier()
1597  tab echo '0'
1598  CheckDefFailure(['5tab echo 3'], 'E16:')
1599enddef
1600
1601def Test_restore_modifiers()
1602  # check that when compiling a :def function command modifiers are not messed
1603  # up.
1604  var lines =<< trim END
1605      vim9script
1606      set eventignore=
1607      autocmd QuickFixCmdPost * copen
1608      def AutocmdsDisabled()
1609        eval 0
1610      enddef
1611      func Func()
1612        noautocmd call s:AutocmdsDisabled()
1613        let g:ei_after = &eventignore
1614      endfunc
1615      Func()
1616  END
1617  CheckScriptSuccess(lines)
1618  g:ei_after->assert_equal('')
1619enddef
1620
1621def StackTop()
1622  eval 1
1623  eval 2
1624  # call not on fourth line
1625  StackBot()
1626enddef
1627
1628def StackBot()
1629  # throw an error
1630  eval [][0]
1631enddef
1632
1633def Test_callstack_def()
1634  try
1635    StackTop()
1636  catch
1637    v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
1638  endtry
1639enddef
1640
1641" Re-using spot for variable used in block
1642def Test_block_scoped_var()
1643  var lines =<< trim END
1644      vim9script
1645      def Func()
1646        var x = ['a', 'b', 'c']
1647        if 1
1648          var y = 'x'
1649          map(x, {-> y})
1650        endif
1651        var z = x
1652        assert_equal(['x', 'x', 'x'], z)
1653      enddef
1654      Func()
1655  END
1656  CheckScriptSuccess(lines)
1657enddef
1658
1659
1660" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1661