15deeb3f1SBram Moolenaar" Test various aspects of the Vim9 script language.
25deeb3f1SBram Moolenaar
35deeb3f1SBram Moolenaarsource check.vim
4ad304706SBram Moolenaarsource term_util.vim
55deeb3f1SBram Moolenaarsource view_util.vim
604b12697SBram Moolenaarsource vim9.vim
747e7d70bSBram Moolenaarsource screendump.vim
85deeb3f1SBram Moolenaar
95deeb3f1SBram Moolenaarfunc Test_def_basic()
105deeb3f1SBram Moolenaar  def SomeFunc(): string
115deeb3f1SBram Moolenaar    return 'yes'
125deeb3f1SBram Moolenaar  enddef
13c0c71e9dSBram Moolenaar  call SomeFunc()->assert_equal('yes')
145deeb3f1SBram Moolenaarendfunc
155deeb3f1SBram Moolenaar
162b9b17eaSBram Moolenaarfunc Test_compiling_error()
172b9b17eaSBram Moolenaar  " use a terminal to see the whole error message
18f4e8cdd3SBram Moolenaar  CheckRunVimInTerminal
19f4e8cdd3SBram Moolenaar
202b9b17eaSBram Moolenaar  call TestCompilingError()
21e8c4660aSBram Moolenaar  call TestCompilingErrorInTry()
222b9b17eaSBram Moolenaarendfunc
232b9b17eaSBram Moolenaar
242b9b17eaSBram Moolenaardef TestCompilingError()
25f4e8cdd3SBram Moolenaar  var lines =<< trim END
26f4e8cdd3SBram Moolenaar    vim9script
27f4e8cdd3SBram Moolenaar    def Fails()
28f4e8cdd3SBram Moolenaar      echo nothing
29f4e8cdd3SBram Moolenaar    enddef
30f4e8cdd3SBram Moolenaar    defcompile
31f4e8cdd3SBram Moolenaar  END
32e8c4660aSBram Moolenaar  writefile(lines, 'XTest_compile_error')
33f4e8cdd3SBram Moolenaar  var buf = RunVimInTerminal('-S XTest_compile_error',
34e0de171eSBram Moolenaar              {rows: 10, wait_for_ruler: 0})
35e8c4660aSBram Moolenaar  WaitForAssert(() => assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing',
3603dfde2bSBram Moolenaar                     Term_getlines(buf, range(1, 9))))
37f4e8cdd3SBram Moolenaar
38f4e8cdd3SBram Moolenaar  # clean up
39e8c4660aSBram Moolenaar  StopVimInTerminal(buf)
40e8c4660aSBram Moolenaar  delete('XTest_compile_error')
41e8c4660aSBram Moolenaarenddef
42e8c4660aSBram Moolenaar
43e8c4660aSBram Moolenaardef TestCompilingErrorInTry()
44e8c4660aSBram Moolenaar  var dir = 'Xdir/autoload'
45e8c4660aSBram Moolenaar  mkdir(dir, 'p')
46e8c4660aSBram Moolenaar
47e8c4660aSBram Moolenaar  var lines =<< trim END
48e8c4660aSBram Moolenaar      vim9script
49e8c4660aSBram Moolenaar      def script#OnlyCompiled()
50e8c4660aSBram Moolenaar        g:runtime = 'yes'
51e8c4660aSBram Moolenaar        invalid
52e8c4660aSBram Moolenaar      enddef
53e8c4660aSBram Moolenaar  END
54e8c4660aSBram Moolenaar  writefile(lines, dir .. '/script.vim')
55e8c4660aSBram Moolenaar
56e8c4660aSBram Moolenaar  lines =<< trim END
57e8c4660aSBram Moolenaar      vim9script
58e8c4660aSBram Moolenaar      todo
59e8c4660aSBram Moolenaar      try
60e8c4660aSBram Moolenaar        script#OnlyCompiled()
61e8c4660aSBram Moolenaar      catch /nothing/
62e8c4660aSBram Moolenaar      endtry
63e8c4660aSBram Moolenaar  END
64e8c4660aSBram Moolenaar  lines[1] = 'set rtp=' .. getcwd() .. '/Xdir'
65e8c4660aSBram Moolenaar  writefile(lines, 'XTest_compile_error')
66e8c4660aSBram Moolenaar
67e8c4660aSBram Moolenaar  var buf = RunVimInTerminal('-S XTest_compile_error', {rows: 10, wait_for_ruler: 0})
68e8c4660aSBram Moolenaar  WaitForAssert(() => assert_match('Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid',
69e8c4660aSBram Moolenaar                     Term_getlines(buf, range(1, 9))))
70e8c4660aSBram Moolenaar
71e8c4660aSBram Moolenaar  # clean up
72e8c4660aSBram Moolenaar  StopVimInTerminal(buf)
73e8c4660aSBram Moolenaar  delete('XTest_compile_error')
74e8c4660aSBram Moolenaar  delete('Xdir', 'rf')
75f4e8cdd3SBram Moolenaarenddef
76f4e8cdd3SBram Moolenaar
77b55d618fSBram Moolenaardef Test_compile_error_in_called_function()
78b55d618fSBram Moolenaar  var lines =<< trim END
79b55d618fSBram Moolenaar      vim9script
80b55d618fSBram Moolenaar      var n: number
81b55d618fSBram Moolenaar      def Foo()
82b55d618fSBram Moolenaar        &hls = n
83b55d618fSBram Moolenaar      enddef
84b55d618fSBram Moolenaar      def Bar()
85b55d618fSBram Moolenaar        Foo()
86b55d618fSBram Moolenaar      enddef
87b55d618fSBram Moolenaar      silent! Foo()
88b55d618fSBram Moolenaar      Bar()
89b55d618fSBram Moolenaar  END
90b55d618fSBram Moolenaar  CheckScriptFailureList(lines, ['E1012:', 'E1191:'])
91b55d618fSBram Moolenaarenddef
92b55d618fSBram Moolenaar
9322f17a29SBram Moolenaardef Test_wrong_function_name()
9422f17a29SBram Moolenaar  var lines =<< trim END
9522f17a29SBram Moolenaar      vim9script
9622f17a29SBram Moolenaar      func _Foo()
9722f17a29SBram Moolenaar        echo 'foo'
9822f17a29SBram Moolenaar      endfunc
9922f17a29SBram Moolenaar  END
10022f17a29SBram Moolenaar  CheckScriptFailure(lines, 'E128:')
10122f17a29SBram Moolenaar
10222f17a29SBram Moolenaar  lines =<< trim END
10322f17a29SBram Moolenaar      vim9script
10422f17a29SBram Moolenaar      def _Foo()
10522f17a29SBram Moolenaar        echo 'foo'
10622f17a29SBram Moolenaar      enddef
10722f17a29SBram Moolenaar  END
10822f17a29SBram Moolenaar  CheckScriptFailure(lines, 'E128:')
10922f17a29SBram Moolenaarenddef
11022f17a29SBram Moolenaar
111f48b2fa3SBram Moolenaardef Test_autoload_name_mismatch()
112f48b2fa3SBram Moolenaar  var dir = 'Xdir/autoload'
113f48b2fa3SBram Moolenaar  mkdir(dir, 'p')
114f48b2fa3SBram Moolenaar
115f48b2fa3SBram Moolenaar  var lines =<< trim END
116f48b2fa3SBram Moolenaar      vim9script
117f48b2fa3SBram Moolenaar      def scriptX#Function()
118f48b2fa3SBram Moolenaar        # comment
119f48b2fa3SBram Moolenaar        g:runtime = 'yes'
120f48b2fa3SBram Moolenaar      enddef
121f48b2fa3SBram Moolenaar  END
122f48b2fa3SBram Moolenaar  writefile(lines, dir .. '/script.vim')
123f48b2fa3SBram Moolenaar
124f48b2fa3SBram Moolenaar  var save_rtp = &rtp
125f48b2fa3SBram Moolenaar  exe 'set rtp=' .. getcwd() .. '/Xdir'
126f48b2fa3SBram Moolenaar  lines =<< trim END
127f48b2fa3SBram Moolenaar      call script#Function()
128f48b2fa3SBram Moolenaar  END
129f48b2fa3SBram Moolenaar  CheckScriptFailure(lines, 'E746:', 2)
130f48b2fa3SBram Moolenaar
131f48b2fa3SBram Moolenaar  &rtp = save_rtp
132f48b2fa3SBram Moolenaar  delete(dir, 'rf')
133f48b2fa3SBram Moolenaarenddef
134f48b2fa3SBram Moolenaar
135f0a4069eSBram Moolenaardef Test_autoload_names()
136f0a4069eSBram Moolenaar  var dir = 'Xdir/autoload'
137f0a4069eSBram Moolenaar  mkdir(dir, 'p')
138f0a4069eSBram Moolenaar
139f0a4069eSBram Moolenaar  var lines =<< trim END
140f0a4069eSBram Moolenaar      func foobar#function()
141f0a4069eSBram Moolenaar        return 'yes'
142f0a4069eSBram Moolenaar      endfunc
143f0a4069eSBram Moolenaar      let foobar#var = 'no'
144f0a4069eSBram Moolenaar  END
145f0a4069eSBram Moolenaar  writefile(lines, dir .. '/foobar.vim')
146f0a4069eSBram Moolenaar
147f0a4069eSBram Moolenaar  var save_rtp = &rtp
148f0a4069eSBram Moolenaar  exe 'set rtp=' .. getcwd() .. '/Xdir'
149f0a4069eSBram Moolenaar
150f0a4069eSBram Moolenaar  lines =<< trim END
151f0a4069eSBram Moolenaar      assert_equal('yes', foobar#function())
152f0a4069eSBram Moolenaar      var Function = foobar#function
153f0a4069eSBram Moolenaar      assert_equal('yes', Function())
154f0a4069eSBram Moolenaar
155f0a4069eSBram Moolenaar      assert_equal('no', foobar#var)
156f0a4069eSBram Moolenaar  END
157f0a4069eSBram Moolenaar  CheckDefAndScriptSuccess(lines)
158f0a4069eSBram Moolenaar
159f0a4069eSBram Moolenaar  &rtp = save_rtp
160f0a4069eSBram Moolenaar  delete(dir, 'rf')
161f0a4069eSBram Moolenaarenddef
162f0a4069eSBram Moolenaar
16388c89c77SBram Moolenaardef Test_autoload_error_in_script()
16488c89c77SBram Moolenaar  var dir = 'Xdir/autoload'
16588c89c77SBram Moolenaar  mkdir(dir, 'p')
16688c89c77SBram Moolenaar
16788c89c77SBram Moolenaar  var lines =<< trim END
16888c89c77SBram Moolenaar      func scripterror#function()
16988c89c77SBram Moolenaar        let g:called_function = 'yes'
17088c89c77SBram Moolenaar      endfunc
17188c89c77SBram Moolenaar      let 0 = 1
17288c89c77SBram Moolenaar  END
17388c89c77SBram Moolenaar  writefile(lines, dir .. '/scripterror.vim')
17488c89c77SBram Moolenaar
17588c89c77SBram Moolenaar  var save_rtp = &rtp
17688c89c77SBram Moolenaar  exe 'set rtp=' .. getcwd() .. '/Xdir'
17788c89c77SBram Moolenaar
17888c89c77SBram Moolenaar  g:called_function = 'no'
17988c89c77SBram Moolenaar  # The error in the autoload script cannot be checked with assert_fails(), use
18088c89c77SBram Moolenaar  # CheckDefSuccess() instead of CheckDefFailure()
18188c89c77SBram Moolenaar  try
18288c89c77SBram Moolenaar    CheckDefSuccess(['scripterror#function()'])
18388c89c77SBram Moolenaar  catch
18488c89c77SBram Moolenaar    assert_match('E121: Undefined variable: 0', v:exception)
18588c89c77SBram Moolenaar  endtry
18688c89c77SBram Moolenaar  assert_equal('no', g:called_function)
18788c89c77SBram Moolenaar
18888c89c77SBram Moolenaar  lines =<< trim END
18988c89c77SBram Moolenaar      func scriptcaught#function()
19088c89c77SBram Moolenaar        let g:called_function = 'yes'
19188c89c77SBram Moolenaar      endfunc
19288c89c77SBram Moolenaar      try
19388c89c77SBram Moolenaar        let 0 = 1
19488c89c77SBram Moolenaar      catch
19588c89c77SBram Moolenaar        let g:caught = v:exception
19688c89c77SBram Moolenaar      endtry
19788c89c77SBram Moolenaar  END
19888c89c77SBram Moolenaar  writefile(lines, dir .. '/scriptcaught.vim')
19988c89c77SBram Moolenaar
20088c89c77SBram Moolenaar  g:called_function = 'no'
20188c89c77SBram Moolenaar  CheckDefSuccess(['scriptcaught#function()'])
20288c89c77SBram Moolenaar  assert_match('E121: Undefined variable: 0', g:caught)
20388c89c77SBram Moolenaar  assert_equal('yes', g:called_function)
20488c89c77SBram Moolenaar
20588c89c77SBram Moolenaar  &rtp = save_rtp
20688c89c77SBram Moolenaar  delete(dir, 'rf')
20788c89c77SBram Moolenaarenddef
20888c89c77SBram Moolenaar
2090ba48e8cSBram Moolenaardef CallRecursive(n: number): number
2100ba48e8cSBram Moolenaar  return CallRecursive(n + 1)
2110ba48e8cSBram Moolenaarenddef
2120ba48e8cSBram Moolenaar
2130ba48e8cSBram Moolenaardef CallMapRecursive(l: list<number>): number
2142949cfdbSBram Moolenaar  return map(l, (_, v) => CallMapRecursive([v]))[0]
2150ba48e8cSBram Moolenaarenddef
2160ba48e8cSBram Moolenaar
2170ba48e8cSBram Moolenaardef Test_funcdepth_error()
2180ba48e8cSBram Moolenaar  set maxfuncdepth=10
2190ba48e8cSBram Moolenaar
2200ba48e8cSBram Moolenaar  var caught = false
2210ba48e8cSBram Moolenaar  try
2220ba48e8cSBram Moolenaar    CallRecursive(1)
2230ba48e8cSBram Moolenaar  catch /E132:/
2240ba48e8cSBram Moolenaar    caught = true
2250ba48e8cSBram Moolenaar  endtry
2260ba48e8cSBram Moolenaar  assert_true(caught)
2270ba48e8cSBram Moolenaar
2280ba48e8cSBram Moolenaar  caught = false
2290ba48e8cSBram Moolenaar  try
2300ba48e8cSBram Moolenaar    CallMapRecursive([1])
2310ba48e8cSBram Moolenaar  catch /E132:/
2320ba48e8cSBram Moolenaar    caught = true
2330ba48e8cSBram Moolenaar  endtry
2340ba48e8cSBram Moolenaar  assert_true(caught)
2350ba48e8cSBram Moolenaar
2360ba48e8cSBram Moolenaar  set maxfuncdepth&
2370ba48e8cSBram Moolenaarenddef
2380ba48e8cSBram Moolenaar
2395178b1b0SBram Moolenaardef Test_endfunc_enddef()
2405178b1b0SBram Moolenaar  var lines =<< trim END
2415178b1b0SBram Moolenaar    def Test()
2425178b1b0SBram Moolenaar      echo 'test'
2435178b1b0SBram Moolenaar      endfunc
2445178b1b0SBram Moolenaar    enddef
2455178b1b0SBram Moolenaar  END
2465178b1b0SBram Moolenaar  CheckScriptFailure(lines, 'E1151:', 3)
2475178b1b0SBram Moolenaar
2485178b1b0SBram Moolenaar  lines =<< trim END
2495178b1b0SBram Moolenaar    def Test()
2505178b1b0SBram Moolenaar      func Nested()
2515178b1b0SBram Moolenaar        echo 'test'
2525178b1b0SBram Moolenaar      enddef
2535178b1b0SBram Moolenaar    enddef
2545178b1b0SBram Moolenaar  END
2555178b1b0SBram Moolenaar  CheckScriptFailure(lines, 'E1152:', 4)
25649f1e9ecSBram Moolenaar
25749f1e9ecSBram Moolenaar  lines =<< trim END
25849f1e9ecSBram Moolenaar    def Ok()
25949f1e9ecSBram Moolenaar      echo 'hello'
26049f1e9ecSBram Moolenaar    enddef | echo 'there'
26149f1e9ecSBram Moolenaar    def Bad()
26249f1e9ecSBram Moolenaar      echo 'hello'
26349f1e9ecSBram Moolenaar    enddef there
26449f1e9ecSBram Moolenaar  END
26549f1e9ecSBram Moolenaar  CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6)
2665178b1b0SBram Moolenaarenddef
2675178b1b0SBram Moolenaar
268b8ba9b91SBram Moolenaardef Test_missing_endfunc_enddef()
269b8ba9b91SBram Moolenaar  var lines =<< trim END
270b8ba9b91SBram Moolenaar    vim9script
271b8ba9b91SBram Moolenaar    def Test()
272b8ba9b91SBram Moolenaar      echo 'test'
273b8ba9b91SBram Moolenaar    endef
274b8ba9b91SBram Moolenaar  END
275b8ba9b91SBram Moolenaar  CheckScriptFailure(lines, 'E1057:', 2)
276b8ba9b91SBram Moolenaar
277b8ba9b91SBram Moolenaar  lines =<< trim END
278b8ba9b91SBram Moolenaar    vim9script
279b8ba9b91SBram Moolenaar    func Some()
280b8ba9b91SBram Moolenaar      echo 'test'
281b8ba9b91SBram Moolenaar    enfffunc
282b8ba9b91SBram Moolenaar  END
283b8ba9b91SBram Moolenaar  CheckScriptFailure(lines, 'E126:', 2)
284b8ba9b91SBram Moolenaarenddef
285b8ba9b91SBram Moolenaar
2864efd9948SBram Moolenaardef Test_white_space_before_paren()
2874efd9948SBram Moolenaar  var lines =<< trim END
2884efd9948SBram Moolenaar    vim9script
2894efd9948SBram Moolenaar    def Test ()
2904efd9948SBram Moolenaar      echo 'test'
2914efd9948SBram Moolenaar    enddef
2924efd9948SBram Moolenaar  END
2934efd9948SBram Moolenaar  CheckScriptFailure(lines, 'E1068:', 2)
2944efd9948SBram Moolenaar
2954efd9948SBram Moolenaar  lines =<< trim END
2964efd9948SBram Moolenaar    vim9script
2974efd9948SBram Moolenaar    func Test ()
2984efd9948SBram Moolenaar      echo 'test'
2994efd9948SBram Moolenaar    endfunc
3004efd9948SBram Moolenaar  END
3014efd9948SBram Moolenaar  CheckScriptFailure(lines, 'E1068:', 2)
3024efd9948SBram Moolenaar
3034efd9948SBram Moolenaar  lines =<< trim END
3044efd9948SBram Moolenaar    def Test ()
3054efd9948SBram Moolenaar      echo 'test'
3064efd9948SBram Moolenaar    enddef
3074efd9948SBram Moolenaar  END
3084efd9948SBram Moolenaar  CheckScriptFailure(lines, 'E1068:', 1)
3094efd9948SBram Moolenaar
3104efd9948SBram Moolenaar  lines =<< trim END
3114efd9948SBram Moolenaar    func Test ()
3124efd9948SBram Moolenaar      echo 'test'
3134efd9948SBram Moolenaar    endfunc
3144efd9948SBram Moolenaar  END
3154efd9948SBram Moolenaar  CheckScriptSuccess(lines)
3164efd9948SBram Moolenaarenddef
3174efd9948SBram Moolenaar
318832ea89cSBram Moolenaardef Test_enddef_dict_key()
319832ea89cSBram Moolenaar  var d = {
320832ea89cSBram Moolenaar    enddef: 'x',
321832ea89cSBram Moolenaar    endfunc: 'y',
322832ea89cSBram Moolenaar  }
323832ea89cSBram Moolenaar  assert_equal({enddef: 'x', endfunc: 'y'}, d)
324832ea89cSBram Moolenaarenddef
325832ea89cSBram Moolenaar
3265deeb3f1SBram Moolenaardef ReturnString(): string
3275deeb3f1SBram Moolenaar  return 'string'
3285deeb3f1SBram Moolenaarenddef
3295deeb3f1SBram Moolenaar
3305deeb3f1SBram Moolenaardef ReturnNumber(): number
3315deeb3f1SBram Moolenaar  return 123
3325deeb3f1SBram Moolenaarenddef
3335deeb3f1SBram Moolenaar
3345deeb3f1SBram Moolenaarlet g:notNumber = 'string'
3355deeb3f1SBram Moolenaar
3365deeb3f1SBram Moolenaardef ReturnGlobal(): number
3375deeb3f1SBram Moolenaar  return g:notNumber
3385deeb3f1SBram Moolenaarenddef
3395deeb3f1SBram Moolenaar
3405deeb3f1SBram Moolenaardef Test_return_something()
341c0c71e9dSBram Moolenaar  ReturnString()->assert_equal('string')
342c0c71e9dSBram Moolenaar  ReturnNumber()->assert_equal(123)
3435e654230SBram Moolenaar  assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
3445deeb3f1SBram Moolenaarenddef
3455deeb3f1SBram Moolenaar
346e32e516dSBram Moolenaardef Test_check_argument_type()
347e32e516dSBram Moolenaar  var lines =<< trim END
348e32e516dSBram Moolenaar      vim9script
349e32e516dSBram Moolenaar      def Val(a: number, b: number): number
350e32e516dSBram Moolenaar        return 0
351e32e516dSBram Moolenaar      enddef
352e32e516dSBram Moolenaar      def Func()
353e32e516dSBram Moolenaar        var x: any = true
354e32e516dSBram Moolenaar        Val(0, x)
355e32e516dSBram Moolenaar      enddef
356e32e516dSBram Moolenaar      disass Func
357e32e516dSBram Moolenaar      Func()
358e32e516dSBram Moolenaar  END
359e32e516dSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2)
360e32e516dSBram Moolenaarenddef
361e32e516dSBram Moolenaar
362efd88555SBram Moolenaardef Test_missing_return()
363efd88555SBram Moolenaar  CheckDefFailure(['def Missing(): number',
364efd88555SBram Moolenaar                   '  if g:cond',
365efd88555SBram Moolenaar                   '    echo "no return"',
366efd88555SBram Moolenaar                   '  else',
367efd88555SBram Moolenaar                   '    return 0',
368efd88555SBram Moolenaar                   '  endif'
369efd88555SBram Moolenaar                   'enddef'], 'E1027:')
370efd88555SBram Moolenaar  CheckDefFailure(['def Missing(): number',
371efd88555SBram Moolenaar                   '  if g:cond',
372efd88555SBram Moolenaar                   '    return 1',
373efd88555SBram Moolenaar                   '  else',
374efd88555SBram Moolenaar                   '    echo "no return"',
375efd88555SBram Moolenaar                   '  endif'
376efd88555SBram Moolenaar                   'enddef'], 'E1027:')
377efd88555SBram Moolenaar  CheckDefFailure(['def Missing(): number',
378efd88555SBram Moolenaar                   '  if g:cond',
379efd88555SBram Moolenaar                   '    return 1',
380efd88555SBram Moolenaar                   '  else',
381efd88555SBram Moolenaar                   '    return 2',
382efd88555SBram Moolenaar                   '  endif'
383efd88555SBram Moolenaar                   '  return 3'
384efd88555SBram Moolenaar                   'enddef'], 'E1095:')
385efd88555SBram Moolenaarenddef
386efd88555SBram Moolenaar
387403dc31fSBram Moolenaardef Test_return_bool()
388403dc31fSBram Moolenaar  var lines =<< trim END
389403dc31fSBram Moolenaar      vim9script
390403dc31fSBram Moolenaar      def MenuFilter(id: number, key: string): bool
391403dc31fSBram Moolenaar        return popup_filter_menu(id, key)
392403dc31fSBram Moolenaar      enddef
393403dc31fSBram Moolenaar      def YesnoFilter(id: number, key: string): bool
394403dc31fSBram Moolenaar        return popup_filter_yesno(id, key)
395403dc31fSBram Moolenaar      enddef
396403dc31fSBram Moolenaar      defcompile
397403dc31fSBram Moolenaar  END
398403dc31fSBram Moolenaar  CheckScriptSuccess(lines)
399403dc31fSBram Moolenaarenddef
400403dc31fSBram Moolenaar
4015deeb3f1SBram Moolenaarlet s:nothing = 0
4025deeb3f1SBram Moolenaardef ReturnNothing()
4035deeb3f1SBram Moolenaar  s:nothing = 1
4045deeb3f1SBram Moolenaar  if true
4055deeb3f1SBram Moolenaar    return
4065deeb3f1SBram Moolenaar  endif
4075deeb3f1SBram Moolenaar  s:nothing = 2
4085deeb3f1SBram Moolenaarenddef
4095deeb3f1SBram Moolenaar
4105deeb3f1SBram Moolenaardef Test_return_nothing()
4115deeb3f1SBram Moolenaar  ReturnNothing()
412c0c71e9dSBram Moolenaar  s:nothing->assert_equal(1)
4135deeb3f1SBram Moolenaarenddef
4145deeb3f1SBram Moolenaar
415648ea76eSBram Moolenaardef Test_return_invalid()
416648ea76eSBram Moolenaar  var lines =<< trim END
417648ea76eSBram Moolenaar    vim9script
418648ea76eSBram Moolenaar    def Func(): invalid
419648ea76eSBram Moolenaar      return xxx
420648ea76eSBram Moolenaar    enddef
421648ea76eSBram Moolenaar    defcompile
422648ea76eSBram Moolenaar  END
423648ea76eSBram Moolenaar  CheckScriptFailure(lines, 'E1010:', 2)
42431842cd0SBram Moolenaar
42531842cd0SBram Moolenaar  lines =<< trim END
42631842cd0SBram Moolenaar      vim9script
42731842cd0SBram Moolenaar      def Test(Fun: func(number): number): list<number>
42831842cd0SBram Moolenaar          return map([1, 2, 3], (_, i) => Fun(i))
42931842cd0SBram Moolenaar      enddef
43031842cd0SBram Moolenaar      defcompile
43131842cd0SBram Moolenaar      def Inc(nr: number): nr
43231842cd0SBram Moolenaar        return nr + 2
43331842cd0SBram Moolenaar      enddef
43431842cd0SBram Moolenaar      echo Test(Inc)
43531842cd0SBram Moolenaar  END
43631842cd0SBram Moolenaar  # doing this twice was leaking memory
43731842cd0SBram Moolenaar  CheckScriptFailure(lines, 'E1010:')
43831842cd0SBram Moolenaar  CheckScriptFailure(lines, 'E1010:')
439648ea76eSBram Moolenaarenddef
440648ea76eSBram Moolenaar
441efc084e3SBram Moolenaardef Test_return_list_any()
442efc084e3SBram Moolenaar  var lines =<< trim END
443efc084e3SBram Moolenaar      vim9script
444efc084e3SBram Moolenaar      def Func(): list<string>
445efc084e3SBram Moolenaar        var l: list<any>
446efc084e3SBram Moolenaar        l->add('string')
447efc084e3SBram Moolenaar        return l
448efc084e3SBram Moolenaar      enddef
449efc084e3SBram Moolenaar      echo Func()
450efc084e3SBram Moolenaar  END
451efc084e3SBram Moolenaar  CheckScriptFailure(lines, 'E1012:')
452efc084e3SBram Moolenaar  lines =<< trim END
453efc084e3SBram Moolenaar      vim9script
454efc084e3SBram Moolenaar      def Func(): list<string>
455efc084e3SBram Moolenaar        var l: list<any>
456efc084e3SBram Moolenaar        l += ['string']
457efc084e3SBram Moolenaar        return l
458efc084e3SBram Moolenaar      enddef
459efc084e3SBram Moolenaar      echo Func()
460efc084e3SBram Moolenaar  END
461efc084e3SBram Moolenaar  CheckScriptFailure(lines, 'E1012:')
462efc084e3SBram Moolenaarenddef
463efc084e3SBram Moolenaar
4645deeb3f1SBram Moolenaarfunc Increment()
4655deeb3f1SBram Moolenaar  let g:counter += 1
4665deeb3f1SBram Moolenaarendfunc
4675deeb3f1SBram Moolenaar
4685deeb3f1SBram Moolenaardef Test_call_ufunc_count()
4695deeb3f1SBram Moolenaar  g:counter = 1
4705deeb3f1SBram Moolenaar  Increment()
4715deeb3f1SBram Moolenaar  Increment()
4725deeb3f1SBram Moolenaar  Increment()
473f5be8cdbSBram Moolenaar  # works with and without :call
474c0c71e9dSBram Moolenaar  g:counter->assert_equal(4)
475c0c71e9dSBram Moolenaar  eval g:counter->assert_equal(4)
4765deeb3f1SBram Moolenaar  unlet g:counter
4775deeb3f1SBram Moolenaarenddef
4785deeb3f1SBram Moolenaar
4795deeb3f1SBram Moolenaardef MyVarargs(arg: string, ...rest: list<string>): string
4807a9cbca0SBram Moolenaar  var res = arg
4815deeb3f1SBram Moolenaar  for s in rest
4825deeb3f1SBram Moolenaar    res ..= ',' .. s
4835deeb3f1SBram Moolenaar  endfor
4845deeb3f1SBram Moolenaar  return res
4855deeb3f1SBram Moolenaarenddef
4865deeb3f1SBram Moolenaar
4875deeb3f1SBram Moolenaardef Test_call_varargs()
488c0c71e9dSBram Moolenaar  MyVarargs('one')->assert_equal('one')
489c0c71e9dSBram Moolenaar  MyVarargs('one', 'two')->assert_equal('one,two')
490c0c71e9dSBram Moolenaar  MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
4915deeb3f1SBram Moolenaarenddef
4925deeb3f1SBram Moolenaar
49301dd6c37SBram Moolenaardef Test_call_white_space()
49401dd6c37SBram Moolenaar  CheckDefAndScriptFailure2(["call Test ('text')"], 'E476:', 'E1068:')
49501dd6c37SBram Moolenaarenddef
49601dd6c37SBram Moolenaar
4975deeb3f1SBram Moolenaardef MyDefaultArgs(name = 'string'): string
4985deeb3f1SBram Moolenaar  return name
4995deeb3f1SBram Moolenaarenddef
5005deeb3f1SBram Moolenaar
501e30f64b4SBram Moolenaardef MyDefaultSecond(name: string, second: bool  = true): string
502e30f64b4SBram Moolenaar  return second ? name : 'none'
503e30f64b4SBram Moolenaarenddef
504e30f64b4SBram Moolenaar
50538a3bfa9SBram Moolenaar
5065deeb3f1SBram Moolenaardef Test_call_default_args()
507c0c71e9dSBram Moolenaar  MyDefaultArgs()->assert_equal('string')
50838a3bfa9SBram Moolenaar  MyDefaultArgs(v:none)->assert_equal('string')
509c0c71e9dSBram Moolenaar  MyDefaultArgs('one')->assert_equal('one')
51038a3bfa9SBram Moolenaar  assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
5115deeb3f1SBram Moolenaar
512c0c71e9dSBram Moolenaar  MyDefaultSecond('test')->assert_equal('test')
513c0c71e9dSBram Moolenaar  MyDefaultSecond('test', true)->assert_equal('test')
514c0c71e9dSBram Moolenaar  MyDefaultSecond('test', false)->assert_equal('none')
515e30f64b4SBram Moolenaar
51638a3bfa9SBram Moolenaar  var lines =<< trim END
51738a3bfa9SBram Moolenaar      def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
51838a3bfa9SBram Moolenaar        return name .. aa .. bb
51938a3bfa9SBram Moolenaar      enddef
52038a3bfa9SBram Moolenaar
52138a3bfa9SBram Moolenaar      MyDefaultThird('->')->assert_equal('->aabb')
52238a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none)->assert_equal('->aabb')
52338a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
52438a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
52538a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
52638a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
52738a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
528e28d9b3bSBram Moolenaar
529e28d9b3bSBram Moolenaar      def DefArg(mandatory: any, optional = mandatory): string
530e28d9b3bSBram Moolenaar        return mandatory .. optional
531e28d9b3bSBram Moolenaar      enddef
532e28d9b3bSBram Moolenaar      DefArg(1234)->assert_equal('12341234')
533e28d9b3bSBram Moolenaar      DefArg("ok")->assert_equal('okok')
53438a3bfa9SBram Moolenaar  END
53538a3bfa9SBram Moolenaar  CheckDefAndScriptSuccess(lines)
53638a3bfa9SBram Moolenaar
537822ba247SBram Moolenaar  CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
5382d870f8dSBram Moolenaar  delfunc g:Func
5397707228aSBram Moolenaar  CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
5402d870f8dSBram Moolenaar  delfunc g:Func
54134fcb697SYegappan Lakshmanan  CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
54212bce958SBram Moolenaar
54338a3bfa9SBram Moolenaar  lines =<< trim END
54412bce958SBram Moolenaar      vim9script
54512bce958SBram Moolenaar      def Func(a = b == 0 ? 1 : 2, b = 0)
54612bce958SBram Moolenaar      enddef
54712bce958SBram Moolenaar      defcompile
54812bce958SBram Moolenaar  END
54912bce958SBram Moolenaar  CheckScriptFailure(lines, 'E1001: Variable not found: b')
55004b12697SBram Moolenaarenddef
55104b12697SBram Moolenaar
552cef1270dSBram Moolenaardef FuncWithComment(  # comment
553cef1270dSBram Moolenaar  a: number, #comment
554cef1270dSBram Moolenaar  b: bool, # comment
555cef1270dSBram Moolenaar  c: string) #comment
556cef1270dSBram Moolenaar  assert_equal(4, a)
557cef1270dSBram Moolenaar  assert_equal(true, b)
558cef1270dSBram Moolenaar  assert_equal('yes', c)
559cef1270dSBram Moolenaarenddef
560cef1270dSBram Moolenaar
561cef1270dSBram Moolenaardef Test_func_with_comments()
562cef1270dSBram Moolenaar  FuncWithComment(4, true, 'yes')
563cef1270dSBram Moolenaar
564cef1270dSBram Moolenaar  var lines =<< trim END
565cef1270dSBram Moolenaar      def Func(# comment
566cef1270dSBram Moolenaar        arg: string)
567cef1270dSBram Moolenaar      enddef
568cef1270dSBram Moolenaar  END
569cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E125:', 1)
570cef1270dSBram Moolenaar
571cef1270dSBram Moolenaar  lines =<< trim END
572cef1270dSBram Moolenaar      def Func(
573cef1270dSBram Moolenaar        arg: string# comment
574cef1270dSBram Moolenaar        )
575cef1270dSBram Moolenaar      enddef
576cef1270dSBram Moolenaar  END
577cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E475:', 2)
578cef1270dSBram Moolenaar
579cef1270dSBram Moolenaar  lines =<< trim END
580cef1270dSBram Moolenaar      def Func(
581cef1270dSBram Moolenaar        arg: string
582cef1270dSBram Moolenaar        )# comment
583cef1270dSBram Moolenaar      enddef
584cef1270dSBram Moolenaar  END
585cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E488:', 3)
586cef1270dSBram Moolenaarenddef
587cef1270dSBram Moolenaar
58804b12697SBram Moolenaardef Test_nested_function()
58904b12697SBram Moolenaar  def Nested(arg: string): string
59004b12697SBram Moolenaar    return 'nested ' .. arg
59104b12697SBram Moolenaar  enddef
592c0c71e9dSBram Moolenaar  Nested('function')->assert_equal('nested function')
59304b12697SBram Moolenaar
5940e65d3deSBram Moolenaar  CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
5950e65d3deSBram Moolenaar  CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
5960e65d3deSBram Moolenaar
59704b12697SBram Moolenaar  CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
598bcbf4139SBram Moolenaar  CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
599bcbf4139SBram Moolenaar  CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
6008b848cafSBram Moolenaar
60154021758SBram Moolenaar  var lines =<< trim END
60254021758SBram Moolenaar      def Outer()
60354021758SBram Moolenaar        def Inner()
60454021758SBram Moolenaar          # comment
60554021758SBram Moolenaar        enddef
60654021758SBram Moolenaar        def Inner()
60754021758SBram Moolenaar        enddef
60854021758SBram Moolenaar      enddef
60954021758SBram Moolenaar  END
61054021758SBram Moolenaar  CheckDefFailure(lines, 'E1073:')
61154021758SBram Moolenaar
61254021758SBram Moolenaar  lines =<< trim END
61354021758SBram Moolenaar      def Outer()
61454021758SBram Moolenaar        def Inner()
61554021758SBram Moolenaar          # comment
61654021758SBram Moolenaar        enddef
61754021758SBram Moolenaar        def! Inner()
61854021758SBram Moolenaar        enddef
61954021758SBram Moolenaar      enddef
62054021758SBram Moolenaar  END
62154021758SBram Moolenaar  CheckDefFailure(lines, 'E1117:')
62254021758SBram Moolenaar
62354021758SBram Moolenaar  # nested function inside conditional
62454021758SBram Moolenaar  lines =<< trim END
62554021758SBram Moolenaar      vim9script
62654021758SBram Moolenaar      var thecount = 0
62754021758SBram Moolenaar      if true
62854021758SBram Moolenaar        def Test(): number
62954021758SBram Moolenaar          def TheFunc(): number
63054021758SBram Moolenaar            thecount += 1
63154021758SBram Moolenaar            return thecount
63254021758SBram Moolenaar          enddef
63354021758SBram Moolenaar          return TheFunc()
63454021758SBram Moolenaar        enddef
63554021758SBram Moolenaar      endif
63654021758SBram Moolenaar      defcompile
63754021758SBram Moolenaar      assert_equal(1, Test())
63854021758SBram Moolenaar      assert_equal(2, Test())
63954021758SBram Moolenaar  END
64054021758SBram Moolenaar  CheckScriptSuccess(lines)
6418863bda2SBram Moolenaar
6428863bda2SBram Moolenaar  # also works when "thecount" is inside the "if" block
6438863bda2SBram Moolenaar  lines =<< trim END
6448863bda2SBram Moolenaar      vim9script
6458863bda2SBram Moolenaar      if true
6468863bda2SBram Moolenaar        var thecount = 0
6478863bda2SBram Moolenaar        def Test(): number
6488863bda2SBram Moolenaar          def TheFunc(): number
6498863bda2SBram Moolenaar            thecount += 1
6508863bda2SBram Moolenaar            return thecount
6518863bda2SBram Moolenaar          enddef
6528863bda2SBram Moolenaar          return TheFunc()
6538863bda2SBram Moolenaar        enddef
6548863bda2SBram Moolenaar      endif
6558863bda2SBram Moolenaar      defcompile
6568863bda2SBram Moolenaar      assert_equal(1, Test())
6578863bda2SBram Moolenaar      assert_equal(2, Test())
6588863bda2SBram Moolenaar  END
6598863bda2SBram Moolenaar  CheckScriptSuccess(lines)
6604bba16d2SBram Moolenaar
6614bba16d2SBram Moolenaar  lines =<< trim END
6624bba16d2SBram Moolenaar      vim9script
6634bba16d2SBram Moolenaar      def Outer()
6644bba16d2SBram Moolenaar        def Inner()
6654bba16d2SBram Moolenaar          echo 'hello'
6664bba16d2SBram Moolenaar        enddef burp
6674bba16d2SBram Moolenaar      enddef
6684bba16d2SBram Moolenaar      defcompile
6694bba16d2SBram Moolenaar  END
6704bba16d2SBram Moolenaar  CheckScriptFailure(lines, 'E1173: Text found after enddef: burp', 3)
6715deeb3f1SBram Moolenaarenddef
6725deeb3f1SBram Moolenaar
673adc8e446SBram Moolenaardef Test_not_nested_function()
674adc8e446SBram Moolenaar  echo printf('%d',
675adc8e446SBram Moolenaar      function('len')('xxx'))
676adc8e446SBram Moolenaarenddef
677adc8e446SBram Moolenaar
678af8edbb8SBram Moolenaarfunc Test_call_default_args_from_func()
679c0c71e9dSBram Moolenaar  call MyDefaultArgs()->assert_equal('string')
680c0c71e9dSBram Moolenaar  call MyDefaultArgs('one')->assert_equal('one')
6819bd5d879SBram Moolenaar  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
682af8edbb8SBram Moolenaarendfunc
683af8edbb8SBram Moolenaar
68438ddf333SBram Moolenaardef Test_nested_global_function()
6857a9cbca0SBram Moolenaar  var lines =<< trim END
68638ddf333SBram Moolenaar      vim9script
68738ddf333SBram Moolenaar      def Outer()
68838ddf333SBram Moolenaar          def g:Inner(): string
68938ddf333SBram Moolenaar              return 'inner'
69038ddf333SBram Moolenaar          enddef
69138ddf333SBram Moolenaar      enddef
692af8edbb8SBram Moolenaar      defcompile
693af8edbb8SBram Moolenaar      Outer()
694c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
695af8edbb8SBram Moolenaar      delfunc g:Inner
696af8edbb8SBram Moolenaar      Outer()
697c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
698af8edbb8SBram Moolenaar      delfunc g:Inner
699af8edbb8SBram Moolenaar      Outer()
700c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
701af8edbb8SBram Moolenaar      delfunc g:Inner
70238ddf333SBram Moolenaar  END
70338ddf333SBram Moolenaar  CheckScriptSuccess(lines)
7042c79e9d1SBram Moolenaar
7052c79e9d1SBram Moolenaar  lines =<< trim END
7062c79e9d1SBram Moolenaar      vim9script
7072c79e9d1SBram Moolenaar      def Outer()
7082c79e9d1SBram Moolenaar          def g:Inner(): string
7092c79e9d1SBram Moolenaar              return 'inner'
7102c79e9d1SBram Moolenaar          enddef
7112c79e9d1SBram Moolenaar      enddef
7122c79e9d1SBram Moolenaar      defcompile
7132c79e9d1SBram Moolenaar      Outer()
7142c79e9d1SBram Moolenaar      Outer()
7152c79e9d1SBram Moolenaar  END
7162c79e9d1SBram Moolenaar  CheckScriptFailure(lines, "E122:")
717cd45ed03SBram Moolenaar  delfunc g:Inner
718ad486a0fSBram Moolenaar
719ad486a0fSBram Moolenaar  lines =<< trim END
720ad486a0fSBram Moolenaar      vim9script
72158a52f21SBram Moolenaar      def Outer()
72258a52f21SBram Moolenaar        def g:Inner()
7232949cfdbSBram Moolenaar          echo map([1, 2, 3], (_, v) => v + 1)
72458a52f21SBram Moolenaar        enddef
72558a52f21SBram Moolenaar        g:Inner()
72658a52f21SBram Moolenaar      enddef
72758a52f21SBram Moolenaar      Outer()
72858a52f21SBram Moolenaar  END
72958a52f21SBram Moolenaar  CheckScriptSuccess(lines)
73058a52f21SBram Moolenaar  delfunc g:Inner
73158a52f21SBram Moolenaar
73258a52f21SBram Moolenaar  lines =<< trim END
73358a52f21SBram Moolenaar      vim9script
734ad486a0fSBram Moolenaar      def Func()
735ad486a0fSBram Moolenaar        echo 'script'
736ad486a0fSBram Moolenaar      enddef
737ad486a0fSBram Moolenaar      def Outer()
738ad486a0fSBram Moolenaar        def Func()
739ad486a0fSBram Moolenaar          echo 'inner'
740ad486a0fSBram Moolenaar        enddef
741ad486a0fSBram Moolenaar      enddef
742ad486a0fSBram Moolenaar      defcompile
743ad486a0fSBram Moolenaar  END
744*d604d78eSBram Moolenaar  CheckScriptFailure(lines, "E1073:", 1)
745*d604d78eSBram Moolenaar
746*d604d78eSBram Moolenaar  lines =<< trim END
747*d604d78eSBram Moolenaar      vim9script
748*d604d78eSBram Moolenaar      def Func()
749*d604d78eSBram Moolenaar        echo 'script'
750*d604d78eSBram Moolenaar      enddef
751*d604d78eSBram Moolenaar      def Func()
752*d604d78eSBram Moolenaar        echo 'script'
753*d604d78eSBram Moolenaar      enddef
754*d604d78eSBram Moolenaar  END
755*d604d78eSBram Moolenaar  CheckScriptFailure(lines, "E1073:", 5)
75638ddf333SBram Moolenaarenddef
75738ddf333SBram Moolenaar
7586abdcf82SBram Moolenaardef DefListAll()
7596abdcf82SBram Moolenaar  def
7606abdcf82SBram Moolenaarenddef
7616abdcf82SBram Moolenaar
7626abdcf82SBram Moolenaardef DefListOne()
7636abdcf82SBram Moolenaar  def DefListOne
7646abdcf82SBram Moolenaarenddef
7656abdcf82SBram Moolenaar
7666abdcf82SBram Moolenaardef DefListMatches()
7676abdcf82SBram Moolenaar  def /DefList
7686abdcf82SBram Moolenaarenddef
7696abdcf82SBram Moolenaar
7706abdcf82SBram Moolenaardef Test_nested_def_list()
7716abdcf82SBram Moolenaar  var funcs = split(execute('call DefListAll()'), "\n")
7726abdcf82SBram Moolenaar  assert_true(len(funcs) > 10)
7736abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListAll()') >= 0)
7746abdcf82SBram Moolenaar
7756abdcf82SBram Moolenaar  funcs = split(execute('call DefListOne()'), "\n")
7766abdcf82SBram Moolenaar  assert_equal(['   def DefListOne()', '1    def DefListOne', '   enddef'], funcs)
7776abdcf82SBram Moolenaar
7786abdcf82SBram Moolenaar  funcs = split(execute('call DefListMatches()'), "\n")
7796abdcf82SBram Moolenaar  assert_true(len(funcs) >= 3)
7806abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListAll()') >= 0)
7816abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListOne()') >= 0)
7826abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListMatches()') >= 0)
78354021758SBram Moolenaar
78454021758SBram Moolenaar  var lines =<< trim END
78554021758SBram Moolenaar    vim9script
78654021758SBram Moolenaar    def Func()
78754021758SBram Moolenaar      def +Func+
78854021758SBram Moolenaar    enddef
78954021758SBram Moolenaar    defcompile
79054021758SBram Moolenaar  END
79154021758SBram Moolenaar  CheckScriptFailure(lines, 'E476:', 1)
7926abdcf82SBram Moolenaarenddef
7936abdcf82SBram Moolenaar
794333894b1SBram Moolenaardef Test_global_local_function()
7957a9cbca0SBram Moolenaar  var lines =<< trim END
796333894b1SBram Moolenaar      vim9script
797333894b1SBram Moolenaar      def g:Func(): string
798333894b1SBram Moolenaar          return 'global'
799333894b1SBram Moolenaar      enddef
800333894b1SBram Moolenaar      def Func(): string
801333894b1SBram Moolenaar          return 'local'
802333894b1SBram Moolenaar      enddef
803c0c71e9dSBram Moolenaar      g:Func()->assert_equal('global')
804c0c71e9dSBram Moolenaar      Func()->assert_equal('local')
8052d870f8dSBram Moolenaar      delfunc g:Func
806333894b1SBram Moolenaar  END
807333894b1SBram Moolenaar  CheckScriptSuccess(lines)
808035d6e91SBram Moolenaar
809035d6e91SBram Moolenaar  lines =<< trim END
810035d6e91SBram Moolenaar      vim9script
811035d6e91SBram Moolenaar      def g:Funcy()
812035d6e91SBram Moolenaar        echo 'funcy'
813035d6e91SBram Moolenaar      enddef
814035d6e91SBram Moolenaar      s:Funcy()
815035d6e91SBram Moolenaar  END
816035d6e91SBram Moolenaar  CheckScriptFailure(lines, 'E117:')
817333894b1SBram Moolenaarenddef
818333894b1SBram Moolenaar
8190f769815SBram Moolenaardef Test_local_function_shadows_global()
8207a9cbca0SBram Moolenaar  var lines =<< trim END
8210f769815SBram Moolenaar      vim9script
8220f769815SBram Moolenaar      def g:Gfunc(): string
8230f769815SBram Moolenaar        return 'global'
8240f769815SBram Moolenaar      enddef
8250f769815SBram Moolenaar      def AnotherFunc(): number
8267a9cbca0SBram Moolenaar        var Gfunc = function('len')
8270f769815SBram Moolenaar        return Gfunc('testing')
8280f769815SBram Moolenaar      enddef
8290f769815SBram Moolenaar      g:Gfunc()->assert_equal('global')
8300f769815SBram Moolenaar      AnotherFunc()->assert_equal(7)
8310f769815SBram Moolenaar      delfunc g:Gfunc
8320f769815SBram Moolenaar  END
8330f769815SBram Moolenaar  CheckScriptSuccess(lines)
8340f769815SBram Moolenaar
8350f769815SBram Moolenaar  lines =<< trim END
8360f769815SBram Moolenaar      vim9script
8370f769815SBram Moolenaar      def g:Func(): string
8380f769815SBram Moolenaar        return 'global'
8390f769815SBram Moolenaar      enddef
8400f769815SBram Moolenaar      def AnotherFunc()
8410f769815SBram Moolenaar        g:Func = function('len')
8420f769815SBram Moolenaar      enddef
8430f769815SBram Moolenaar      AnotherFunc()
8440f769815SBram Moolenaar  END
8450f769815SBram Moolenaar  CheckScriptFailure(lines, 'E705:')
8460f769815SBram Moolenaar  delfunc g:Func
8470865b15bSBram Moolenaar
8480865b15bSBram Moolenaar  # global function is found without g: prefix
8490865b15bSBram Moolenaar  lines =<< trim END
8500865b15bSBram Moolenaar      vim9script
8510865b15bSBram Moolenaar      def g:Func(): string
8520865b15bSBram Moolenaar        return 'global'
8530865b15bSBram Moolenaar      enddef
8540865b15bSBram Moolenaar      def AnotherFunc(): string
8550865b15bSBram Moolenaar        return Func()
8560865b15bSBram Moolenaar      enddef
8570865b15bSBram Moolenaar      assert_equal('global', AnotherFunc())
8580865b15bSBram Moolenaar    delfunc g:Func
8590865b15bSBram Moolenaar  END
8600865b15bSBram Moolenaar  CheckScriptSuccess(lines)
8610865b15bSBram Moolenaar
8620865b15bSBram Moolenaar  lines =<< trim END
8630865b15bSBram Moolenaar      vim9script
8640865b15bSBram Moolenaar      def g:Func(): string
8650865b15bSBram Moolenaar        return 'global'
8660865b15bSBram Moolenaar      enddef
8670865b15bSBram Moolenaar      assert_equal('global', Func())
8680865b15bSBram Moolenaar      delfunc g:Func
8690865b15bSBram Moolenaar  END
8700865b15bSBram Moolenaar  CheckScriptSuccess(lines)
8710f769815SBram Moolenaarenddef
8720f769815SBram Moolenaar
8735deeb3f1SBram Moolenaarfunc TakesOneArg(arg)
8745deeb3f1SBram Moolenaar  echo a:arg
8755deeb3f1SBram Moolenaarendfunc
8765deeb3f1SBram Moolenaar
8775deeb3f1SBram Moolenaardef Test_call_wrong_args()
878d2c61705SBram Moolenaar  CheckDefFailure(['TakesOneArg()'], 'E119:')
879d2c61705SBram Moolenaar  CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
880d2c61705SBram Moolenaar  CheckDefFailure(['bufnr(xxx)'], 'E1001:')
881d2c61705SBram Moolenaar  CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
882ee8580e5SBram Moolenaar
8837a9cbca0SBram Moolenaar  var lines =<< trim END
884ee8580e5SBram Moolenaar    vim9script
885ee8580e5SBram Moolenaar    def Func(s: string)
886ee8580e5SBram Moolenaar      echo s
887ee8580e5SBram Moolenaar    enddef
888ee8580e5SBram Moolenaar    Func([])
889ee8580e5SBram Moolenaar  END
8907707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
891b185a407SBram Moolenaar
892b185a407SBram Moolenaar  lines =<< trim END
893b185a407SBram Moolenaar    vim9script
894b4893b84SBram Moolenaar    var name = 'piet'
895b4893b84SBram Moolenaar    def FuncOne(name: string)
896b4893b84SBram Moolenaar      echo nr
897b4893b84SBram Moolenaar    enddef
898b4893b84SBram Moolenaar  END
899057e84afSBram Moolenaar  CheckScriptFailure(lines, 'E1168:')
900b4893b84SBram Moolenaar
901b4893b84SBram Moolenaar  lines =<< trim END
902b4893b84SBram Moolenaar    vim9script
903b185a407SBram Moolenaar    def FuncOne(nr: number)
904b185a407SBram Moolenaar      echo nr
905b185a407SBram Moolenaar    enddef
906b185a407SBram Moolenaar    def FuncTwo()
907b185a407SBram Moolenaar      FuncOne()
908b185a407SBram Moolenaar    enddef
909b185a407SBram Moolenaar    defcompile
910b185a407SBram Moolenaar  END
911b185a407SBram Moolenaar  writefile(lines, 'Xscript')
9127a9cbca0SBram Moolenaar  var didCatch = false
913b185a407SBram Moolenaar  try
914b185a407SBram Moolenaar    source Xscript
915b185a407SBram Moolenaar  catch
916b185a407SBram Moolenaar    assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
917b185a407SBram Moolenaar    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
918b185a407SBram Moolenaar    didCatch = true
919b185a407SBram Moolenaar  endtry
920b185a407SBram Moolenaar  assert_true(didCatch)
921b185a407SBram Moolenaar
922b185a407SBram Moolenaar  lines =<< trim END
923b185a407SBram Moolenaar    vim9script
924b185a407SBram Moolenaar    def FuncOne(nr: number)
925b185a407SBram Moolenaar      echo nr
926b185a407SBram Moolenaar    enddef
927b185a407SBram Moolenaar    def FuncTwo()
928b185a407SBram Moolenaar      FuncOne(1, 2)
929b185a407SBram Moolenaar    enddef
930b185a407SBram Moolenaar    defcompile
931b185a407SBram Moolenaar  END
932b185a407SBram Moolenaar  writefile(lines, 'Xscript')
933b185a407SBram Moolenaar  didCatch = false
934b185a407SBram Moolenaar  try
935b185a407SBram Moolenaar    source Xscript
936b185a407SBram Moolenaar  catch
937b185a407SBram Moolenaar    assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
938b185a407SBram Moolenaar    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
939b185a407SBram Moolenaar    didCatch = true
940b185a407SBram Moolenaar  endtry
941b185a407SBram Moolenaar  assert_true(didCatch)
942b185a407SBram Moolenaar
943b185a407SBram Moolenaar  delete('Xscript')
9445deeb3f1SBram Moolenaarenddef
9455deeb3f1SBram Moolenaar
9465082471fSBram Moolenaardef Test_call_funcref_wrong_args()
9475082471fSBram Moolenaar  var head =<< trim END
9485082471fSBram Moolenaar      vim9script
9495082471fSBram Moolenaar      def Func3(a1: string, a2: number, a3: list<number>)
9505082471fSBram Moolenaar        echo a1 .. a2 .. a3[0]
9515082471fSBram Moolenaar      enddef
9525082471fSBram Moolenaar      def Testme()
9535082471fSBram Moolenaar        var funcMap: dict<func> = {func: Func3}
9545082471fSBram Moolenaar  END
9555082471fSBram Moolenaar  var tail =<< trim END
9565082471fSBram Moolenaar      enddef
9575082471fSBram Moolenaar      Testme()
9585082471fSBram Moolenaar  END
9595082471fSBram Moolenaar  CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
9605082471fSBram Moolenaar
9615082471fSBram Moolenaar  CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
9625082471fSBram Moolenaar  CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
96332b3f820SBram Moolenaar
96432b3f820SBram Moolenaar  var lines =<< trim END
96532b3f820SBram Moolenaar      vim9script
96632b3f820SBram Moolenaar      var Ref: func(number): any
96732b3f820SBram Moolenaar      Ref = (j) => !j
96832b3f820SBram Moolenaar      echo Ref(false)
96932b3f820SBram Moolenaar  END
97032b3f820SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
97132b3f820SBram Moolenaar
97232b3f820SBram Moolenaar  lines =<< trim END
97332b3f820SBram Moolenaar      vim9script
97432b3f820SBram Moolenaar      var Ref: func(number): any
97532b3f820SBram Moolenaar      Ref = (j) => !j
97632b3f820SBram Moolenaar      call Ref(false)
97732b3f820SBram Moolenaar  END
97832b3f820SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
9795082471fSBram Moolenaarenddef
9805082471fSBram Moolenaar
981b4d16cb1SBram Moolenaardef Test_call_lambda_args()
9822a38908bSBram Moolenaar  var lines =<< trim END
9832a38908bSBram Moolenaar    var Callback = (..._) => 'anything'
9842a38908bSBram Moolenaar    assert_equal('anything', Callback())
9852a38908bSBram Moolenaar    assert_equal('anything', Callback(1))
9862a38908bSBram Moolenaar    assert_equal('anything', Callback('a', 2))
9871088b694SBram Moolenaar
9881088b694SBram Moolenaar    assert_equal('xyz', ((a: string): string => a)('xyz'))
9892a38908bSBram Moolenaar  END
9902a38908bSBram Moolenaar  CheckDefAndScriptSuccess(lines)
9912a38908bSBram Moolenaar
9922949cfdbSBram Moolenaar  CheckDefFailure(['echo ((i) => 0)()'],
9932949cfdbSBram Moolenaar                  'E119: Not enough arguments for function: ((i) => 0)()')
994b4d16cb1SBram Moolenaar
9952a38908bSBram Moolenaar  lines =<< trim END
9962949cfdbSBram Moolenaar      var Ref = (x: number, y: number) => x + y
997b4d16cb1SBram Moolenaar      echo Ref(1, 'x')
998b4d16cb1SBram Moolenaar  END
999b4d16cb1SBram Moolenaar  CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
1000e68b02a1SBram Moolenaar
1001e68b02a1SBram Moolenaar  lines =<< trim END
1002e68b02a1SBram Moolenaar    var Ref: func(job, string, number)
1003e68b02a1SBram Moolenaar    Ref = (x, y) => 0
1004e68b02a1SBram Moolenaar  END
1005e68b02a1SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1012:')
1006e68b02a1SBram Moolenaar
1007e68b02a1SBram Moolenaar  lines =<< trim END
1008e68b02a1SBram Moolenaar    var Ref: func(job, string)
1009e68b02a1SBram Moolenaar    Ref = (x, y, z) => 0
1010e68b02a1SBram Moolenaar  END
1011e68b02a1SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1012:')
1012057e84afSBram Moolenaar
1013057e84afSBram Moolenaar  lines =<< trim END
1014057e84afSBram Moolenaar      var one = 1
1015057e84afSBram Moolenaar      var l = [1, 2, 3]
1016057e84afSBram Moolenaar      echo map(l, (one) => one)
1017057e84afSBram Moolenaar  END
1018057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
1019057e84afSBram Moolenaar  CheckScriptFailure(['vim9script'] + lines, 'E1168:')
1020057e84afSBram Moolenaar
1021057e84afSBram Moolenaar  lines =<< trim END
102214ded11fSBram Moolenaar    var Ref: func(any, ?any): bool
102314ded11fSBram Moolenaar    Ref = (_, y = 1) => false
102414ded11fSBram Moolenaar  END
102514ded11fSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1172:')
102614ded11fSBram Moolenaar
102714ded11fSBram Moolenaar  lines =<< trim END
1028015cf103SBram Moolenaar      var a = 0
1029015cf103SBram Moolenaar      var b = (a == 0 ? 1 : 2)
1030015cf103SBram Moolenaar      assert_equal(1, b)
103198f9a5f4SBram Moolenaar      var txt = 'a'
103298f9a5f4SBram Moolenaar      b = (txt =~ 'x' ? 1 : 2)
103398f9a5f4SBram Moolenaar      assert_equal(2, b)
1034015cf103SBram Moolenaar  END
1035015cf103SBram Moolenaar  CheckDefAndScriptSuccess(lines)
1036015cf103SBram Moolenaar
1037015cf103SBram Moolenaar  lines =<< trim END
1038057e84afSBram Moolenaar      def ShadowLocal()
1039057e84afSBram Moolenaar        var one = 1
1040057e84afSBram Moolenaar        var l = [1, 2, 3]
1041057e84afSBram Moolenaar        echo map(l, (one) => one)
1042057e84afSBram Moolenaar      enddef
1043057e84afSBram Moolenaar  END
1044057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
1045057e84afSBram Moolenaar
1046057e84afSBram Moolenaar  lines =<< trim END
1047057e84afSBram Moolenaar      def Shadowarg(one: number)
1048057e84afSBram Moolenaar        var l = [1, 2, 3]
1049057e84afSBram Moolenaar        echo map(l, (one) => one)
1050057e84afSBram Moolenaar      enddef
1051057e84afSBram Moolenaar  END
1052057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
1053767034c5SBram Moolenaar
1054767034c5SBram Moolenaar  lines =<< trim END
1055767034c5SBram Moolenaar    echo ((a) => a)('aa', 'bb')
1056767034c5SBram Moolenaar  END
1057767034c5SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E118:', 1)
1058c4c56425SBram Moolenaar
1059c4c56425SBram Moolenaar  lines =<< trim END
1060c4c56425SBram Moolenaar    echo 'aa'->((a) => a)('bb')
1061c4c56425SBram Moolenaar  END
1062c4c56425SBram Moolenaar  CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1063c4c56425SBram Moolenaar  CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
1064b4d16cb1SBram Moolenaarenddef
1065b4d16cb1SBram Moolenaar
1066a755fdbeSBram Moolenaardef Test_lambda_line_nr()
1067a755fdbeSBram Moolenaar  var lines =<< trim END
1068a755fdbeSBram Moolenaar      vim9script
1069a755fdbeSBram Moolenaar      # comment
1070a755fdbeSBram Moolenaar      # comment
1071a755fdbeSBram Moolenaar      var id = timer_start(1'000, (_) => 0)
1072a755fdbeSBram Moolenaar      var out = execute('verbose ' .. timer_info(id)[0].callback
1073a755fdbeSBram Moolenaar          ->string()
1074a755fdbeSBram Moolenaar          ->substitute("('\\|')", ' ', 'g'))
1075a755fdbeSBram Moolenaar      assert_match('Last set from .* line 4', out)
1076a755fdbeSBram Moolenaar  END
1077a755fdbeSBram Moolenaar  CheckScriptSuccess(lines)
1078a755fdbeSBram Moolenaarenddef
1079a755fdbeSBram Moolenaar
10805f91e74bSBram Moolenaardef FilterWithCond(x: string, Cond: func(string): bool): bool
10815f91e74bSBram Moolenaar  return Cond(x)
10825f91e74bSBram Moolenaarenddef
10835f91e74bSBram Moolenaar
10840346b799SBram Moolenaardef Test_lambda_return_type()
10850346b799SBram Moolenaar  var lines =<< trim END
10860346b799SBram Moolenaar    var Ref = (): => 123
10870346b799SBram Moolenaar  END
10880346b799SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1157:', 1)
10895f91e74bSBram Moolenaar
1090611728f8SYegappan Lakshmanan  # no space before the return type
1091611728f8SYegappan Lakshmanan  lines =<< trim END
1092611728f8SYegappan Lakshmanan    var Ref = (x):number => x + 1
1093611728f8SYegappan Lakshmanan  END
1094611728f8SYegappan Lakshmanan  CheckDefAndScriptFailure(lines, 'E1069:', 1)
1095611728f8SYegappan Lakshmanan
10965f91e74bSBram Moolenaar  # this works
10975f91e74bSBram Moolenaar  for x in ['foo', 'boo']
10985f91e74bSBram Moolenaar    echo FilterWithCond(x, (v) => v =~ '^b')
10995f91e74bSBram Moolenaar  endfor
11005f91e74bSBram Moolenaar
11015f91e74bSBram Moolenaar  # this fails
11025f91e74bSBram Moolenaar  lines =<< trim END
11035f91e74bSBram Moolenaar      echo FilterWithCond('foo', (v) => v .. '^b')
11045f91e74bSBram Moolenaar  END
11055f91e74bSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
1106a9931535SBram Moolenaar
1107a9931535SBram Moolenaar  lines =<< trim END
1108a9931535SBram Moolenaar      var Lambda1 = (x) => {
1109a9931535SBram Moolenaar              return x
1110a9931535SBram Moolenaar              }
1111a9931535SBram Moolenaar      assert_equal('asdf', Lambda1('asdf'))
1112a9931535SBram Moolenaar      var Lambda2 = (x): string => {
1113a9931535SBram Moolenaar              return x
1114a9931535SBram Moolenaar              }
1115a9931535SBram Moolenaar      assert_equal('foo', Lambda2('foo'))
1116a9931535SBram Moolenaar  END
1117a9931535SBram Moolenaar  CheckDefAndScriptSuccess(lines)
1118a9931535SBram Moolenaar
1119a9931535SBram Moolenaar  lines =<< trim END
1120a9931535SBram Moolenaar      var Lambda = (x): string => {
1121a9931535SBram Moolenaar              return x
1122a9931535SBram Moolenaar              }
1123a9931535SBram Moolenaar      echo Lambda(['foo'])
1124a9931535SBram Moolenaar  END
1125a9931535SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1012:')
11260346b799SBram Moolenaarenddef
11270346b799SBram Moolenaar
1128709664ccSBram Moolenaardef Test_lambda_uses_assigned_var()
1129709664ccSBram Moolenaar  CheckDefSuccess([
1130709664ccSBram Moolenaar        'var x: any = "aaa"'
11312949cfdbSBram Moolenaar        'x = filter(["bbb"], (_, v) => v =~ x)'])
1132709664ccSBram Moolenaarenddef
1133709664ccSBram Moolenaar
113418062fcaSBram Moolenaardef Test_pass_legacy_lambda_to_def_func()
113518062fcaSBram Moolenaar  var lines =<< trim END
113618062fcaSBram Moolenaar      vim9script
113718062fcaSBram Moolenaar      func Foo()
113818062fcaSBram Moolenaar        eval s:Bar({x -> 0})
113918062fcaSBram Moolenaar      endfunc
114018062fcaSBram Moolenaar      def Bar(y: any)
114118062fcaSBram Moolenaar      enddef
114218062fcaSBram Moolenaar      Foo()
114318062fcaSBram Moolenaar  END
114418062fcaSBram Moolenaar  CheckScriptSuccess(lines)
1145831bdf86SBram Moolenaar
1146831bdf86SBram Moolenaar  lines =<< trim END
1147831bdf86SBram Moolenaar      vim9script
11487a40ff00SBram Moolenaar      def g:TestFunc(f: func)
1149831bdf86SBram Moolenaar      enddef
1150831bdf86SBram Moolenaar      legacy call g:TestFunc({-> 0})
1151831bdf86SBram Moolenaar      delfunc g:TestFunc
1152831bdf86SBram Moolenaar
1153831bdf86SBram Moolenaar      def g:TestFunc(f: func(number))
1154831bdf86SBram Moolenaar      enddef
1155831bdf86SBram Moolenaar      legacy call g:TestFunc({nr -> 0})
1156831bdf86SBram Moolenaar      delfunc g:TestFunc
1157831bdf86SBram Moolenaar  END
1158831bdf86SBram Moolenaar  CheckScriptSuccess(lines)
115918062fcaSBram Moolenaarenddef
116018062fcaSBram Moolenaar
1161844fb64aSBram Moolenaardef Test_lambda_in_reduce_line_break()
1162844fb64aSBram Moolenaar  # this was using freed memory
1163844fb64aSBram Moolenaar  var lines =<< trim END
1164844fb64aSBram Moolenaar      vim9script
1165844fb64aSBram Moolenaar      const result: dict<number> =
1166844fb64aSBram Moolenaar          ['Bob', 'Sam', 'Cat', 'Bob', 'Cat', 'Cat']
1167844fb64aSBram Moolenaar          ->reduce((acc, val) => {
1168844fb64aSBram Moolenaar              if has_key(acc, val)
1169844fb64aSBram Moolenaar                  acc[val] += 1
1170844fb64aSBram Moolenaar                  return acc
1171844fb64aSBram Moolenaar              else
1172844fb64aSBram Moolenaar                  acc[val] = 1
1173844fb64aSBram Moolenaar                  return acc
1174844fb64aSBram Moolenaar              endif
1175844fb64aSBram Moolenaar          }, {})
1176844fb64aSBram Moolenaar      assert_equal({Bob: 2, Sam: 1, Cat: 3}, result)
1177844fb64aSBram Moolenaar  END
1178844fb64aSBram Moolenaar  CheckScriptSuccess(lines)
1179844fb64aSBram Moolenaarenddef
1180844fb64aSBram Moolenaar
11815deeb3f1SBram Moolenaar" Default arg and varargs
11825deeb3f1SBram Moolenaardef MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
11837a9cbca0SBram Moolenaar  var res = one .. ',' .. two
11845deeb3f1SBram Moolenaar  for s in rest
11855deeb3f1SBram Moolenaar    res ..= ',' .. s
11865deeb3f1SBram Moolenaar  endfor
11875deeb3f1SBram Moolenaar  return res
11885deeb3f1SBram Moolenaarenddef
11895deeb3f1SBram Moolenaar
11905deeb3f1SBram Moolenaardef Test_call_def_varargs()
11919bd5d879SBram Moolenaar  assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1192c0c71e9dSBram Moolenaar  MyDefVarargs('one')->assert_equal('one,foo')
1193c0c71e9dSBram Moolenaar  MyDefVarargs('one', 'two')->assert_equal('one,two')
1194c0c71e9dSBram Moolenaar  MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
119524aa48b7SBram Moolenaar  CheckDefFailure(['MyDefVarargs("one", 22)'],
11967707228aSBram Moolenaar      'E1013: Argument 2: type mismatch, expected string but got number')
119724aa48b7SBram Moolenaar  CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
11987707228aSBram Moolenaar      'E1013: Argument 3: type mismatch, expected string but got number')
119924aa48b7SBram Moolenaar
12007a9cbca0SBram Moolenaar  var lines =<< trim END
120124aa48b7SBram Moolenaar      vim9script
120224aa48b7SBram Moolenaar      def Func(...l: list<string>)
120324aa48b7SBram Moolenaar        echo l
120424aa48b7SBram Moolenaar      enddef
120524aa48b7SBram Moolenaar      Func('a', 'b', 'c')
120624aa48b7SBram Moolenaar  END
120724aa48b7SBram Moolenaar  CheckScriptSuccess(lines)
120824aa48b7SBram Moolenaar
120924aa48b7SBram Moolenaar  lines =<< trim END
121024aa48b7SBram Moolenaar      vim9script
121124aa48b7SBram Moolenaar      def Func(...l: list<string>)
121224aa48b7SBram Moolenaar        echo l
121324aa48b7SBram Moolenaar      enddef
121424aa48b7SBram Moolenaar      Func()
121524aa48b7SBram Moolenaar  END
121624aa48b7SBram Moolenaar  CheckScriptSuccess(lines)
121724aa48b7SBram Moolenaar
121824aa48b7SBram Moolenaar  lines =<< trim END
121924aa48b7SBram Moolenaar      vim9script
12202a38908bSBram Moolenaar      def Func(...l: list<any>)
12212f8cbc4bSBram Moolenaar        echo l
12222f8cbc4bSBram Moolenaar      enddef
12232f8cbc4bSBram Moolenaar      Func(0)
12242f8cbc4bSBram Moolenaar  END
12252f8cbc4bSBram Moolenaar  CheckScriptSuccess(lines)
12262f8cbc4bSBram Moolenaar
12272f8cbc4bSBram Moolenaar  lines =<< trim END
12282f8cbc4bSBram Moolenaar      vim9script
12292a38908bSBram Moolenaar      def Func(...l: any)
12302a38908bSBram Moolenaar        echo l
12312a38908bSBram Moolenaar      enddef
12322a38908bSBram Moolenaar      Func(0)
12332a38908bSBram Moolenaar  END
12342a38908bSBram Moolenaar  CheckScriptFailure(lines, 'E1180:', 2)
12352a38908bSBram Moolenaar
12362a38908bSBram Moolenaar  lines =<< trim END
12372a38908bSBram Moolenaar      vim9script
123828022727SBram Moolenaar      def Func(..._l: list<string>)
123928022727SBram Moolenaar        echo _l
124028022727SBram Moolenaar      enddef
124128022727SBram Moolenaar      Func('a', 'b', 'c')
124228022727SBram Moolenaar  END
124328022727SBram Moolenaar  CheckScriptSuccess(lines)
124428022727SBram Moolenaar
124528022727SBram Moolenaar  lines =<< trim END
124628022727SBram Moolenaar      vim9script
124724aa48b7SBram Moolenaar      def Func(...l: list<string>)
124824aa48b7SBram Moolenaar        echo l
124924aa48b7SBram Moolenaar      enddef
125024aa48b7SBram Moolenaar      Func(1, 2, 3)
125124aa48b7SBram Moolenaar  END
12527707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
125324aa48b7SBram Moolenaar
125424aa48b7SBram Moolenaar  lines =<< trim END
125524aa48b7SBram Moolenaar      vim9script
125624aa48b7SBram Moolenaar      def Func(...l: list<string>)
125724aa48b7SBram Moolenaar        echo l
125824aa48b7SBram Moolenaar      enddef
125924aa48b7SBram Moolenaar      Func('a', 9)
126024aa48b7SBram Moolenaar  END
12617707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
126224aa48b7SBram Moolenaar
126324aa48b7SBram Moolenaar  lines =<< trim END
126424aa48b7SBram Moolenaar      vim9script
126524aa48b7SBram Moolenaar      def Func(...l: list<string>)
126624aa48b7SBram Moolenaar        echo l
126724aa48b7SBram Moolenaar      enddef
126824aa48b7SBram Moolenaar      Func(1, 'a')
126924aa48b7SBram Moolenaar  END
12707707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
12714f53b79bSBram Moolenaar
12724f53b79bSBram Moolenaar  lines =<< trim END
12734f53b79bSBram Moolenaar      vim9script
12744f53b79bSBram Moolenaar      def Func(  # some comment
12754f53b79bSBram Moolenaar                ...l = []
12764f53b79bSBram Moolenaar                )
12774f53b79bSBram Moolenaar        echo l
12784f53b79bSBram Moolenaar      enddef
12794f53b79bSBram Moolenaar  END
12804f53b79bSBram Moolenaar  CheckScriptFailure(lines, 'E1160:')
12816ce46b99SBram Moolenaar
12826ce46b99SBram Moolenaar  lines =<< trim END
12836ce46b99SBram Moolenaar      vim9script
12846ce46b99SBram Moolenaar      def DoIt()
12856ce46b99SBram Moolenaar        g:Later('')
12866ce46b99SBram Moolenaar      enddef
12876ce46b99SBram Moolenaar      defcompile
12886ce46b99SBram Moolenaar      def g:Later(...l:  list<number>)
12896ce46b99SBram Moolenaar      enddef
12906ce46b99SBram Moolenaar      DoIt()
12916ce46b99SBram Moolenaar  END
12926ce46b99SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
12935deeb3f1SBram Moolenaarenddef
12945deeb3f1SBram Moolenaar
12951378fbc4SBram Moolenaarlet s:value = ''
12961378fbc4SBram Moolenaar
12971378fbc4SBram Moolenaardef FuncOneDefArg(opt = 'text')
12981378fbc4SBram Moolenaar  s:value = opt
12991378fbc4SBram Moolenaarenddef
13001378fbc4SBram Moolenaar
13011378fbc4SBram Moolenaardef FuncTwoDefArg(nr = 123, opt = 'text'): string
13021378fbc4SBram Moolenaar  return nr .. opt
13031378fbc4SBram Moolenaarenddef
13041378fbc4SBram Moolenaar
13051378fbc4SBram Moolenaardef FuncVarargs(...arg: list<string>): string
13061378fbc4SBram Moolenaar  return join(arg, ',')
13071378fbc4SBram Moolenaarenddef
13081378fbc4SBram Moolenaar
13091378fbc4SBram Moolenaardef Test_func_type_varargs()
13107a9cbca0SBram Moolenaar  var RefDefArg: func(?string)
13111378fbc4SBram Moolenaar  RefDefArg = FuncOneDefArg
13121378fbc4SBram Moolenaar  RefDefArg()
1313c0c71e9dSBram Moolenaar  s:value->assert_equal('text')
13141378fbc4SBram Moolenaar  RefDefArg('some')
1315c0c71e9dSBram Moolenaar  s:value->assert_equal('some')
13161378fbc4SBram Moolenaar
13177a9cbca0SBram Moolenaar  var RefDef2Arg: func(?number, ?string): string
13181378fbc4SBram Moolenaar  RefDef2Arg = FuncTwoDefArg
1319c0c71e9dSBram Moolenaar  RefDef2Arg()->assert_equal('123text')
1320c0c71e9dSBram Moolenaar  RefDef2Arg(99)->assert_equal('99text')
1321c0c71e9dSBram Moolenaar  RefDef2Arg(77, 'some')->assert_equal('77some')
13221378fbc4SBram Moolenaar
13237a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
13247a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
13251378fbc4SBram Moolenaar
13267a9cbca0SBram Moolenaar  var RefVarargs: func(...list<string>): string
13271378fbc4SBram Moolenaar  RefVarargs = FuncVarargs
1328c0c71e9dSBram Moolenaar  RefVarargs()->assert_equal('')
1329c0c71e9dSBram Moolenaar  RefVarargs('one')->assert_equal('one')
1330c0c71e9dSBram Moolenaar  RefVarargs('one', 'two')->assert_equal('one,two')
13311378fbc4SBram Moolenaar
13327a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
13337a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
13341378fbc4SBram Moolenaarenddef
13351378fbc4SBram Moolenaar
13360b76b42dSBram Moolenaar" Only varargs
13370b76b42dSBram Moolenaardef MyVarargsOnly(...args: list<string>): string
13380b76b42dSBram Moolenaar  return join(args, ',')
13390b76b42dSBram Moolenaarenddef
13400b76b42dSBram Moolenaar
13410b76b42dSBram Moolenaardef Test_call_varargs_only()
1342c0c71e9dSBram Moolenaar  MyVarargsOnly()->assert_equal('')
1343c0c71e9dSBram Moolenaar  MyVarargsOnly('one')->assert_equal('one')
1344c0c71e9dSBram Moolenaar  MyVarargsOnly('one', 'two')->assert_equal('one,two')
13457707228aSBram Moolenaar  CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
13467707228aSBram Moolenaar  CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
13470b76b42dSBram Moolenaarenddef
13480b76b42dSBram Moolenaar
13495deeb3f1SBram Moolenaardef Test_using_var_as_arg()
13507a9cbca0SBram Moolenaar  writefile(['def Func(x: number)',  'var x = 234', 'enddef', 'defcompile'], 'Xdef')
13519bd5d879SBram Moolenaar  assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
1352d2c61705SBram Moolenaar  delete('Xdef')
13535deeb3f1SBram Moolenaarenddef
13545deeb3f1SBram Moolenaar
1355cb2bdb1cSBram Moolenaardef DictArg(arg: dict<string>)
1356cb2bdb1cSBram Moolenaar  arg['key'] = 'value'
1357cb2bdb1cSBram Moolenaarenddef
1358cb2bdb1cSBram Moolenaar
1359cb2bdb1cSBram Moolenaardef ListArg(arg: list<string>)
1360cb2bdb1cSBram Moolenaar  arg[0] = 'value'
1361cb2bdb1cSBram Moolenaarenddef
1362cb2bdb1cSBram Moolenaar
1363cb2bdb1cSBram Moolenaardef Test_assign_to_argument()
1364f5be8cdbSBram Moolenaar  # works for dict and list
13657a9cbca0SBram Moolenaar  var d: dict<string> = {}
1366cb2bdb1cSBram Moolenaar  DictArg(d)
1367c0c71e9dSBram Moolenaar  d['key']->assert_equal('value')
13687a9cbca0SBram Moolenaar  var l: list<string> = []
1369cb2bdb1cSBram Moolenaar  ListArg(l)
1370c0c71e9dSBram Moolenaar  l[0]->assert_equal('value')
1371cb2bdb1cSBram Moolenaar
1372d2c61705SBram Moolenaar  CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
13732d870f8dSBram Moolenaar  delfunc! g:Func
1374cb2bdb1cSBram Moolenaarenddef
1375cb2bdb1cSBram Moolenaar
1376b816dae1SBram Moolenaar" These argument names are reserved in legacy functions.
1377b816dae1SBram Moolenaardef WithReservedNames(firstline: string, lastline: string): string
1378b816dae1SBram Moolenaar  return firstline .. lastline
1379b816dae1SBram Moolenaarenddef
1380b816dae1SBram Moolenaar
1381b816dae1SBram Moolenaardef Test_argument_names()
1382b816dae1SBram Moolenaar  assert_equal('OK', WithReservedNames('O', 'K'))
1383b816dae1SBram Moolenaarenddef
1384b816dae1SBram Moolenaar
13855deeb3f1SBram Moolenaardef Test_call_func_defined_later()
1386c0c71e9dSBram Moolenaar  g:DefinedLater('one')->assert_equal('one')
13879bd5d879SBram Moolenaar  assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
13885deeb3f1SBram Moolenaarenddef
13895deeb3f1SBram Moolenaar
13901df8b3fbSBram Moolenaarfunc DefinedLater(arg)
13911df8b3fbSBram Moolenaar  return a:arg
13921df8b3fbSBram Moolenaarendfunc
13931df8b3fbSBram Moolenaar
13941df8b3fbSBram Moolenaardef Test_call_funcref()
1395c0c71e9dSBram Moolenaar  g:SomeFunc('abc')->assert_equal(3)
13969bd5d879SBram Moolenaar  assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
13979bd5d879SBram Moolenaar  assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
13982f1980f7SBram Moolenaar
13997a9cbca0SBram Moolenaar  var lines =<< trim END
14002f1980f7SBram Moolenaar    vim9script
14012f1980f7SBram Moolenaar    def RetNumber(): number
14022f1980f7SBram Moolenaar      return 123
14032f1980f7SBram Moolenaar    enddef
14047a9cbca0SBram Moolenaar    var Funcref: func: number = function('RetNumber')
1405c0c71e9dSBram Moolenaar    Funcref()->assert_equal(123)
14062f1980f7SBram Moolenaar  END
14072f1980f7SBram Moolenaar  CheckScriptSuccess(lines)
14080f60e80fSBram Moolenaar
14090f60e80fSBram Moolenaar  lines =<< trim END
14100f60e80fSBram Moolenaar    vim9script
14110f60e80fSBram Moolenaar    def RetNumber(): number
14120f60e80fSBram Moolenaar      return 123
14130f60e80fSBram Moolenaar    enddef
14140f60e80fSBram Moolenaar    def Bar(F: func: number): number
14150f60e80fSBram Moolenaar      return F()
14160f60e80fSBram Moolenaar    enddef
14177a9cbca0SBram Moolenaar    var Funcref = function('RetNumber')
1418c0c71e9dSBram Moolenaar    Bar(Funcref)->assert_equal(123)
14190f60e80fSBram Moolenaar  END
14200f60e80fSBram Moolenaar  CheckScriptSuccess(lines)
1421bfba8651SBram Moolenaar
1422bfba8651SBram Moolenaar  lines =<< trim END
1423bfba8651SBram Moolenaar    vim9script
1424bfba8651SBram Moolenaar    def UseNumber(nr: number)
1425bfba8651SBram Moolenaar      echo nr
1426bfba8651SBram Moolenaar    enddef
14277a9cbca0SBram Moolenaar    var Funcref: func(number) = function('UseNumber')
1428bfba8651SBram Moolenaar    Funcref(123)
1429bfba8651SBram Moolenaar  END
1430bfba8651SBram Moolenaar  CheckScriptSuccess(lines)
1431b8070e31SBram Moolenaar
1432b8070e31SBram Moolenaar  lines =<< trim END
1433b8070e31SBram Moolenaar    vim9script
1434b8070e31SBram Moolenaar    def UseNumber(nr: number)
1435b8070e31SBram Moolenaar      echo nr
1436b8070e31SBram Moolenaar    enddef
14377a9cbca0SBram Moolenaar    var Funcref: func(string) = function('UseNumber')
1438b8070e31SBram Moolenaar  END
14395e654230SBram Moolenaar  CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
14404fc224caSBram Moolenaar
14414fc224caSBram Moolenaar  lines =<< trim END
14424fc224caSBram Moolenaar    vim9script
14434fc224caSBram Moolenaar    def EchoNr(nr = 34)
14444fc224caSBram Moolenaar      g:echo = nr
14454fc224caSBram Moolenaar    enddef
14467a9cbca0SBram Moolenaar    var Funcref: func(?number) = function('EchoNr')
14474fc224caSBram Moolenaar    Funcref()
1448c0c71e9dSBram Moolenaar    g:echo->assert_equal(34)
14494fc224caSBram Moolenaar    Funcref(123)
1450c0c71e9dSBram Moolenaar    g:echo->assert_equal(123)
14514fc224caSBram Moolenaar  END
14524fc224caSBram Moolenaar  CheckScriptSuccess(lines)
1453ace6132aSBram Moolenaar
1454ace6132aSBram Moolenaar  lines =<< trim END
1455ace6132aSBram Moolenaar    vim9script
1456ace6132aSBram Moolenaar    def EchoList(...l: list<number>)
1457ace6132aSBram Moolenaar      g:echo = l
1458ace6132aSBram Moolenaar    enddef
14597a9cbca0SBram Moolenaar    var Funcref: func(...list<number>) = function('EchoList')
1460ace6132aSBram Moolenaar    Funcref()
1461c0c71e9dSBram Moolenaar    g:echo->assert_equal([])
1462ace6132aSBram Moolenaar    Funcref(1, 2, 3)
1463c0c71e9dSBram Moolenaar    g:echo->assert_equal([1, 2, 3])
1464ace6132aSBram Moolenaar  END
1465ace6132aSBram Moolenaar  CheckScriptSuccess(lines)
146601865adeSBram Moolenaar
146701865adeSBram Moolenaar  lines =<< trim END
146801865adeSBram Moolenaar    vim9script
146901865adeSBram Moolenaar    def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
147001865adeSBram Moolenaar      g:optarg = opt
147101865adeSBram Moolenaar      g:listarg = l
147201865adeSBram Moolenaar      return nr
147301865adeSBram Moolenaar    enddef
14747a9cbca0SBram Moolenaar    var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
1475c0c71e9dSBram Moolenaar    Funcref(10)->assert_equal(10)
1476c0c71e9dSBram Moolenaar    g:optarg->assert_equal(12)
1477c0c71e9dSBram Moolenaar    g:listarg->assert_equal([])
147801865adeSBram Moolenaar
1479c0c71e9dSBram Moolenaar    Funcref(11, 22)->assert_equal(11)
1480c0c71e9dSBram Moolenaar    g:optarg->assert_equal(22)
1481c0c71e9dSBram Moolenaar    g:listarg->assert_equal([])
148201865adeSBram Moolenaar
1483c0c71e9dSBram Moolenaar    Funcref(17, 18, 1, 2, 3)->assert_equal(17)
1484c0c71e9dSBram Moolenaar    g:optarg->assert_equal(18)
1485c0c71e9dSBram Moolenaar    g:listarg->assert_equal([1, 2, 3])
148601865adeSBram Moolenaar  END
148701865adeSBram Moolenaar  CheckScriptSuccess(lines)
14881df8b3fbSBram Moolenaarenddef
14891df8b3fbSBram Moolenaar
14901df8b3fbSBram Moolenaarlet SomeFunc = function('len')
14911df8b3fbSBram Moolenaarlet NotAFunc = 'text'
14921df8b3fbSBram Moolenaar
149399aaf0ceSBram Moolenaardef CombineFuncrefTypes()
1494f5be8cdbSBram Moolenaar  # same arguments, different return type
14957a9cbca0SBram Moolenaar  var Ref1: func(bool): string
14967a9cbca0SBram Moolenaar  var Ref2: func(bool): number
14977a9cbca0SBram Moolenaar  var Ref3: func(bool): any
149899aaf0ceSBram Moolenaar  Ref3 = g:cond ? Ref1 : Ref2
149999aaf0ceSBram Moolenaar
1500f5be8cdbSBram Moolenaar  # different number of arguments
15017a9cbca0SBram Moolenaar  var Refa1: func(bool): number
15027a9cbca0SBram Moolenaar  var Refa2: func(bool, number): number
15037a9cbca0SBram Moolenaar  var Refa3: func: number
150499aaf0ceSBram Moolenaar  Refa3 = g:cond ? Refa1 : Refa2
150599aaf0ceSBram Moolenaar
1506f5be8cdbSBram Moolenaar  # different argument types
15077a9cbca0SBram Moolenaar  var Refb1: func(bool, string): number
15087a9cbca0SBram Moolenaar  var Refb2: func(string, number): number
15097a9cbca0SBram Moolenaar  var Refb3: func(any, any): number
151099aaf0ceSBram Moolenaar  Refb3 = g:cond ? Refb1 : Refb2
151199aaf0ceSBram Moolenaarenddef
151299aaf0ceSBram Moolenaar
15135deeb3f1SBram Moolenaardef FuncWithForwardCall()
15141df8b3fbSBram Moolenaar  return g:DefinedEvenLater("yes")
15155deeb3f1SBram Moolenaarenddef
15165deeb3f1SBram Moolenaar
15175deeb3f1SBram Moolenaardef DefinedEvenLater(arg: string): string
15185deeb3f1SBram Moolenaar  return arg
15195deeb3f1SBram Moolenaarenddef
15205deeb3f1SBram Moolenaar
15215deeb3f1SBram Moolenaardef Test_error_in_nested_function()
1522f5be8cdbSBram Moolenaar  # Error in called function requires unwinding the call stack.
152344d6652dSBram Moolenaar  assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
15245deeb3f1SBram Moolenaarenddef
15255deeb3f1SBram Moolenaar
15265deeb3f1SBram Moolenaardef Test_return_type_wrong()
15275a849da5SBram Moolenaar  CheckScriptFailure([
15285a849da5SBram Moolenaar        'def Func(): number',
15295a849da5SBram Moolenaar        'return "a"',
15305a849da5SBram Moolenaar        'enddef',
15315a849da5SBram Moolenaar        'defcompile'], 'expected number but got string')
15322d870f8dSBram Moolenaar  delfunc! g:Func
15335a849da5SBram Moolenaar  CheckScriptFailure([
15345a849da5SBram Moolenaar        'def Func(): string',
15355a849da5SBram Moolenaar        'return 1',
15365a849da5SBram Moolenaar        'enddef',
15375a849da5SBram Moolenaar        'defcompile'], 'expected string but got number')
15382d870f8dSBram Moolenaar  delfunc! g:Func
15395a849da5SBram Moolenaar  CheckScriptFailure([
15405a849da5SBram Moolenaar        'def Func(): void',
15415a849da5SBram Moolenaar        'return "a"',
15425a849da5SBram Moolenaar        'enddef',
15435a849da5SBram Moolenaar        'defcompile'],
15445a849da5SBram Moolenaar        'E1096: Returning a value in a function without a return type')
15452d870f8dSBram Moolenaar  delfunc! g:Func
15465a849da5SBram Moolenaar  CheckScriptFailure([
15475a849da5SBram Moolenaar        'def Func()',
15485a849da5SBram Moolenaar        'return "a"',
15495a849da5SBram Moolenaar        'enddef',
15505a849da5SBram Moolenaar        'defcompile'],
15515a849da5SBram Moolenaar        'E1096: Returning a value in a function without a return type')
15522d870f8dSBram Moolenaar  delfunc! g:Func
15535deeb3f1SBram Moolenaar
15545a849da5SBram Moolenaar  CheckScriptFailure([
15555a849da5SBram Moolenaar        'def Func(): number',
15565a849da5SBram Moolenaar        'return',
15575a849da5SBram Moolenaar        'enddef',
15585a849da5SBram Moolenaar        'defcompile'], 'E1003:')
15592d870f8dSBram Moolenaar  delfunc! g:Func
15605deeb3f1SBram Moolenaar
156133ea9fd4SBram Moolenaar  CheckScriptFailure([
156233ea9fd4SBram Moolenaar        'def Func():number',
156333ea9fd4SBram Moolenaar        'return 123',
156433ea9fd4SBram Moolenaar        'enddef',
156533ea9fd4SBram Moolenaar        'defcompile'], 'E1069:')
156633ea9fd4SBram Moolenaar  delfunc! g:Func
156733ea9fd4SBram Moolenaar
156833ea9fd4SBram Moolenaar  CheckScriptFailure([
156933ea9fd4SBram Moolenaar        'def Func() :number',
157033ea9fd4SBram Moolenaar        'return 123',
157133ea9fd4SBram Moolenaar        'enddef',
157233ea9fd4SBram Moolenaar        'defcompile'], 'E1059:')
157333ea9fd4SBram Moolenaar  delfunc! g:Func
157433ea9fd4SBram Moolenaar
157533ea9fd4SBram Moolenaar  CheckScriptFailure([
157633ea9fd4SBram Moolenaar        'def Func() : number',
157733ea9fd4SBram Moolenaar        'return 123',
157833ea9fd4SBram Moolenaar        'enddef',
157933ea9fd4SBram Moolenaar        'defcompile'], 'E1059:')
158033ea9fd4SBram Moolenaar  delfunc! g:Func
158133ea9fd4SBram Moolenaar
15825deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
15832d870f8dSBram Moolenaar  delfunc! g:Func
15845deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
15852d870f8dSBram Moolenaar  delfunc! g:Func
1586ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
15872d870f8dSBram Moolenaar  delfunc! g:Func
15885a849da5SBram Moolenaar
15895a849da5SBram Moolenaar  CheckScriptFailure([
15905a849da5SBram Moolenaar        'vim9script',
15915a849da5SBram Moolenaar        'def FuncB()',
15925a849da5SBram Moolenaar        '  return 123',
15935a849da5SBram Moolenaar        'enddef',
15945a849da5SBram Moolenaar        'def FuncA()',
15955a849da5SBram Moolenaar        '   FuncB()',
15965a849da5SBram Moolenaar        'enddef',
15975a849da5SBram Moolenaar        'defcompile'], 'E1096:')
15985deeb3f1SBram Moolenaarenddef
15995deeb3f1SBram Moolenaar
16005deeb3f1SBram Moolenaardef Test_arg_type_wrong()
16015deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
1602ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
1603f93c7feaSBram Moolenaar  CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
16046e949784SBram Moolenaar  CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
160534fcb697SYegappan Lakshmanan  CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
160634fcb697SYegappan Lakshmanan  CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
16075deeb3f1SBram Moolenaarenddef
16085deeb3f1SBram Moolenaar
160986cdb8a4SBram Moolenaardef Test_white_space_before_comma()
161086cdb8a4SBram Moolenaar  var lines =<< trim END
161186cdb8a4SBram Moolenaar    vim9script
161286cdb8a4SBram Moolenaar    def Func(a: number , b: number)
161386cdb8a4SBram Moolenaar    enddef
161486cdb8a4SBram Moolenaar  END
161586cdb8a4SBram Moolenaar  CheckScriptFailure(lines, 'E1068:')
1616611728f8SYegappan Lakshmanan  call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
161786cdb8a4SBram Moolenaarenddef
161886cdb8a4SBram Moolenaar
1619608d78fbSBram Moolenaardef Test_white_space_after_comma()
1620608d78fbSBram Moolenaar  var lines =<< trim END
1621608d78fbSBram Moolenaar    vim9script
1622608d78fbSBram Moolenaar    def Func(a: number,b: number)
1623608d78fbSBram Moolenaar    enddef
1624608d78fbSBram Moolenaar  END
1625608d78fbSBram Moolenaar  CheckScriptFailure(lines, 'E1069:')
1626608d78fbSBram Moolenaar
1627608d78fbSBram Moolenaar  # OK in legacy function
1628608d78fbSBram Moolenaar  lines =<< trim END
1629608d78fbSBram Moolenaar    vim9script
1630608d78fbSBram Moolenaar    func Func(a,b)
1631608d78fbSBram Moolenaar    endfunc
1632608d78fbSBram Moolenaar  END
1633608d78fbSBram Moolenaar  CheckScriptSuccess(lines)
1634608d78fbSBram Moolenaarenddef
1635608d78fbSBram Moolenaar
16365deeb3f1SBram Moolenaardef Test_vim9script_call()
16377a9cbca0SBram Moolenaar  var lines =<< trim END
16385deeb3f1SBram Moolenaar    vim9script
16397a9cbca0SBram Moolenaar    var name = ''
16405deeb3f1SBram Moolenaar    def MyFunc(arg: string)
16417a9cbca0SBram Moolenaar       name = arg
16425deeb3f1SBram Moolenaar    enddef
16435deeb3f1SBram Moolenaar    MyFunc('foobar')
16447a9cbca0SBram Moolenaar    name->assert_equal('foobar')
16455deeb3f1SBram Moolenaar
16467a9cbca0SBram Moolenaar    var str = 'barfoo'
16475deeb3f1SBram Moolenaar    str->MyFunc()
16487a9cbca0SBram Moolenaar    name->assert_equal('barfoo')
16495deeb3f1SBram Moolenaar
16506797966dSBram Moolenaar    g:value = 'value'
16515deeb3f1SBram Moolenaar    g:value->MyFunc()
16527a9cbca0SBram Moolenaar    name->assert_equal('value')
16535deeb3f1SBram Moolenaar
16547a9cbca0SBram Moolenaar    var listvar = []
16555deeb3f1SBram Moolenaar    def ListFunc(arg: list<number>)
16565deeb3f1SBram Moolenaar       listvar = arg
16575deeb3f1SBram Moolenaar    enddef
16585deeb3f1SBram Moolenaar    [1, 2, 3]->ListFunc()
1659c0c71e9dSBram Moolenaar    listvar->assert_equal([1, 2, 3])
16605deeb3f1SBram Moolenaar
16617a9cbca0SBram Moolenaar    var dictvar = {}
16625deeb3f1SBram Moolenaar    def DictFunc(arg: dict<number>)
16635deeb3f1SBram Moolenaar       dictvar = arg
16645deeb3f1SBram Moolenaar    enddef
1665e0de171eSBram Moolenaar    {a: 1, b: 2}->DictFunc()
1666e0de171eSBram Moolenaar    dictvar->assert_equal({a: 1, b: 2})
16675deeb3f1SBram Moolenaar    def CompiledDict()
1668e0de171eSBram Moolenaar      {a: 3, b: 4}->DictFunc()
16695deeb3f1SBram Moolenaar    enddef
16705deeb3f1SBram Moolenaar    CompiledDict()
1671e0de171eSBram Moolenaar    dictvar->assert_equal({a: 3, b: 4})
16725deeb3f1SBram Moolenaar
1673e0de171eSBram Moolenaar    {a: 3, b: 4}->DictFunc()
1674e0de171eSBram Moolenaar    dictvar->assert_equal({a: 3, b: 4})
16755deeb3f1SBram Moolenaar
16765deeb3f1SBram Moolenaar    ('text')->MyFunc()
16777a9cbca0SBram Moolenaar    name->assert_equal('text')
16785deeb3f1SBram Moolenaar    ("some")->MyFunc()
16797a9cbca0SBram Moolenaar    name->assert_equal('some')
1680e6b5324eSBram Moolenaar
168113e12b8aSBram Moolenaar    # line starting with single quote is not a mark
168210409562SBram Moolenaar    # line starting with double quote can be a method call
16833d48e25dSBram Moolenaar    'asdfasdf'->MyFunc()
16847a9cbca0SBram Moolenaar    name->assert_equal('asdfasdf')
168510409562SBram Moolenaar    "xyz"->MyFunc()
16867a9cbca0SBram Moolenaar    name->assert_equal('xyz')
16873d48e25dSBram Moolenaar
16883d48e25dSBram Moolenaar    def UseString()
16893d48e25dSBram Moolenaar      'xyork'->MyFunc()
16903d48e25dSBram Moolenaar    enddef
16913d48e25dSBram Moolenaar    UseString()
16927a9cbca0SBram Moolenaar    name->assert_equal('xyork')
16933d48e25dSBram Moolenaar
169410409562SBram Moolenaar    def UseString2()
169510409562SBram Moolenaar      "knife"->MyFunc()
169610409562SBram Moolenaar    enddef
169710409562SBram Moolenaar    UseString2()
16987a9cbca0SBram Moolenaar    name->assert_equal('knife')
169910409562SBram Moolenaar
170013e12b8aSBram Moolenaar    # prepending a colon makes it a mark
170113e12b8aSBram Moolenaar    new
170213e12b8aSBram Moolenaar    setline(1, ['aaa', 'bbb', 'ccc'])
170313e12b8aSBram Moolenaar    normal! 3Gmt1G
170413e12b8aSBram Moolenaar    :'t
1705c0c71e9dSBram Moolenaar    getcurpos()[1]->assert_equal(3)
170613e12b8aSBram Moolenaar    bwipe!
170713e12b8aSBram Moolenaar
1708e6b5324eSBram Moolenaar    MyFunc(
1709e6b5324eSBram Moolenaar        'continued'
1710e6b5324eSBram Moolenaar        )
1711e6b5324eSBram Moolenaar    assert_equal('continued',
17127a9cbca0SBram Moolenaar            name
1713e6b5324eSBram Moolenaar            )
1714e6b5324eSBram Moolenaar
1715e6b5324eSBram Moolenaar    call MyFunc(
1716e6b5324eSBram Moolenaar        'more'
1717e6b5324eSBram Moolenaar          ..
1718e6b5324eSBram Moolenaar          'lines'
1719e6b5324eSBram Moolenaar        )
1720e6b5324eSBram Moolenaar    assert_equal(
1721e6b5324eSBram Moolenaar        'morelines',
17227a9cbca0SBram Moolenaar        name)
17235deeb3f1SBram Moolenaar  END
17245deeb3f1SBram Moolenaar  writefile(lines, 'Xcall.vim')
17255deeb3f1SBram Moolenaar  source Xcall.vim
17265deeb3f1SBram Moolenaar  delete('Xcall.vim')
17275deeb3f1SBram Moolenaarenddef
17285deeb3f1SBram Moolenaar
17295deeb3f1SBram Moolenaardef Test_vim9script_call_fail_decl()
17307a9cbca0SBram Moolenaar  var lines =<< trim END
17315deeb3f1SBram Moolenaar    vim9script
17327a9cbca0SBram Moolenaar    var name = ''
17335deeb3f1SBram Moolenaar    def MyFunc(arg: string)
17347a9cbca0SBram Moolenaar       var name = 123
17355deeb3f1SBram Moolenaar    enddef
1736822ba247SBram Moolenaar    defcompile
17375deeb3f1SBram Moolenaar  END
17386c4bfe4bSBram Moolenaar  CheckScriptFailure(lines, 'E1054:')
17395deeb3f1SBram Moolenaarenddef
17405deeb3f1SBram Moolenaar
174165b9545fSBram Moolenaardef Test_vim9script_call_fail_type()
17427a9cbca0SBram Moolenaar  var lines =<< trim END
174365b9545fSBram Moolenaar    vim9script
174465b9545fSBram Moolenaar    def MyFunc(arg: string)
174565b9545fSBram Moolenaar      echo arg
174665b9545fSBram Moolenaar    enddef
174765b9545fSBram Moolenaar    MyFunc(1234)
174865b9545fSBram Moolenaar  END
17497707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
175065b9545fSBram Moolenaarenddef
175165b9545fSBram Moolenaar
17525deeb3f1SBram Moolenaardef Test_vim9script_call_fail_const()
17537a9cbca0SBram Moolenaar  var lines =<< trim END
17545deeb3f1SBram Moolenaar    vim9script
17555deeb3f1SBram Moolenaar    const var = ''
17565deeb3f1SBram Moolenaar    def MyFunc(arg: string)
17575deeb3f1SBram Moolenaar       var = 'asdf'
17585deeb3f1SBram Moolenaar    enddef
1759822ba247SBram Moolenaar    defcompile
17605deeb3f1SBram Moolenaar  END
17615deeb3f1SBram Moolenaar  writefile(lines, 'Xcall_const.vim')
17629bd5d879SBram Moolenaar  assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
17635deeb3f1SBram Moolenaar  delete('Xcall_const.vim')
17643bdc90b7SBram Moolenaar
17653bdc90b7SBram Moolenaar  lines =<< trim END
17663bdc90b7SBram Moolenaar      const g:Aconst = 77
17673bdc90b7SBram Moolenaar      def Change()
17683bdc90b7SBram Moolenaar        # comment
17693bdc90b7SBram Moolenaar        g:Aconst = 99
17703bdc90b7SBram Moolenaar      enddef
17713bdc90b7SBram Moolenaar      call Change()
17723bdc90b7SBram Moolenaar      unlet g:Aconst
17733bdc90b7SBram Moolenaar  END
17741dcf55d4SBram Moolenaar  CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
17755deeb3f1SBram Moolenaarenddef
17765deeb3f1SBram Moolenaar
17775deeb3f1SBram Moolenaar" Test that inside :function a Python function can be defined, :def is not
17785deeb3f1SBram Moolenaar" recognized.
17795deeb3f1SBram Moolenaarfunc Test_function_python()
17805deeb3f1SBram Moolenaar  CheckFeature python3
1781727345ebSBram Moolenaar  let py = 'python3'
17825deeb3f1SBram Moolenaar  execute py "<< EOF"
17835deeb3f1SBram Moolenaardef do_something():
17845deeb3f1SBram Moolenaar  return 1
17855deeb3f1SBram MoolenaarEOF
17865deeb3f1SBram Moolenaarendfunc
17875deeb3f1SBram Moolenaar
17885deeb3f1SBram Moolenaardef Test_delfunc()
17897a9cbca0SBram Moolenaar  var lines =<< trim END
17905deeb3f1SBram Moolenaar    vim9script
17914c17ad94SBram Moolenaar    def g:GoneSoon()
17925deeb3f1SBram Moolenaar      echo 'hello'
17935deeb3f1SBram Moolenaar    enddef
17945deeb3f1SBram Moolenaar
17955deeb3f1SBram Moolenaar    def CallGoneSoon()
17965deeb3f1SBram Moolenaar      GoneSoon()
17975deeb3f1SBram Moolenaar    enddef
1798822ba247SBram Moolenaar    defcompile
17995deeb3f1SBram Moolenaar
18004c17ad94SBram Moolenaar    delfunc g:GoneSoon
18015deeb3f1SBram Moolenaar    CallGoneSoon()
18025deeb3f1SBram Moolenaar  END
18035deeb3f1SBram Moolenaar  writefile(lines, 'XToDelFunc')
18049bd5d879SBram Moolenaar  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
18059bd5d879SBram Moolenaar  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
18065deeb3f1SBram Moolenaar
18075deeb3f1SBram Moolenaar  delete('XToDelFunc')
18085deeb3f1SBram Moolenaarenddef
18095deeb3f1SBram Moolenaar
18105deeb3f1SBram Moolenaardef Test_redef_failure()
1811d2c61705SBram Moolenaar  writefile(['def Func0(): string',  'return "Func0"', 'enddef'], 'Xdef')
18125deeb3f1SBram Moolenaar  so Xdef
1813d2c61705SBram Moolenaar  writefile(['def Func1(): string',  'return "Func1"', 'enddef'], 'Xdef')
18145deeb3f1SBram Moolenaar  so Xdef
1815d2c61705SBram Moolenaar  writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
18169bd5d879SBram Moolenaar  assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
1817d2c61705SBram Moolenaar  writefile(['def Func2(): string',  'return "Func2"', 'enddef'], 'Xdef')
18185deeb3f1SBram Moolenaar  so Xdef
1819d2c61705SBram Moolenaar  delete('Xdef')
18205deeb3f1SBram Moolenaar
1821701cc6caSBram Moolenaar  assert_fails('g:Func0()', 'E1091:')
1822c0c71e9dSBram Moolenaar  g:Func1()->assert_equal('Func1')
1823c0c71e9dSBram Moolenaar  g:Func2()->assert_equal('Func2')
18245deeb3f1SBram Moolenaar
18255deeb3f1SBram Moolenaar  delfunc! Func0
18265deeb3f1SBram Moolenaar  delfunc! Func1
18275deeb3f1SBram Moolenaar  delfunc! Func2
18285deeb3f1SBram Moolenaarenddef
18295deeb3f1SBram Moolenaar
1830f93c7feaSBram Moolenaardef Test_vim9script_func()
18317a9cbca0SBram Moolenaar  var lines =<< trim END
1832f93c7feaSBram Moolenaar    vim9script
1833f93c7feaSBram Moolenaar    func Func(arg)
1834f93c7feaSBram Moolenaar      echo a:arg
1835f93c7feaSBram Moolenaar    endfunc
1836f93c7feaSBram Moolenaar    Func('text')
1837f93c7feaSBram Moolenaar  END
1838f93c7feaSBram Moolenaar  writefile(lines, 'XVim9Func')
1839f93c7feaSBram Moolenaar  so XVim9Func
1840f93c7feaSBram Moolenaar
1841f93c7feaSBram Moolenaar  delete('XVim9Func')
1842f93c7feaSBram Moolenaarenddef
1843f93c7feaSBram Moolenaar
18445deeb3f1SBram Moolenaarlet s:funcResult = 0
18455deeb3f1SBram Moolenaar
18465deeb3f1SBram Moolenaardef FuncNoArgNoRet()
18475390099aSBram Moolenaar  s:funcResult = 11
18485deeb3f1SBram Moolenaarenddef
18495deeb3f1SBram Moolenaar
18505deeb3f1SBram Moolenaardef FuncNoArgRetNumber(): number
18515390099aSBram Moolenaar  s:funcResult = 22
18525deeb3f1SBram Moolenaar  return 1234
18535deeb3f1SBram Moolenaarenddef
18545deeb3f1SBram Moolenaar
1855ec5929d0SBram Moolenaardef FuncNoArgRetString(): string
18565390099aSBram Moolenaar  s:funcResult = 45
1857ec5929d0SBram Moolenaar  return 'text'
1858ec5929d0SBram Moolenaarenddef
1859ec5929d0SBram Moolenaar
18605deeb3f1SBram Moolenaardef FuncOneArgNoRet(arg: number)
18615390099aSBram Moolenaar  s:funcResult = arg
18625deeb3f1SBram Moolenaarenddef
18635deeb3f1SBram Moolenaar
18645deeb3f1SBram Moolenaardef FuncOneArgRetNumber(arg: number): number
18655390099aSBram Moolenaar  s:funcResult = arg
18665deeb3f1SBram Moolenaar  return arg
18675deeb3f1SBram Moolenaarenddef
18685deeb3f1SBram Moolenaar
186908938eebSBram Moolenaardef FuncTwoArgNoRet(one: bool, two: number)
18705390099aSBram Moolenaar  s:funcResult = two
187108938eebSBram Moolenaarenddef
187208938eebSBram Moolenaar
1873ec5929d0SBram Moolenaardef FuncOneArgRetString(arg: string): string
1874ec5929d0SBram Moolenaar  return arg
1875ec5929d0SBram Moolenaarenddef
1876ec5929d0SBram Moolenaar
18778922860aSBram Moolenaardef FuncOneArgRetAny(arg: any): any
18788922860aSBram Moolenaar  return arg
18798922860aSBram Moolenaarenddef
18808922860aSBram Moolenaar
18815deeb3f1SBram Moolenaardef Test_func_type()
18827a9cbca0SBram Moolenaar  var Ref1: func()
18835390099aSBram Moolenaar  s:funcResult = 0
18845deeb3f1SBram Moolenaar  Ref1 = FuncNoArgNoRet
18855deeb3f1SBram Moolenaar  Ref1()
1886c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(11)
18874c683750SBram Moolenaar
18887a9cbca0SBram Moolenaar  var Ref2: func
18895390099aSBram Moolenaar  s:funcResult = 0
18904c683750SBram Moolenaar  Ref2 = FuncNoArgNoRet
18914c683750SBram Moolenaar  Ref2()
1892c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(11)
18934c683750SBram Moolenaar
18945390099aSBram Moolenaar  s:funcResult = 0
18954c683750SBram Moolenaar  Ref2 = FuncOneArgNoRet
18964c683750SBram Moolenaar  Ref2(12)
1897c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(12)
18984c683750SBram Moolenaar
18995390099aSBram Moolenaar  s:funcResult = 0
19004c683750SBram Moolenaar  Ref2 = FuncNoArgRetNumber
1901c0c71e9dSBram Moolenaar  Ref2()->assert_equal(1234)
1902c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(22)
19034c683750SBram Moolenaar
19045390099aSBram Moolenaar  s:funcResult = 0
19054c683750SBram Moolenaar  Ref2 = FuncOneArgRetNumber
1906c0c71e9dSBram Moolenaar  Ref2(13)->assert_equal(13)
1907c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(13)
19085deeb3f1SBram Moolenaarenddef
19095deeb3f1SBram Moolenaar
19109978d473SBram Moolenaardef Test_repeat_return_type()
19117a9cbca0SBram Moolenaar  var res = 0
19129978d473SBram Moolenaar  for n in repeat([1], 3)
19139978d473SBram Moolenaar    res += n
19149978d473SBram Moolenaar  endfor
1915c0c71e9dSBram Moolenaar  res->assert_equal(3)
1916fce82b3aSBram Moolenaar
1917fce82b3aSBram Moolenaar  res = 0
1918fce82b3aSBram Moolenaar  for n in add([1, 2], 3)
1919fce82b3aSBram Moolenaar    res += n
1920fce82b3aSBram Moolenaar  endfor
1921c0c71e9dSBram Moolenaar  res->assert_equal(6)
19229978d473SBram Moolenaarenddef
19239978d473SBram Moolenaar
1924846178a7SBram Moolenaardef Test_argv_return_type()
1925846178a7SBram Moolenaar  next fileone filetwo
19267a9cbca0SBram Moolenaar  var res = ''
1927846178a7SBram Moolenaar  for name in argv()
1928846178a7SBram Moolenaar    res ..= name
1929846178a7SBram Moolenaar  endfor
1930c0c71e9dSBram Moolenaar  res->assert_equal('fileonefiletwo')
1931846178a7SBram Moolenaarenddef
1932846178a7SBram Moolenaar
1933ec5929d0SBram Moolenaardef Test_func_type_part()
19347a9cbca0SBram Moolenaar  var RefVoid: func: void
1935ec5929d0SBram Moolenaar  RefVoid = FuncNoArgNoRet
1936ec5929d0SBram Moolenaar  RefVoid = FuncOneArgNoRet
19377a9cbca0SBram Moolenaar  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
19387a9cbca0SBram Moolenaar  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
1939ec5929d0SBram Moolenaar
19407a9cbca0SBram Moolenaar  var RefAny: func(): any
1941ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetNumber
1942ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetString
19437a9cbca0SBram Moolenaar  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
19447a9cbca0SBram Moolenaar  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
1945ec5929d0SBram Moolenaar
19466abd3dc2SBram Moolenaar  var RefAnyNoArgs: func: any = RefAny
19476abd3dc2SBram Moolenaar
19487a9cbca0SBram Moolenaar  var RefNr: func: number
1949ec5929d0SBram Moolenaar  RefNr = FuncNoArgRetNumber
1950ec5929d0SBram Moolenaar  RefNr = FuncOneArgRetNumber
19517a9cbca0SBram Moolenaar  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
19527a9cbca0SBram Moolenaar  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
1953ec5929d0SBram Moolenaar
19547a9cbca0SBram Moolenaar  var RefStr: func: string
1955ec5929d0SBram Moolenaar  RefStr = FuncNoArgRetString
1956ec5929d0SBram Moolenaar  RefStr = FuncOneArgRetString
19577a9cbca0SBram Moolenaar  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
19587a9cbca0SBram Moolenaar  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
1959ec5929d0SBram Moolenaarenddef
1960ec5929d0SBram Moolenaar
19615deeb3f1SBram Moolenaardef Test_func_type_fails()
19627a9cbca0SBram Moolenaar  CheckDefFailure(['var ref1: func()'], 'E704:')
19635deeb3f1SBram Moolenaar
19647a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
19657a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
19667a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
19677a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
19687a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
19697a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
197008938eebSBram Moolenaar
19717a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
19727a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
19737a9cbca0SBram Moolenaar  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:')
19747a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
19755deeb3f1SBram Moolenaarenddef
19765deeb3f1SBram Moolenaar
19778922860aSBram Moolenaardef Test_func_return_type()
19787a9cbca0SBram Moolenaar  var nr: number
19798922860aSBram Moolenaar  nr = FuncNoArgRetNumber()
1980c0c71e9dSBram Moolenaar  nr->assert_equal(1234)
19818922860aSBram Moolenaar
19828922860aSBram Moolenaar  nr = FuncOneArgRetAny(122)
1983c0c71e9dSBram Moolenaar  nr->assert_equal(122)
19848922860aSBram Moolenaar
19857a9cbca0SBram Moolenaar  var str: string
19868922860aSBram Moolenaar  str = FuncOneArgRetAny('yes')
1987c0c71e9dSBram Moolenaar  str->assert_equal('yes')
19888922860aSBram Moolenaar
19897a9cbca0SBram Moolenaar  CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
19908922860aSBram Moolenaarenddef
19918922860aSBram Moolenaar
19926abd3dc2SBram Moolenaardef Test_func_common_type()
19936abd3dc2SBram Moolenaar  def FuncOne(n: number): number
19946abd3dc2SBram Moolenaar    return n
19956abd3dc2SBram Moolenaar  enddef
19966abd3dc2SBram Moolenaar  def FuncTwo(s: string): number
19976abd3dc2SBram Moolenaar    return len(s)
19986abd3dc2SBram Moolenaar  enddef
19996abd3dc2SBram Moolenaar  def FuncThree(n: number, s: string): number
20006abd3dc2SBram Moolenaar    return n + len(s)
20016abd3dc2SBram Moolenaar  enddef
20026abd3dc2SBram Moolenaar  var list = [FuncOne, FuncTwo, FuncThree]
20036abd3dc2SBram Moolenaar  assert_equal(8, list[0](8))
20046abd3dc2SBram Moolenaar  assert_equal(4, list[1]('word'))
20056abd3dc2SBram Moolenaar  assert_equal(7, list[2](3, 'word'))
20066abd3dc2SBram Moolenaarenddef
20076abd3dc2SBram Moolenaar
20085e774c75SBram Moolenaardef MultiLine(
20095e774c75SBram Moolenaar    arg1: string,
20105e774c75SBram Moolenaar    arg2 = 1234,
20115e774c75SBram Moolenaar    ...rest: list<string>
20125e774c75SBram Moolenaar      ): string
20135e774c75SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
20145e774c75SBram Moolenaarenddef
20155e774c75SBram Moolenaar
20162c330432SBram Moolenaardef MultiLineComment(
20172c330432SBram Moolenaar    arg1: string, # comment
20182c330432SBram Moolenaar    arg2 = 1234, # comment
20192c330432SBram Moolenaar    ...rest: list<string> # comment
20202c330432SBram Moolenaar      ): string # comment
20212c330432SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
20222c330432SBram Moolenaarenddef
20232c330432SBram Moolenaar
20245e774c75SBram Moolenaardef Test_multiline()
2025c0c71e9dSBram Moolenaar  MultiLine('text')->assert_equal('text1234')
2026c0c71e9dSBram Moolenaar  MultiLine('text', 777)->assert_equal('text777')
2027c0c71e9dSBram Moolenaar  MultiLine('text', 777, 'one')->assert_equal('text777one')
2028c0c71e9dSBram Moolenaar  MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
20295e774c75SBram Moolenaarenddef
20305e774c75SBram Moolenaar
203123e03252SBram Moolenaarfunc Test_multiline_not_vim9()
2032c0c71e9dSBram Moolenaar  call MultiLine('text')->assert_equal('text1234')
2033c0c71e9dSBram Moolenaar  call MultiLine('text', 777)->assert_equal('text777')
2034c0c71e9dSBram Moolenaar  call MultiLine('text', 777, 'one')->assert_equal('text777one')
2035c0c71e9dSBram Moolenaar  call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
203623e03252SBram Moolenaarendfunc
203723e03252SBram Moolenaar
20385e774c75SBram Moolenaar
2039ee4e0c1eSBram Moolenaar" When using CheckScriptFailure() for the below test, E1010 is generated instead
2040ee4e0c1eSBram Moolenaar" of E1056.
2041ee4e0c1eSBram Moolenaarfunc Test_E1056_1059()
2042ee4e0c1eSBram Moolenaar  let caught_1056 = 0
2043ee4e0c1eSBram Moolenaar  try
2044ee4e0c1eSBram Moolenaar    def F():
2045ee4e0c1eSBram Moolenaar      return 1
2046ee4e0c1eSBram Moolenaar    enddef
2047ee4e0c1eSBram Moolenaar  catch /E1056:/
2048ee4e0c1eSBram Moolenaar    let caught_1056 = 1
2049ee4e0c1eSBram Moolenaar  endtry
2050c0c71e9dSBram Moolenaar  eval caught_1056->assert_equal(1)
2051ee4e0c1eSBram Moolenaar
2052ee4e0c1eSBram Moolenaar  let caught_1059 = 0
2053ee4e0c1eSBram Moolenaar  try
2054ee4e0c1eSBram Moolenaar    def F5(items : list)
2055ee4e0c1eSBram Moolenaar      echo 'a'
2056ee4e0c1eSBram Moolenaar    enddef
2057ee4e0c1eSBram Moolenaar  catch /E1059:/
2058ee4e0c1eSBram Moolenaar    let caught_1059 = 1
2059ee4e0c1eSBram Moolenaar  endtry
2060c0c71e9dSBram Moolenaar  eval caught_1059->assert_equal(1)
2061ee4e0c1eSBram Moolenaarendfunc
20625deeb3f1SBram Moolenaar
2063015f4267SBram Moolenaarfunc DelMe()
2064015f4267SBram Moolenaar  echo 'DelMe'
2065015f4267SBram Moolenaarendfunc
2066015f4267SBram Moolenaar
2067bf8feb5aSBram Moolenaardef Test_error_reporting()
2068bf8feb5aSBram Moolenaar  # comment lines at the start of the function
20697a9cbca0SBram Moolenaar  var lines =<< trim END
2070bf8feb5aSBram Moolenaar    " comment
2071bf8feb5aSBram Moolenaar    def Func()
2072bf8feb5aSBram Moolenaar      # comment
2073bf8feb5aSBram Moolenaar      # comment
2074bf8feb5aSBram Moolenaar      invalid
2075bf8feb5aSBram Moolenaar    enddef
2076bf8feb5aSBram Moolenaar    defcompile
2077bf8feb5aSBram Moolenaar  END
207808052228SBram Moolenaar  writefile(lines, 'Xdef')
2079bf8feb5aSBram Moolenaar  try
2080bf8feb5aSBram Moolenaar    source Xdef
20817517ffdbSBram Moolenaar    assert_report('should have failed')
2082bf8feb5aSBram Moolenaar  catch /E476:/
2083c0c71e9dSBram Moolenaar    v:exception->assert_match('Invalid command: invalid')
2084c0c71e9dSBram Moolenaar    v:throwpoint->assert_match(', line 3$')
2085bf8feb5aSBram Moolenaar  endtry
20862d870f8dSBram Moolenaar  delfunc! g:Func
2087bf8feb5aSBram Moolenaar
2088bf8feb5aSBram Moolenaar  # comment lines after the start of the function
2089bf8feb5aSBram Moolenaar  lines =<< trim END
2090bf8feb5aSBram Moolenaar    " comment
2091bf8feb5aSBram Moolenaar    def Func()
20927a9cbca0SBram Moolenaar      var x = 1234
2093bf8feb5aSBram Moolenaar      # comment
2094bf8feb5aSBram Moolenaar      # comment
2095bf8feb5aSBram Moolenaar      invalid
2096bf8feb5aSBram Moolenaar    enddef
2097bf8feb5aSBram Moolenaar    defcompile
2098bf8feb5aSBram Moolenaar  END
209908052228SBram Moolenaar  writefile(lines, 'Xdef')
2100bf8feb5aSBram Moolenaar  try
2101bf8feb5aSBram Moolenaar    source Xdef
21027517ffdbSBram Moolenaar    assert_report('should have failed')
2103bf8feb5aSBram Moolenaar  catch /E476:/
2104c0c71e9dSBram Moolenaar    v:exception->assert_match('Invalid command: invalid')
2105c0c71e9dSBram Moolenaar    v:throwpoint->assert_match(', line 4$')
2106bf8feb5aSBram Moolenaar  endtry
21072d870f8dSBram Moolenaar  delfunc! g:Func
2108bf8feb5aSBram Moolenaar
21097517ffdbSBram Moolenaar  lines =<< trim END
21107517ffdbSBram Moolenaar    vim9script
21117517ffdbSBram Moolenaar    def Func()
2112e0de171eSBram Moolenaar      var db = {foo: 1, bar: 2}
21137517ffdbSBram Moolenaar      # comment
21147a9cbca0SBram Moolenaar      var x = db.asdf
21157517ffdbSBram Moolenaar    enddef
21167517ffdbSBram Moolenaar    defcompile
21177517ffdbSBram Moolenaar    Func()
21187517ffdbSBram Moolenaar  END
211908052228SBram Moolenaar  writefile(lines, 'Xdef')
21207517ffdbSBram Moolenaar  try
21217517ffdbSBram Moolenaar    source Xdef
21227517ffdbSBram Moolenaar    assert_report('should have failed')
21237517ffdbSBram Moolenaar  catch /E716:/
2124c0c71e9dSBram Moolenaar    v:throwpoint->assert_match('_Func, line 3$')
21257517ffdbSBram Moolenaar  endtry
21262d870f8dSBram Moolenaar  delfunc! g:Func
21277517ffdbSBram Moolenaar
212808052228SBram Moolenaar  delete('Xdef')
2129bf8feb5aSBram Moolenaarenddef
2130bf8feb5aSBram Moolenaar
2131015f4267SBram Moolenaardef Test_deleted_function()
2132015f4267SBram Moolenaar  CheckDefExecFailure([
21337a9cbca0SBram Moolenaar      'var RefMe: func = function("g:DelMe")',
2134015f4267SBram Moolenaar      'delfunc g:DelMe',
2135015f4267SBram Moolenaar      'echo RefMe()'], 'E117:')
2136015f4267SBram Moolenaarenddef
2137015f4267SBram Moolenaar
2138015f4267SBram Moolenaardef Test_unknown_function()
2139015f4267SBram Moolenaar  CheckDefExecFailure([
21407a9cbca0SBram Moolenaar      'var Ref: func = function("NotExist")',
21419b7bf9e9SBram Moolenaar      'delfunc g:NotExist'], 'E700:')
2142015f4267SBram Moolenaarenddef
2143015f4267SBram Moolenaar
2144328eac2bSBram Moolenaardef RefFunc(Ref: func(any): any): string
2145c8cd2b34SBram Moolenaar  return Ref('more')
2146c8cd2b34SBram Moolenaarenddef
2147c8cd2b34SBram Moolenaar
2148c8cd2b34SBram Moolenaardef Test_closure_simple()
21497a9cbca0SBram Moolenaar  var local = 'some '
21502949cfdbSBram Moolenaar  RefFunc((s) => local .. s)->assert_equal('some more')
2151c8cd2b34SBram Moolenaarenddef
2152c8cd2b34SBram Moolenaar
2153bf67ea1aSBram Moolenaardef MakeRef()
21547a9cbca0SBram Moolenaar  var local = 'some '
21552949cfdbSBram Moolenaar  g:Ref = (s) => local .. s
2156bf67ea1aSBram Moolenaarenddef
2157bf67ea1aSBram Moolenaar
2158bf67ea1aSBram Moolenaardef Test_closure_ref_after_return()
2159bf67ea1aSBram Moolenaar  MakeRef()
2160c0c71e9dSBram Moolenaar  g:Ref('thing')->assert_equal('some thing')
2161bf67ea1aSBram Moolenaar  unlet g:Ref
2162bf67ea1aSBram Moolenaarenddef
2163bf67ea1aSBram Moolenaar
21645adc55cbSBram Moolenaardef MakeTwoRefs()
21657a9cbca0SBram Moolenaar  var local = ['some']
21662949cfdbSBram Moolenaar  g:Extend = (s) => local->add(s)
21672949cfdbSBram Moolenaar  g:Read = () => local
21685adc55cbSBram Moolenaarenddef
21695adc55cbSBram Moolenaar
21705adc55cbSBram Moolenaardef Test_closure_two_refs()
21715adc55cbSBram Moolenaar  MakeTwoRefs()
2172c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some')
21735adc55cbSBram Moolenaar  g:Extend('more')
2174c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some more')
21755adc55cbSBram Moolenaar  g:Extend('even')
2176c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some more even')
21775adc55cbSBram Moolenaar
21785adc55cbSBram Moolenaar  unlet g:Extend
21795adc55cbSBram Moolenaar  unlet g:Read
21805adc55cbSBram Moolenaarenddef
21815adc55cbSBram Moolenaar
21825adc55cbSBram Moolenaardef ReadRef(Ref: func(): list<string>): string
21835adc55cbSBram Moolenaar  return join(Ref(), ' ')
21845adc55cbSBram Moolenaarenddef
21855adc55cbSBram Moolenaar
21865e654230SBram Moolenaardef ExtendRef(Ref: func(string): list<string>, add: string)
21875adc55cbSBram Moolenaar  Ref(add)
21885adc55cbSBram Moolenaarenddef
21895adc55cbSBram Moolenaar
21905adc55cbSBram Moolenaardef Test_closure_two_indirect_refs()
2191f7779c63SBram Moolenaar  MakeTwoRefs()
2192c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some')
21935adc55cbSBram Moolenaar  ExtendRef(g:Extend, 'more')
2194c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some more')
21955adc55cbSBram Moolenaar  ExtendRef(g:Extend, 'even')
2196c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some more even')
21975adc55cbSBram Moolenaar
21985adc55cbSBram Moolenaar  unlet g:Extend
21995adc55cbSBram Moolenaar  unlet g:Read
22005adc55cbSBram Moolenaarenddef
2201bf67ea1aSBram Moolenaar
22022fd4cd75SBram Moolenaardef MakeArgRefs(theArg: string)
22037a9cbca0SBram Moolenaar  var local = 'loc_val'
22042949cfdbSBram Moolenaar  g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
22052fd4cd75SBram Moolenaarenddef
22062fd4cd75SBram Moolenaar
22072fd4cd75SBram Moolenaardef MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
22087a9cbca0SBram Moolenaar  var local = 'the_loc'
22092949cfdbSBram Moolenaar  g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
22102fd4cd75SBram Moolenaarenddef
22112fd4cd75SBram Moolenaar
22122fd4cd75SBram Moolenaardef Test_closure_using_argument()
22132fd4cd75SBram Moolenaar  MakeArgRefs('arg_val')
2214c0c71e9dSBram Moolenaar  g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
22152fd4cd75SBram Moolenaar
22162fd4cd75SBram Moolenaar  MakeArgRefsVarargs('arg_val', 'one', 'two')
2217c0c71e9dSBram Moolenaar  g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
22182fd4cd75SBram Moolenaar
22192fd4cd75SBram Moolenaar  unlet g:UseArg
22202fd4cd75SBram Moolenaar  unlet g:UseVararg
222144ec21c4SBram Moolenaar
222244ec21c4SBram Moolenaar  var lines =<< trim END
222344ec21c4SBram Moolenaar      vim9script
222444ec21c4SBram Moolenaar      def Test(Fun: func(number): number): list<number>
222544ec21c4SBram Moolenaar        return map([1, 2, 3], (_, i) => Fun(i))
222644ec21c4SBram Moolenaar      enddef
222744ec21c4SBram Moolenaar      def Inc(nr: number): number
222844ec21c4SBram Moolenaar        return nr + 2
222944ec21c4SBram Moolenaar      enddef
223044ec21c4SBram Moolenaar      assert_equal([3, 4, 5], Test(Inc))
223144ec21c4SBram Moolenaar  END
223244ec21c4SBram Moolenaar  CheckScriptSuccess(lines)
22332fd4cd75SBram Moolenaarenddef
22342fd4cd75SBram Moolenaar
223585d5e2b7SBram Moolenaardef MakeGetAndAppendRefs()
223685d5e2b7SBram Moolenaar  var local = 'a'
223785d5e2b7SBram Moolenaar
223885d5e2b7SBram Moolenaar  def Append(arg: string)
223985d5e2b7SBram Moolenaar    local ..= arg
224085d5e2b7SBram Moolenaar  enddef
224185d5e2b7SBram Moolenaar  g:Append = Append
224285d5e2b7SBram Moolenaar
224385d5e2b7SBram Moolenaar  def Get(): string
224485d5e2b7SBram Moolenaar    return local
224585d5e2b7SBram Moolenaar  enddef
224685d5e2b7SBram Moolenaar  g:Get = Get
224785d5e2b7SBram Moolenaarenddef
224885d5e2b7SBram Moolenaar
224985d5e2b7SBram Moolenaardef Test_closure_append_get()
225085d5e2b7SBram Moolenaar  MakeGetAndAppendRefs()
225185d5e2b7SBram Moolenaar  g:Get()->assert_equal('a')
225285d5e2b7SBram Moolenaar  g:Append('-b')
225385d5e2b7SBram Moolenaar  g:Get()->assert_equal('a-b')
225485d5e2b7SBram Moolenaar  g:Append('-c')
225585d5e2b7SBram Moolenaar  g:Get()->assert_equal('a-b-c')
225685d5e2b7SBram Moolenaar
225785d5e2b7SBram Moolenaar  unlet g:Append
225885d5e2b7SBram Moolenaar  unlet g:Get
225985d5e2b7SBram Moolenaarenddef
2260b68b346eSBram Moolenaar
226104b12697SBram Moolenaardef Test_nested_closure()
22627a9cbca0SBram Moolenaar  var local = 'text'
226304b12697SBram Moolenaar  def Closure(arg: string): string
226404b12697SBram Moolenaar    return local .. arg
226504b12697SBram Moolenaar  enddef
2266c0c71e9dSBram Moolenaar  Closure('!!!')->assert_equal('text!!!')
226704b12697SBram Moolenaarenddef
226804b12697SBram Moolenaar
22696f5b6dfbSBram Moolenaarfunc GetResult(Ref)
22706f5b6dfbSBram Moolenaar  return a:Ref('some')
22716f5b6dfbSBram Moolenaarendfunc
22726f5b6dfbSBram Moolenaar
22736f5b6dfbSBram Moolenaardef Test_call_closure_not_compiled()
22747a9cbca0SBram Moolenaar  var text = 'text'
22752949cfdbSBram Moolenaar  g:Ref = (s) =>  s .. text
2276c0c71e9dSBram Moolenaar  GetResult(g:Ref)->assert_equal('sometext')
22776f5b6dfbSBram Moolenaarenddef
22786f5b6dfbSBram Moolenaar
22797cbfaa51SBram Moolenaardef Test_double_closure_fails()
22807a9cbca0SBram Moolenaar  var lines =<< trim END
22817cbfaa51SBram Moolenaar    vim9script
22827cbfaa51SBram Moolenaar    def Func()
22837a9cbca0SBram Moolenaar      var name = 0
22847cbfaa51SBram Moolenaar      for i in range(2)
22852949cfdbSBram Moolenaar          timer_start(0, () => name)
22867cbfaa51SBram Moolenaar      endfor
22877cbfaa51SBram Moolenaar    enddef
22887cbfaa51SBram Moolenaar    Func()
22897cbfaa51SBram Moolenaar  END
2290148ce7aeSBram Moolenaar  CheckScriptSuccess(lines)
22917cbfaa51SBram Moolenaarenddef
22927cbfaa51SBram Moolenaar
229385d5e2b7SBram Moolenaardef Test_nested_closure_used()
229485d5e2b7SBram Moolenaar  var lines =<< trim END
229585d5e2b7SBram Moolenaar      vim9script
229685d5e2b7SBram Moolenaar      def Func()
229785d5e2b7SBram Moolenaar        var x = 'hello'
22982949cfdbSBram Moolenaar        var Closure = () => x
22992949cfdbSBram Moolenaar        g:Myclosure = () => Closure()
230085d5e2b7SBram Moolenaar      enddef
230185d5e2b7SBram Moolenaar      Func()
230285d5e2b7SBram Moolenaar      assert_equal('hello', g:Myclosure())
230385d5e2b7SBram Moolenaar  END
230485d5e2b7SBram Moolenaar  CheckScriptSuccess(lines)
230585d5e2b7SBram Moolenaarenddef
23060876c785SBram Moolenaar
2307c70bdab0SBram Moolenaardef Test_nested_closure_fails()
23087a9cbca0SBram Moolenaar  var lines =<< trim END
2309c70bdab0SBram Moolenaar    vim9script
2310c70bdab0SBram Moolenaar    def FuncA()
2311c70bdab0SBram Moolenaar      FuncB(0)
2312c70bdab0SBram Moolenaar    enddef
2313c70bdab0SBram Moolenaar    def FuncB(n: number): list<string>
23142949cfdbSBram Moolenaar      return map([0], (_, v) => n)
2315c70bdab0SBram Moolenaar    enddef
2316c70bdab0SBram Moolenaar    FuncA()
2317c70bdab0SBram Moolenaar  END
2318c70bdab0SBram Moolenaar  CheckScriptFailure(lines, 'E1012:')
2319c70bdab0SBram Moolenaarenddef
2320c70bdab0SBram Moolenaar
2321f112f30aSBram Moolenaardef Test_global_closure()
2322f112f30aSBram Moolenaar  var lines =<< trim END
2323f112f30aSBram Moolenaar      vim9script
2324f112f30aSBram Moolenaar      def ReverseEveryNLines(n: number, line1: number, line2: number)
2325f112f30aSBram Moolenaar        var mods = 'sil keepj keepp lockm '
2326f112f30aSBram Moolenaar        var range = ':' .. line1 .. ',' .. line2
2327f112f30aSBram Moolenaar        def g:Offset(): number
2328f112f30aSBram Moolenaar            var offset = (line('.') - line1 + 1) % n
2329f112f30aSBram Moolenaar            return offset != 0 ? offset : n
2330f112f30aSBram Moolenaar        enddef
2331f112f30aSBram Moolenaar        exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
2332f112f30aSBram Moolenaar      enddef
2333f112f30aSBram Moolenaar
2334f112f30aSBram Moolenaar      new
2335f112f30aSBram Moolenaar      repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
2336f112f30aSBram Moolenaar      ReverseEveryNLines(3, 1, 9)
2337f112f30aSBram Moolenaar  END
2338f112f30aSBram Moolenaar  CheckScriptSuccess(lines)
2339f112f30aSBram Moolenaar  var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
2340f112f30aSBram Moolenaar  assert_equal(expected, getline(1, 9))
2341f112f30aSBram Moolenaar  bwipe!
2342f112f30aSBram Moolenaarenddef
2343f112f30aSBram Moolenaar
2344cd45ed03SBram Moolenaardef Test_global_closure_called_directly()
2345cd45ed03SBram Moolenaar  var lines =<< trim END
2346cd45ed03SBram Moolenaar      vim9script
2347cd45ed03SBram Moolenaar      def Outer()
2348cd45ed03SBram Moolenaar        var x = 1
2349cd45ed03SBram Moolenaar        def g:Inner()
2350cd45ed03SBram Moolenaar          var y = x
2351cd45ed03SBram Moolenaar          x += 1
2352cd45ed03SBram Moolenaar          assert_equal(1, y)
2353cd45ed03SBram Moolenaar        enddef
2354cd45ed03SBram Moolenaar        g:Inner()
2355cd45ed03SBram Moolenaar        assert_equal(2, x)
2356cd45ed03SBram Moolenaar      enddef
2357cd45ed03SBram Moolenaar      Outer()
2358cd45ed03SBram Moolenaar  END
2359cd45ed03SBram Moolenaar  CheckScriptSuccess(lines)
2360cd45ed03SBram Moolenaar  delfunc g:Inner
2361cd45ed03SBram Moolenaarenddef
2362cd45ed03SBram Moolenaar
236334c54eb6SBram Moolenaardef Test_failure_in_called_function()
236434c54eb6SBram Moolenaar  # this was using the frame index as the return value
236534c54eb6SBram Moolenaar  var lines =<< trim END
236634c54eb6SBram Moolenaar      vim9script
236734c54eb6SBram Moolenaar      au TerminalWinOpen * eval [][0]
236834c54eb6SBram Moolenaar      def PopupTerm(a: any)
236934c54eb6SBram Moolenaar        # make sure typvals on stack are string
237034c54eb6SBram Moolenaar        ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
237134c54eb6SBram Moolenaar        FireEvent()
237234c54eb6SBram Moolenaar      enddef
237334c54eb6SBram Moolenaar      def FireEvent()
237434c54eb6SBram Moolenaar          do TerminalWinOpen
237534c54eb6SBram Moolenaar      enddef
237634c54eb6SBram Moolenaar      # use try/catch to make eval fail
237734c54eb6SBram Moolenaar      try
237834c54eb6SBram Moolenaar          call PopupTerm(0)
237934c54eb6SBram Moolenaar      catch
238034c54eb6SBram Moolenaar      endtry
238134c54eb6SBram Moolenaar      au! TerminalWinOpen
238234c54eb6SBram Moolenaar  END
238334c54eb6SBram Moolenaar  CheckScriptSuccess(lines)
238434c54eb6SBram Moolenaarenddef
238534c54eb6SBram Moolenaar
23865366e1aeSBram Moolenaardef Test_nested_lambda()
23875366e1aeSBram Moolenaar  var lines =<< trim END
23885366e1aeSBram Moolenaar    vim9script
23895366e1aeSBram Moolenaar    def Func()
23905366e1aeSBram Moolenaar      var x = 4
23912949cfdbSBram Moolenaar      var Lambda1 = () => 7
23922949cfdbSBram Moolenaar      var Lambda2 = () => [Lambda1(), x]
23935366e1aeSBram Moolenaar      var res = Lambda2()
23945366e1aeSBram Moolenaar      assert_equal([7, 4], res)
23955366e1aeSBram Moolenaar    enddef
23965366e1aeSBram Moolenaar    Func()
23975366e1aeSBram Moolenaar  END
23985366e1aeSBram Moolenaar  CheckScriptSuccess(lines)
23995366e1aeSBram Moolenaarenddef
24005366e1aeSBram Moolenaar
2401c04f2a4cSBram Moolenaardef Test_double_nested_lambda()
2402c04f2a4cSBram Moolenaar  var lines =<< trim END
2403c04f2a4cSBram Moolenaar      vim9script
2404c04f2a4cSBram Moolenaar      def F(head: string): func(string): func(string): string
2405c04f2a4cSBram Moolenaar        return (sep: string): func(string): string => ((tail: string): string => {
2406c04f2a4cSBram Moolenaar            return head .. sep .. tail
2407c04f2a4cSBram Moolenaar          })
2408c04f2a4cSBram Moolenaar      enddef
2409c04f2a4cSBram Moolenaar      assert_equal('hello-there', F('hello')('-')('there'))
2410c04f2a4cSBram Moolenaar  END
2411c04f2a4cSBram Moolenaar  CheckScriptSuccess(lines)
2412c04f2a4cSBram Moolenaarenddef
2413c04f2a4cSBram Moolenaar
2414074f84c0SBram Moolenaardef Test_nested_inline_lambda()
2415074f84c0SBram Moolenaar  var lines =<< trim END
2416074f84c0SBram Moolenaar      vim9script
2417074f84c0SBram Moolenaar      def F(text: string): func(string): func(string): string
2418074f84c0SBram Moolenaar        return (arg: string): func(string): string => ((sep: string): string => {
241923e2e115SBram Moolenaar            return sep .. arg .. text
2420074f84c0SBram Moolenaar          })
2421074f84c0SBram Moolenaar      enddef
242223e2e115SBram Moolenaar      assert_equal('--there++', F('++')('there')('--'))
2423074f84c0SBram Moolenaar  END
2424074f84c0SBram Moolenaar  CheckScriptSuccess(lines)
24255245beb3SBram Moolenaar
24265245beb3SBram Moolenaar  lines =<< trim END
24275245beb3SBram Moolenaar      vim9script
24285245beb3SBram Moolenaar      echo range(4)->mapnew((_, v) => {
24295245beb3SBram Moolenaar        return range(v) ->mapnew((_, s) => {
24305245beb3SBram Moolenaar          return string(s)
24315245beb3SBram Moolenaar          })
24325245beb3SBram Moolenaar        })
24335245beb3SBram Moolenaar  END
24345245beb3SBram Moolenaar  CheckScriptSuccess(lines)
2435c6ba2f9dSBram Moolenaar
2436c6ba2f9dSBram Moolenaar  lines =<< trim END
2437c6ba2f9dSBram Moolenaar      vim9script
2438c6ba2f9dSBram Moolenaar
2439c6ba2f9dSBram Moolenaar      def s:func()
2440c6ba2f9dSBram Moolenaar        range(10)
2441c6ba2f9dSBram Moolenaar          ->mapnew((_, _) => ({
2442c6ba2f9dSBram Moolenaar            key: range(10)->mapnew((_, _) => {
2443c6ba2f9dSBram Moolenaar              return ' '
2444c6ba2f9dSBram Moolenaar            }),
2445c6ba2f9dSBram Moolenaar          }))
2446c6ba2f9dSBram Moolenaar      enddef
2447c6ba2f9dSBram Moolenaar
2448c6ba2f9dSBram Moolenaar      defcomp
2449c6ba2f9dSBram Moolenaar  END
2450c6ba2f9dSBram Moolenaar  CheckScriptSuccess(lines)
2451074f84c0SBram Moolenaarenddef
2452074f84c0SBram Moolenaar
245352bf81c2SBram Moolenaardef Shadowed(): list<number>
24542949cfdbSBram Moolenaar  var FuncList: list<func: number> = [() => 42]
245575ab91ffSBram Moolenaar  return FuncList->mapnew((_, Shadowed) => Shadowed())
245652bf81c2SBram Moolenaarenddef
245752bf81c2SBram Moolenaar
245852bf81c2SBram Moolenaardef Test_lambda_arg_shadows_func()
245952bf81c2SBram Moolenaar  assert_equal([42], Shadowed())
246052bf81c2SBram Moolenaarenddef
246152bf81c2SBram Moolenaar
2462acd4c5e9SBram Moolenaardef Line_continuation_in_def(dir: string = ''): string
24637a9cbca0SBram Moolenaar  var path: string = empty(dir)
2464acd4c5e9SBram Moolenaar          \ ? 'empty'
2465acd4c5e9SBram Moolenaar          \ : 'full'
2466acd4c5e9SBram Moolenaar  return path
2467acd4c5e9SBram Moolenaarenddef
2468acd4c5e9SBram Moolenaar
2469acd4c5e9SBram Moolenaardef Test_line_continuation_in_def()
2470c0c71e9dSBram Moolenaar  Line_continuation_in_def('.')->assert_equal('full')
2471acd4c5e9SBram Moolenaarenddef
2472acd4c5e9SBram Moolenaar
24732ea95b61SBram Moolenaardef Test_script_var_in_lambda()
24742ea95b61SBram Moolenaar  var lines =<< trim END
24752ea95b61SBram Moolenaar      vim9script
24762ea95b61SBram Moolenaar      var script = 'test'
2477bb8a7ce0SBram Moolenaar      assert_equal(['test'], map(['one'], (_, _) => script))
24782ea95b61SBram Moolenaar  END
24792ea95b61SBram Moolenaar  CheckScriptSuccess(lines)
24802ea95b61SBram Moolenaarenddef
24812ea95b61SBram Moolenaar
24825e654230SBram Moolenaardef Line_continuation_in_lambda(): list<string>
24837a9cbca0SBram Moolenaar  var x = range(97, 100)
248475ab91ffSBram Moolenaar      ->mapnew((_, v) => nr2char(v)
24852949cfdbSBram Moolenaar          ->toupper())
24867a4b8980SBram Moolenaar      ->reverse()
24877a4b8980SBram Moolenaar  return x
24887a4b8980SBram Moolenaarenddef
24897a4b8980SBram Moolenaar
24907a4b8980SBram Moolenaardef Test_line_continuation_in_lambda()
2491c0c71e9dSBram Moolenaar  Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
2492f898f7c6SBram Moolenaar
2493f898f7c6SBram Moolenaar  var lines =<< trim END
2494f898f7c6SBram Moolenaar      vim9script
2495f898f7c6SBram Moolenaar      var res = [{n: 1, m: 2, s: 'xxx'}]
2496f898f7c6SBram Moolenaar                ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
2497f898f7c6SBram Moolenaar                    v.n,
2498f898f7c6SBram Moolenaar                    v.m,
2499f898f7c6SBram Moolenaar                    substitute(v.s, '.*', 'yyy', '')
2500f898f7c6SBram Moolenaar                    ))
2501f898f7c6SBram Moolenaar      assert_equal(['1:2:yyy'], res)
2502f898f7c6SBram Moolenaar  END
2503f898f7c6SBram Moolenaar  CheckScriptSuccess(lines)
25047a4b8980SBram Moolenaarenddef
25057a4b8980SBram Moolenaar
2506b657198cSBram Moolenaardef Test_list_lambda()
2507b657198cSBram Moolenaar  timer_start(1000, (_) => 0)
2508b657198cSBram Moolenaar  var body = execute(timer_info()[0].callback
2509b657198cSBram Moolenaar         ->string()
2510b657198cSBram Moolenaar         ->substitute("('", ' ', '')
2511b657198cSBram Moolenaar         ->substitute("')", '', '')
2512b657198cSBram Moolenaar         ->substitute('function\zs', ' ', ''))
2513767034c5SBram Moolenaar  assert_match('def <lambda>\d\+(_: any): number\n1  return 0\n   enddef', body)
2514b657198cSBram Moolenaarenddef
2515b657198cSBram Moolenaar
25163c77b6a1SBram Moolenaardef Test_lambda_block_variable()
251788421d6dSBram Moolenaar  var lines =<< trim END
251888421d6dSBram Moolenaar      vim9script
251988421d6dSBram Moolenaar      var flist: list<func>
252088421d6dSBram Moolenaar      for i in range(10)
252188421d6dSBram Moolenaar          var inloop = i
252288421d6dSBram Moolenaar          flist[i] = () => inloop
252388421d6dSBram Moolenaar      endfor
252488421d6dSBram Moolenaar  END
252588421d6dSBram Moolenaar  CheckScriptSuccess(lines)
252688421d6dSBram Moolenaar
252788421d6dSBram Moolenaar  lines =<< trim END
252888421d6dSBram Moolenaar      vim9script
252988421d6dSBram Moolenaar      if true
253088421d6dSBram Moolenaar        var outloop = 5
253188421d6dSBram Moolenaar        var flist: list<func>
253288421d6dSBram Moolenaar        for i in range(10)
253388421d6dSBram Moolenaar          flist[i] = () => outloop
253488421d6dSBram Moolenaar        endfor
253588421d6dSBram Moolenaar      endif
253688421d6dSBram Moolenaar  END
253788421d6dSBram Moolenaar  CheckScriptSuccess(lines)
253888421d6dSBram Moolenaar
253988421d6dSBram Moolenaar  lines =<< trim END
254088421d6dSBram Moolenaar      vim9script
254188421d6dSBram Moolenaar      if true
254288421d6dSBram Moolenaar        var outloop = 5
254388421d6dSBram Moolenaar      endif
254488421d6dSBram Moolenaar      var flist: list<func>
254588421d6dSBram Moolenaar      for i in range(10)
254688421d6dSBram Moolenaar        flist[i] = () => outloop
254788421d6dSBram Moolenaar      endfor
254888421d6dSBram Moolenaar  END
254988421d6dSBram Moolenaar  CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
25503c77b6a1SBram Moolenaar
25513c77b6a1SBram Moolenaar  lines =<< trim END
25523c77b6a1SBram Moolenaar      vim9script
25533c77b6a1SBram Moolenaar      for i in range(10)
25543c77b6a1SBram Moolenaar        var Ref = () => 0
25553c77b6a1SBram Moolenaar      endfor
25563c77b6a1SBram Moolenaar      assert_equal(0, ((i) => 0)(0))
25573c77b6a1SBram Moolenaar  END
25583c77b6a1SBram Moolenaar  CheckScriptSuccess(lines)
255988421d6dSBram Moolenaarenddef
256088421d6dSBram Moolenaar
256196cf4ba8SBram Moolenaardef Test_legacy_lambda()
256296cf4ba8SBram Moolenaar  legacy echo {x -> 'hello ' .. x}('foo')
2563dc4c2309SBram Moolenaar
256496cf4ba8SBram Moolenaar  var lines =<< trim END
256596cf4ba8SBram Moolenaar      echo {x -> 'hello ' .. x}('foo')
256696cf4ba8SBram Moolenaar  END
256796cf4ba8SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E720:')
2568dc4c2309SBram Moolenaar
2569dc4c2309SBram Moolenaar  lines =<< trim END
2570dc4c2309SBram Moolenaar      vim9script
2571dc4c2309SBram Moolenaar      def Func()
2572dc4c2309SBram Moolenaar        echo (() => 'no error')()
2573dc4c2309SBram Moolenaar      enddef
2574dc4c2309SBram Moolenaar      legacy call s:Func()
2575dc4c2309SBram Moolenaar  END
2576dc4c2309SBram Moolenaar  CheckScriptSuccess(lines)
257796cf4ba8SBram Moolenaarenddef
257896cf4ba8SBram Moolenaar
2579ce024c3eSBram Moolenaardef Test_legacy()
2580ce024c3eSBram Moolenaar  var lines =<< trim END
2581ce024c3eSBram Moolenaar      vim9script
2582ce024c3eSBram Moolenaar      func g:LegacyFunction()
2583ce024c3eSBram Moolenaar        let g:legacyvar = 1
2584ce024c3eSBram Moolenaar      endfunc
2585ce024c3eSBram Moolenaar      def Testit()
2586ce024c3eSBram Moolenaar        legacy call g:LegacyFunction()
2587ce024c3eSBram Moolenaar      enddef
2588ce024c3eSBram Moolenaar      Testit()
2589ce024c3eSBram Moolenaar      assert_equal(1, g:legacyvar)
2590ce024c3eSBram Moolenaar      unlet g:legacyvar
2591ce024c3eSBram Moolenaar      delfunc g:LegacyFunction
2592ce024c3eSBram Moolenaar  END
2593ce024c3eSBram Moolenaar  CheckScriptSuccess(lines)
2594ce024c3eSBram Moolenaarenddef
2595ce024c3eSBram Moolenaar
2596c3cb1c92SBram Moolenaardef Test_legacy_errors()
2597c3cb1c92SBram Moolenaar  for cmd in ['if', 'elseif', 'else', 'endif',
2598c3cb1c92SBram Moolenaar              'for', 'endfor', 'continue', 'break',
2599c3cb1c92SBram Moolenaar              'while', 'endwhile',
2600c3cb1c92SBram Moolenaar              'try', 'catch', 'finally', 'endtry']
2601c3cb1c92SBram Moolenaar    CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
2602c3cb1c92SBram Moolenaar  endfor
2603c3cb1c92SBram Moolenaarenddef
2604c3cb1c92SBram Moolenaar
2605b1b6f4deSBram Moolenaardef Test_call_legacy_with_dict()
2606b1b6f4deSBram Moolenaar  var lines =<< trim END
2607b1b6f4deSBram Moolenaar      vim9script
2608b1b6f4deSBram Moolenaar      func Legacy() dict
2609b1b6f4deSBram Moolenaar        let g:result = self.value
2610b1b6f4deSBram Moolenaar      endfunc
2611b1b6f4deSBram Moolenaar      def TestDirect()
2612b1b6f4deSBram Moolenaar        var d = {value: 'yes', func: Legacy}
2613b1b6f4deSBram Moolenaar        d.func()
2614b1b6f4deSBram Moolenaar      enddef
2615b1b6f4deSBram Moolenaar      TestDirect()
2616b1b6f4deSBram Moolenaar      assert_equal('yes', g:result)
2617b1b6f4deSBram Moolenaar      unlet g:result
2618b1b6f4deSBram Moolenaar
2619b1b6f4deSBram Moolenaar      def TestIndirect()
2620b1b6f4deSBram Moolenaar        var d = {value: 'foo', func: Legacy}
2621b1b6f4deSBram Moolenaar        var Fi = d.func
2622b1b6f4deSBram Moolenaar        Fi()
2623b1b6f4deSBram Moolenaar      enddef
2624b1b6f4deSBram Moolenaar      TestIndirect()
2625b1b6f4deSBram Moolenaar      assert_equal('foo', g:result)
2626b1b6f4deSBram Moolenaar      unlet g:result
2627b1b6f4deSBram Moolenaar
2628b1b6f4deSBram Moolenaar      var d = {value: 'bar', func: Legacy}
2629b1b6f4deSBram Moolenaar      d.func()
2630b1b6f4deSBram Moolenaar      assert_equal('bar', g:result)
2631b1b6f4deSBram Moolenaar      unlet g:result
2632b1b6f4deSBram Moolenaar  END
2633b1b6f4deSBram Moolenaar  CheckScriptSuccess(lines)
2634b1b6f4deSBram Moolenaarenddef
2635b1b6f4deSBram Moolenaar
2636ab360526SBram Moolenaardef DoFilterThis(a: string): list<string>
2637ab360526SBram Moolenaar  # closure nested inside another closure using argument
2638ab360526SBram Moolenaar  var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
2639ab360526SBram Moolenaar  return ['x', 'y', 'a', 'x2', 'c']->Filter()
2640ab360526SBram Moolenaarenddef
2641ab360526SBram Moolenaar
2642ab360526SBram Moolenaardef Test_nested_closure_using_argument()
2643ab360526SBram Moolenaar  assert_equal(['x', 'x2'], DoFilterThis('x'))
2644ab360526SBram Moolenaarenddef
2645ab360526SBram Moolenaar
26460186e586SBram Moolenaardef Test_triple_nested_closure()
26470186e586SBram Moolenaar  var what = 'x'
26480186e586SBram Moolenaar  var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
26490186e586SBram Moolenaar  var Filter = (l) => filter(l, (_, v) => Match(v, what))
26500186e586SBram Moolenaar  assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
26510186e586SBram Moolenaarenddef
26520186e586SBram Moolenaar
26538f510afcSBram Moolenaarfunc Test_silent_echo()
265447e7d70bSBram Moolenaar  CheckScreendump
265547e7d70bSBram Moolenaar
265647e7d70bSBram Moolenaar  let lines =<< trim END
265747e7d70bSBram Moolenaar    vim9script
265847e7d70bSBram Moolenaar    def EchoNothing()
265947e7d70bSBram Moolenaar      silent echo ''
266047e7d70bSBram Moolenaar    enddef
266147e7d70bSBram Moolenaar    defcompile
266247e7d70bSBram Moolenaar  END
26638f510afcSBram Moolenaar  call writefile(lines, 'XTest_silent_echo')
266447e7d70bSBram Moolenaar
266547e7d70bSBram Moolenaar  " Check that the balloon shows up after a mouse move
266647e7d70bSBram Moolenaar  let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
26678f510afcSBram Moolenaar  call term_sendkeys(buf, ":abc")
266847e7d70bSBram Moolenaar  call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
266947e7d70bSBram Moolenaar
267047e7d70bSBram Moolenaar  " clean up
267147e7d70bSBram Moolenaar  call StopVimInTerminal(buf)
267247e7d70bSBram Moolenaar  call delete('XTest_silent_echo')
26738f510afcSBram Moolenaarendfunc
267447e7d70bSBram Moolenaar
2675171fb923SBram Moolenaardef SilentlyError()
2676171fb923SBram Moolenaar  execute('silent! invalid')
2677171fb923SBram Moolenaar  g:did_it = 'yes'
2678171fb923SBram Moolenaarenddef
2679171fb923SBram Moolenaar
268028ee892aSBram Moolenaarfunc UserError()
268128ee892aSBram Moolenaar  silent! invalid
268228ee892aSBram Moolenaarendfunc
268328ee892aSBram Moolenaar
268428ee892aSBram Moolenaardef SilentlyUserError()
268528ee892aSBram Moolenaar  UserError()
268628ee892aSBram Moolenaar  g:did_it = 'yes'
268728ee892aSBram Moolenaarenddef
2688171fb923SBram Moolenaar
2689171fb923SBram Moolenaar" This can't be a :def function, because the assert would not be reached.
2690171fb923SBram Moolenaarfunc Test_ignore_silent_error()
2691171fb923SBram Moolenaar  let g:did_it = 'no'
2692171fb923SBram Moolenaar  call SilentlyError()
2693171fb923SBram Moolenaar  call assert_equal('yes', g:did_it)
2694171fb923SBram Moolenaar
269528ee892aSBram Moolenaar  let g:did_it = 'no'
269628ee892aSBram Moolenaar  call SilentlyUserError()
269728ee892aSBram Moolenaar  call assert_equal('yes', g:did_it)
2698171fb923SBram Moolenaar
2699171fb923SBram Moolenaar  unlet g:did_it
2700171fb923SBram Moolenaarendfunc
2701171fb923SBram Moolenaar
2702cd030c4bSBram Moolenaardef Test_ignore_silent_error_in_filter()
2703cd030c4bSBram Moolenaar  var lines =<< trim END
2704cd030c4bSBram Moolenaar      vim9script
2705cd030c4bSBram Moolenaar      def Filter(winid: number, key: string): bool
2706cd030c4bSBram Moolenaar          if key == 'o'
2707cd030c4bSBram Moolenaar              silent! eval [][0]
2708cd030c4bSBram Moolenaar              return true
2709cd030c4bSBram Moolenaar          endif
2710cd030c4bSBram Moolenaar          return popup_filter_menu(winid, key)
2711cd030c4bSBram Moolenaar      enddef
2712cd030c4bSBram Moolenaar
2713e0de171eSBram Moolenaar      popup_create('popup', {filter: Filter})
2714cd030c4bSBram Moolenaar      feedkeys("o\r", 'xnt')
2715cd030c4bSBram Moolenaar  END
2716cd030c4bSBram Moolenaar  CheckScriptSuccess(lines)
2717cd030c4bSBram Moolenaarenddef
2718cd030c4bSBram Moolenaar
27194b9bd692SBram Moolenaardef Fibonacci(n: number): number
27204b9bd692SBram Moolenaar  if n < 2
27214b9bd692SBram Moolenaar    return n
27224b9bd692SBram Moolenaar  else
27234b9bd692SBram Moolenaar    return Fibonacci(n - 1) + Fibonacci(n - 2)
27244b9bd692SBram Moolenaar  endif
27254b9bd692SBram Moolenaarenddef
27264b9bd692SBram Moolenaar
2727985116aeSBram Moolenaardef Test_recursive_call()
2728c0c71e9dSBram Moolenaar  Fibonacci(20)->assert_equal(6765)
2729985116aeSBram Moolenaarenddef
2730985116aeSBram Moolenaar
273108f7a41bSBram Moolenaardef TreeWalk(dir: string): list<any>
273275ab91ffSBram Moolenaar  return readdir(dir)->mapnew((_, val) =>
273308f7a41bSBram Moolenaar            fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
27342bede173SBram Moolenaar               ? {[val]: TreeWalk(dir .. '/' .. val)}
273508f7a41bSBram Moolenaar               : val
27362949cfdbSBram Moolenaar             )
273708f7a41bSBram Moolenaarenddef
273808f7a41bSBram Moolenaar
273908f7a41bSBram Moolenaardef Test_closure_in_map()
274008f7a41bSBram Moolenaar  mkdir('XclosureDir/tdir', 'p')
274108f7a41bSBram Moolenaar  writefile(['111'], 'XclosureDir/file1')
274208f7a41bSBram Moolenaar  writefile(['222'], 'XclosureDir/file2')
274308f7a41bSBram Moolenaar  writefile(['333'], 'XclosureDir/tdir/file3')
274408f7a41bSBram Moolenaar
2745e0de171eSBram Moolenaar  TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
274608f7a41bSBram Moolenaar
274708f7a41bSBram Moolenaar  delete('XclosureDir', 'rf')
274808f7a41bSBram Moolenaarenddef
274908f7a41bSBram Moolenaar
27507b5d5442SBram Moolenaardef Test_invalid_function_name()
27517b5d5442SBram Moolenaar  var lines =<< trim END
27527b5d5442SBram Moolenaar      vim9script
27537b5d5442SBram Moolenaar      def s: list<string>
27547b5d5442SBram Moolenaar  END
27557b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E129:')
27567b5d5442SBram Moolenaar
27577b5d5442SBram Moolenaar  lines =<< trim END
27587b5d5442SBram Moolenaar      vim9script
27597b5d5442SBram Moolenaar      def g: list<string>
27607b5d5442SBram Moolenaar  END
27617b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E129:')
27627b5d5442SBram Moolenaar
27637b5d5442SBram Moolenaar  lines =<< trim END
27647b5d5442SBram Moolenaar      vim9script
27657b5d5442SBram Moolenaar      def <SID>: list<string>
27667b5d5442SBram Moolenaar  END
27677b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E884:')
27687b5d5442SBram Moolenaar
27697b5d5442SBram Moolenaar  lines =<< trim END
27707b5d5442SBram Moolenaar      vim9script
27717b5d5442SBram Moolenaar      def F list<string>
27727b5d5442SBram Moolenaar  END
27737b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E488:')
27747b5d5442SBram Moolenaarenddef
27757b5d5442SBram Moolenaar
2776a90afb9aSBram Moolenaardef Test_partial_call()
2777f78da4f9SBram Moolenaar  var lines =<< trim END
2778f78da4f9SBram Moolenaar      var Xsetlist: func
2779f78da4f9SBram Moolenaar      Xsetlist = function('setloclist', [0])
2780e0de171eSBram Moolenaar      Xsetlist([], ' ', {title: 'test'})
2781e0de171eSBram Moolenaar      getloclist(0, {title: 1})->assert_equal({title: 'test'})
2782a90afb9aSBram Moolenaar
2783a90afb9aSBram Moolenaar      Xsetlist = function('setloclist', [0, [], ' '])
2784e0de171eSBram Moolenaar      Xsetlist({title: 'test'})
2785e0de171eSBram Moolenaar      getloclist(0, {title: 1})->assert_equal({title: 'test'})
2786a90afb9aSBram Moolenaar
2787a90afb9aSBram Moolenaar      Xsetlist = function('setqflist')
2788e0de171eSBram Moolenaar      Xsetlist([], ' ', {title: 'test'})
2789e0de171eSBram Moolenaar      getqflist({title: 1})->assert_equal({title: 'test'})
2790a90afb9aSBram Moolenaar
2791a90afb9aSBram Moolenaar      Xsetlist = function('setqflist', [[], ' '])
2792e0de171eSBram Moolenaar      Xsetlist({title: 'test'})
2793e0de171eSBram Moolenaar      getqflist({title: 1})->assert_equal({title: 'test'})
27946abd3dc2SBram Moolenaar
27956abd3dc2SBram Moolenaar      var Len: func: number = function('len', ['word'])
27966abd3dc2SBram Moolenaar      assert_equal(4, Len())
2797f78da4f9SBram Moolenaar
2798f78da4f9SBram Moolenaar      var RepeatFunc = function('repeat', ['o'])
2799f78da4f9SBram Moolenaar      assert_equal('ooooo', RepeatFunc(5))
2800f78da4f9SBram Moolenaar  END
2801f78da4f9SBram Moolenaar  CheckDefAndScriptSuccess(lines)
2802c66f645bSBram Moolenaar
2803c66f645bSBram Moolenaar  lines =<< trim END
2804c66f645bSBram Moolenaar      vim9script
2805c66f645bSBram Moolenaar      def Foo(Parser: any)
2806c66f645bSBram Moolenaar      enddef
2807c66f645bSBram Moolenaar      var Expr: func(dict<any>): dict<any>
2808c66f645bSBram Moolenaar      const Call = Foo(Expr)
2809c66f645bSBram Moolenaar  END
2810c66f645bSBram Moolenaar  CheckScriptFailure(lines, 'E1235:')
2811a90afb9aSBram Moolenaarenddef
2812a90afb9aSBram Moolenaar
28132dd0a2c3SBram Moolenaardef Test_cmd_modifier()
28142dd0a2c3SBram Moolenaar  tab echo '0'
2815d2c61705SBram Moolenaar  CheckDefFailure(['5tab echo 3'], 'E16:')
28162dd0a2c3SBram Moolenaarenddef
28172dd0a2c3SBram Moolenaar
28182dd0a2c3SBram Moolenaardef Test_restore_modifiers()
28192dd0a2c3SBram Moolenaar  # check that when compiling a :def function command modifiers are not messed
28202dd0a2c3SBram Moolenaar  # up.
28217a9cbca0SBram Moolenaar  var lines =<< trim END
28222dd0a2c3SBram Moolenaar      vim9script
28232dd0a2c3SBram Moolenaar      set eventignore=
28242dd0a2c3SBram Moolenaar      autocmd QuickFixCmdPost * copen
28252dd0a2c3SBram Moolenaar      def AutocmdsDisabled()
2826c323527dSBram Moolenaar        eval 1 + 2
28272dd0a2c3SBram Moolenaar      enddef
28282dd0a2c3SBram Moolenaar      func Func()
28292dd0a2c3SBram Moolenaar        noautocmd call s:AutocmdsDisabled()
28302dd0a2c3SBram Moolenaar        let g:ei_after = &eventignore
28312dd0a2c3SBram Moolenaar      endfunc
28322dd0a2c3SBram Moolenaar      Func()
28332dd0a2c3SBram Moolenaar  END
28342dd0a2c3SBram Moolenaar  CheckScriptSuccess(lines)
2835c0c71e9dSBram Moolenaar  g:ei_after->assert_equal('')
28362dd0a2c3SBram Moolenaarenddef
28372dd0a2c3SBram Moolenaar
2838dfa3d552SBram Moolenaardef StackTop()
2839c323527dSBram Moolenaar  eval 1 + 2
2840c323527dSBram Moolenaar  eval 2 + 3
2841dfa3d552SBram Moolenaar  # call not on fourth line
2842dfa3d552SBram Moolenaar  StackBot()
2843dfa3d552SBram Moolenaarenddef
2844dfa3d552SBram Moolenaar
2845dfa3d552SBram Moolenaardef StackBot()
2846dfa3d552SBram Moolenaar  # throw an error
2847dfa3d552SBram Moolenaar  eval [][0]
2848dfa3d552SBram Moolenaarenddef
2849dfa3d552SBram Moolenaar
2850dfa3d552SBram Moolenaardef Test_callstack_def()
2851dfa3d552SBram Moolenaar  try
2852dfa3d552SBram Moolenaar    StackTop()
2853dfa3d552SBram Moolenaar  catch
2854c0c71e9dSBram Moolenaar    v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
2855dfa3d552SBram Moolenaar  endtry
2856dfa3d552SBram Moolenaarenddef
2857dfa3d552SBram Moolenaar
2858e8211a33SBram Moolenaar" Re-using spot for variable used in block
2859e8211a33SBram Moolenaardef Test_block_scoped_var()
2860e8211a33SBram Moolenaar  var lines =<< trim END
2861e8211a33SBram Moolenaar      vim9script
2862e8211a33SBram Moolenaar      def Func()
2863e8211a33SBram Moolenaar        var x = ['a', 'b', 'c']
2864e8211a33SBram Moolenaar        if 1
2865e8211a33SBram Moolenaar          var y = 'x'
2866bb8a7ce0SBram Moolenaar          map(x, (_, _) => y)
2867e8211a33SBram Moolenaar        endif
2868e8211a33SBram Moolenaar        var z = x
2869e8211a33SBram Moolenaar        assert_equal(['x', 'x', 'x'], z)
2870e8211a33SBram Moolenaar      enddef
2871e8211a33SBram Moolenaar      Func()
2872e8211a33SBram Moolenaar  END
2873e8211a33SBram Moolenaar  CheckScriptSuccess(lines)
2874e8211a33SBram Moolenaarenddef
2875e8211a33SBram Moolenaar
2876eeece9e4SBram Moolenaardef Test_reset_did_emsg()
2877eeece9e4SBram Moolenaar  var lines =<< trim END
2878eeece9e4SBram Moolenaar      @s = 'blah'
2879eeece9e4SBram Moolenaar      au BufWinLeave * #
2880eeece9e4SBram Moolenaar      def Func()
2881eeece9e4SBram Moolenaar        var winid = popup_create('popup', {})
2882eeece9e4SBram Moolenaar        exe '*s'
2883eeece9e4SBram Moolenaar        popup_close(winid)
2884eeece9e4SBram Moolenaar      enddef
2885eeece9e4SBram Moolenaar      Func()
2886eeece9e4SBram Moolenaar  END
2887eeece9e4SBram Moolenaar  CheckScriptFailure(lines, 'E492:', 8)
28882d870f8dSBram Moolenaar  delfunc! g:Func
2889eeece9e4SBram Moolenaarenddef
2890eeece9e4SBram Moolenaar
289157f799e6SBram Moolenaardef Test_did_emsg_reset()
289257f799e6SBram Moolenaar  # executing an autocommand resets did_emsg, this should not result in a
289357f799e6SBram Moolenaar  # builtin function considered failing
289457f799e6SBram Moolenaar  var lines =<< trim END
289557f799e6SBram Moolenaar      vim9script
289657f799e6SBram Moolenaar      au BufWinLeave * #
289757f799e6SBram Moolenaar      def Func()
2898767034c5SBram Moolenaar          popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
289957f799e6SBram Moolenaar          eval [][0]
290057f799e6SBram Moolenaar      enddef
290157f799e6SBram Moolenaar      nno <F3> <cmd>call <sid>Func()<cr>
290257f799e6SBram Moolenaar      feedkeys("\<F3>\e", 'xt')
290357f799e6SBram Moolenaar  END
290457f799e6SBram Moolenaar  writefile(lines, 'XemsgReset')
290557f799e6SBram Moolenaar  assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
290657f799e6SBram Moolenaar  delete('XemsgReset')
290757f799e6SBram Moolenaar  nunmap <F3>
290857f799e6SBram Moolenaar  au! BufWinLeave
290957f799e6SBram Moolenaarenddef
291057f799e6SBram Moolenaar
291156602ba1SBram Moolenaardef Test_abort_with_silent_call()
291256602ba1SBram Moolenaar  var lines =<< trim END
291356602ba1SBram Moolenaar      vim9script
291456602ba1SBram Moolenaar      g:result = 'none'
291556602ba1SBram Moolenaar      def Func()
291656602ba1SBram Moolenaar        g:result += 3
291756602ba1SBram Moolenaar        g:result = 'yes'
291856602ba1SBram Moolenaar      enddef
291956602ba1SBram Moolenaar      # error is silenced, but function aborts on error
292056602ba1SBram Moolenaar      silent! Func()
292156602ba1SBram Moolenaar      assert_equal('none', g:result)
292256602ba1SBram Moolenaar      unlet g:result
292356602ba1SBram Moolenaar  END
292456602ba1SBram Moolenaar  CheckScriptSuccess(lines)
292556602ba1SBram Moolenaarenddef
292656602ba1SBram Moolenaar
2927f665e97fSBram Moolenaardef Test_continues_with_silent_error()
2928f665e97fSBram Moolenaar  var lines =<< trim END
2929f665e97fSBram Moolenaar      vim9script
2930f665e97fSBram Moolenaar      g:result = 'none'
2931f665e97fSBram Moolenaar      def Func()
2932f665e97fSBram Moolenaar        silent!  g:result += 3
2933f665e97fSBram Moolenaar        g:result = 'yes'
2934f665e97fSBram Moolenaar      enddef
2935f665e97fSBram Moolenaar      # error is silenced, function does not abort
2936f665e97fSBram Moolenaar      Func()
2937f665e97fSBram Moolenaar      assert_equal('yes', g:result)
2938f665e97fSBram Moolenaar      unlet g:result
2939f665e97fSBram Moolenaar  END
2940f665e97fSBram Moolenaar  CheckScriptSuccess(lines)
2941f665e97fSBram Moolenaarenddef
2942f665e97fSBram Moolenaar
2943af0df47aSBram Moolenaardef Test_abort_even_with_silent()
2944af0df47aSBram Moolenaar  var lines =<< trim END
2945af0df47aSBram Moolenaar      vim9script
2946af0df47aSBram Moolenaar      g:result = 'none'
2947af0df47aSBram Moolenaar      def Func()
2948af0df47aSBram Moolenaar        eval {-> ''}() .. '' .. {}['X']
2949af0df47aSBram Moolenaar        g:result = 'yes'
2950af0df47aSBram Moolenaar      enddef
2951f665e97fSBram Moolenaar      silent! Func()
2952af0df47aSBram Moolenaar      assert_equal('none', g:result)
29534029cabbSBram Moolenaar      unlet g:result
29544029cabbSBram Moolenaar  END
29554029cabbSBram Moolenaar  CheckScriptSuccess(lines)
29564029cabbSBram Moolenaarenddef
29574029cabbSBram Moolenaar
2958f665e97fSBram Moolenaardef Test_cmdmod_silent_restored()
2959f665e97fSBram Moolenaar  var lines =<< trim END
2960f665e97fSBram Moolenaar      vim9script
2961f665e97fSBram Moolenaar      def Func()
2962f665e97fSBram Moolenaar        g:result = 'none'
2963f665e97fSBram Moolenaar        silent! g:result += 3
2964f665e97fSBram Moolenaar        g:result = 'none'
2965f665e97fSBram Moolenaar        g:result += 3
2966f665e97fSBram Moolenaar      enddef
2967f665e97fSBram Moolenaar      Func()
2968f665e97fSBram Moolenaar  END
2969f665e97fSBram Moolenaar  # can't use CheckScriptFailure, it ignores the :silent!
2970f665e97fSBram Moolenaar  var fname = 'Xdefsilent'
2971f665e97fSBram Moolenaar  writefile(lines, fname)
2972f665e97fSBram Moolenaar  var caught = 'no'
2973f665e97fSBram Moolenaar  try
2974f665e97fSBram Moolenaar    exe 'source ' .. fname
2975f665e97fSBram Moolenaar  catch /E1030:/
2976f665e97fSBram Moolenaar    caught = 'yes'
2977f665e97fSBram Moolenaar    assert_match('Func, line 4', v:throwpoint)
2978f665e97fSBram Moolenaar  endtry
2979f665e97fSBram Moolenaar  assert_equal('yes', caught)
2980f665e97fSBram Moolenaar  delete(fname)
2981f665e97fSBram Moolenaarenddef
2982f665e97fSBram Moolenaar
29832fecb531SBram Moolenaardef Test_cmdmod_silent_nested()
29842fecb531SBram Moolenaar  var lines =<< trim END
29852fecb531SBram Moolenaar      vim9script
29862fecb531SBram Moolenaar      var result = ''
29872fecb531SBram Moolenaar
29882fecb531SBram Moolenaar      def Error()
29892fecb531SBram Moolenaar          result ..= 'Eb'
29902fecb531SBram Moolenaar          eval [][0]
29912fecb531SBram Moolenaar          result ..= 'Ea'
29922fecb531SBram Moolenaar      enddef
29932fecb531SBram Moolenaar
29942fecb531SBram Moolenaar      def Crash()
29952fecb531SBram Moolenaar          result ..= 'Cb'
29962fecb531SBram Moolenaar          sil! Error()
29972fecb531SBram Moolenaar          result ..= 'Ca'
29982fecb531SBram Moolenaar      enddef
29992fecb531SBram Moolenaar
30002fecb531SBram Moolenaar      Crash()
30012fecb531SBram Moolenaar      assert_equal('CbEbEaCa', result)
30022fecb531SBram Moolenaar  END
30032fecb531SBram Moolenaar  CheckScriptSuccess(lines)
30042fecb531SBram Moolenaarenddef
30052fecb531SBram Moolenaar
30064029cabbSBram Moolenaardef Test_dict_member_with_silent()
30074029cabbSBram Moolenaar  var lines =<< trim END
30084029cabbSBram Moolenaar      vim9script
30094029cabbSBram Moolenaar      g:result = 'none'
30104029cabbSBram Moolenaar      var d: dict<any>
30114029cabbSBram Moolenaar      def Func()
30124029cabbSBram Moolenaar        try
30132949cfdbSBram Moolenaar          g:result = map([], (_, v) => ({}[v]))->join() .. d['']
30144029cabbSBram Moolenaar        catch
30154029cabbSBram Moolenaar        endtry
30164029cabbSBram Moolenaar      enddef
30174029cabbSBram Moolenaar      silent! Func()
30184029cabbSBram Moolenaar      assert_equal('0', g:result)
30194029cabbSBram Moolenaar      unlet g:result
3020af0df47aSBram Moolenaar  END
3021af0df47aSBram Moolenaar  CheckScriptSuccess(lines)
3022af0df47aSBram Moolenaarenddef
3023af0df47aSBram Moolenaar
3024f904133eSBram Moolenaardef Test_skip_cmds_with_silent()
3025f904133eSBram Moolenaar  var lines =<< trim END
3026f904133eSBram Moolenaar      vim9script
3027f904133eSBram Moolenaar
3028f904133eSBram Moolenaar      def Func(b: bool)
3029f904133eSBram Moolenaar        Crash()
3030f904133eSBram Moolenaar      enddef
3031f904133eSBram Moolenaar
3032f904133eSBram Moolenaar      def Crash()
3033f904133eSBram Moolenaar        sil! :/not found/d _
3034f904133eSBram Moolenaar        sil! :/not found/put _
3035f904133eSBram Moolenaar      enddef
3036f904133eSBram Moolenaar
3037f904133eSBram Moolenaar      Func(true)
3038f904133eSBram Moolenaar  END
3039f904133eSBram Moolenaar  CheckScriptSuccess(lines)
3040f904133eSBram Moolenaarenddef
3041f904133eSBram Moolenaar
30425b3d1bb0SBram Moolenaardef Test_opfunc()
30435b3d1bb0SBram Moolenaar  nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
30445b3d1bb0SBram Moolenaar  def g:Opfunc(_: any): string
30455b3d1bb0SBram Moolenaar    setline(1, 'ASDF')
30465b3d1bb0SBram Moolenaar    return ''
30475b3d1bb0SBram Moolenaar  enddef
30485b3d1bb0SBram Moolenaar  new
30495b3d1bb0SBram Moolenaar  setline(1, 'asdf')
30505b3d1bb0SBram Moolenaar  feedkeys("\<F3>$", 'x')
30515b3d1bb0SBram Moolenaar  assert_equal('ASDF', getline(1))
30525b3d1bb0SBram Moolenaar
30535b3d1bb0SBram Moolenaar  bwipe!
30545b3d1bb0SBram Moolenaar  nunmap <F3>
30555b3d1bb0SBram Moolenaarenddef
30565b3d1bb0SBram Moolenaar
3057077a4231SBram Moolenaar" this was crashing on exit
3058077a4231SBram Moolenaardef Test_nested_lambda_in_closure()
3059077a4231SBram Moolenaar  var lines =<< trim END
3060077a4231SBram Moolenaar      vim9script
3061227c58a4SBram Moolenaar      command WriteDone writefile(['Done'], 'XnestedDone')
3062077a4231SBram Moolenaar      def Outer()
3063077a4231SBram Moolenaar          def g:Inner()
3064077a4231SBram Moolenaar              echo map([1, 2, 3], {_, v -> v + 1})
3065077a4231SBram Moolenaar          enddef
3066077a4231SBram Moolenaar          g:Inner()
3067077a4231SBram Moolenaar      enddef
3068077a4231SBram Moolenaar      defcompile
3069227c58a4SBram Moolenaar      # not reached
3070077a4231SBram Moolenaar  END
3071227c58a4SBram Moolenaar  if !RunVim([], lines, '--clean -c WriteDone -c quit')
3072077a4231SBram Moolenaar    return
3073077a4231SBram Moolenaar  endif
3074077a4231SBram Moolenaar  assert_equal(['Done'], readfile('XnestedDone'))
3075077a4231SBram Moolenaar  delete('XnestedDone')
3076077a4231SBram Moolenaarenddef
3077077a4231SBram Moolenaar
307804947cc6SBram Moolenaardef Test_check_func_arg_types()
307904947cc6SBram Moolenaar  var lines =<< trim END
308004947cc6SBram Moolenaar      vim9script
308104947cc6SBram Moolenaar      def F1(x: string): string
308204947cc6SBram Moolenaar        return x
308304947cc6SBram Moolenaar      enddef
308404947cc6SBram Moolenaar
308504947cc6SBram Moolenaar      def F2(x: number): number
308604947cc6SBram Moolenaar        return x + 1
308704947cc6SBram Moolenaar      enddef
308804947cc6SBram Moolenaar
308904947cc6SBram Moolenaar      def G(g: func): dict<func>
309004947cc6SBram Moolenaar        return {f: g}
309104947cc6SBram Moolenaar      enddef
309204947cc6SBram Moolenaar
309304947cc6SBram Moolenaar      def H(d: dict<func>): string
309404947cc6SBram Moolenaar        return d.f('a')
309504947cc6SBram Moolenaar      enddef
309604947cc6SBram Moolenaar  END
309704947cc6SBram Moolenaar
309804947cc6SBram Moolenaar  CheckScriptSuccess(lines + ['echo H(G(F1))'])
309904947cc6SBram Moolenaar  CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
310004947cc6SBram Moolenaarenddef
310104947cc6SBram Moolenaar
31026e48b84cSBram Moolenaardef Test_list_any_type_checked()
31036e48b84cSBram Moolenaar  var lines =<< trim END
31046e48b84cSBram Moolenaar      vim9script
31056e48b84cSBram Moolenaar      def Foo()
31066e48b84cSBram Moolenaar        --decl--
31076e48b84cSBram Moolenaar        Bar(l)
31086e48b84cSBram Moolenaar      enddef
31096e48b84cSBram Moolenaar      def Bar(ll: list<dict<any>>)
31106e48b84cSBram Moolenaar      enddef
31116e48b84cSBram Moolenaar      Foo()
31126e48b84cSBram Moolenaar  END
31136e48b84cSBram Moolenaar  lines[2] = 'var l: list<any>'
31146e48b84cSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2)
31156e48b84cSBram Moolenaar
31166e48b84cSBram Moolenaar  lines[2] = 'var l: list<any> = []'
31176e48b84cSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2)
31186e48b84cSBram Moolenaar
31196e48b84cSBram Moolenaar  lines[2] = 'var l: list<any> = [11]'
31206e48b84cSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
31216e48b84cSBram Moolenaarenddef
31226e48b84cSBram Moolenaar
3123701cc6caSBram Moolenaardef Test_compile_error()
3124701cc6caSBram Moolenaar  var lines =<< trim END
3125701cc6caSBram Moolenaar    def g:Broken()
3126701cc6caSBram Moolenaar      echo 'a' + {}
3127701cc6caSBram Moolenaar    enddef
3128701cc6caSBram Moolenaar    call g:Broken()
3129701cc6caSBram Moolenaar  END
3130701cc6caSBram Moolenaar  # First call: compilation error
3131701cc6caSBram Moolenaar  CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
3132701cc6caSBram Moolenaar
3133701cc6caSBram Moolenaar  # Second call won't try compiling again
3134701cc6caSBram Moolenaar  assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
3135599410cbSBram Moolenaar  delfunc g:Broken
3136599410cbSBram Moolenaar
3137599410cbSBram Moolenaar  # No error when compiling with :silent!
3138599410cbSBram Moolenaar  lines =<< trim END
3139599410cbSBram Moolenaar    def g:Broken()
3140599410cbSBram Moolenaar      echo 'a' + []
3141599410cbSBram Moolenaar    enddef
3142599410cbSBram Moolenaar    silent! defcompile
3143599410cbSBram Moolenaar  END
3144599410cbSBram Moolenaar  CheckScriptSuccess(lines)
3145599410cbSBram Moolenaar
3146599410cbSBram Moolenaar  # Calling the function won't try compiling again
3147599410cbSBram Moolenaar  assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
3148599410cbSBram Moolenaar  delfunc g:Broken
3149701cc6caSBram Moolenaarenddef
3150701cc6caSBram Moolenaar
3151962c43bfSBram Moolenaardef Test_ignored_argument()
3152962c43bfSBram Moolenaar  var lines =<< trim END
3153962c43bfSBram Moolenaar      vim9script
3154962c43bfSBram Moolenaar      def Ignore(_, _): string
3155962c43bfSBram Moolenaar        return 'yes'
3156962c43bfSBram Moolenaar      enddef
3157962c43bfSBram Moolenaar      assert_equal('yes', Ignore(1, 2))
3158962c43bfSBram Moolenaar
3159962c43bfSBram Moolenaar      func Ok(_)
3160962c43bfSBram Moolenaar        return a:_
3161962c43bfSBram Moolenaar      endfunc
3162962c43bfSBram Moolenaar      assert_equal('ok', Ok('ok'))
3163962c43bfSBram Moolenaar
3164962c43bfSBram Moolenaar      func Oktoo()
3165962c43bfSBram Moolenaar        let _ = 'too'
3166962c43bfSBram Moolenaar        return _
3167962c43bfSBram Moolenaar      endfunc
3168962c43bfSBram Moolenaar      assert_equal('too', Oktoo())
3169da479c75SBram Moolenaar
3170da479c75SBram Moolenaar      assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
3171962c43bfSBram Moolenaar  END
3172962c43bfSBram Moolenaar  CheckScriptSuccess(lines)
3173962c43bfSBram Moolenaar
3174962c43bfSBram Moolenaar  lines =<< trim END
3175962c43bfSBram Moolenaar      def Ignore(_: string): string
3176962c43bfSBram Moolenaar        return _
3177962c43bfSBram Moolenaar      enddef
3178962c43bfSBram Moolenaar      defcompile
3179962c43bfSBram Moolenaar  END
3180962c43bfSBram Moolenaar  CheckScriptFailure(lines, 'E1181:', 1)
3181962c43bfSBram Moolenaar
3182962c43bfSBram Moolenaar  lines =<< trim END
3183962c43bfSBram Moolenaar      var _ = 1
3184962c43bfSBram Moolenaar  END
3185962c43bfSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1181:', 1)
318634fcb697SYegappan Lakshmanan
318734fcb697SYegappan Lakshmanan  lines =<< trim END
318834fcb697SYegappan Lakshmanan      var x = _
318934fcb697SYegappan Lakshmanan  END
319034fcb697SYegappan Lakshmanan  CheckDefAndScriptFailure(lines, 'E1181:', 1)
3191962c43bfSBram Moolenaarenddef
3192962c43bfSBram Moolenaar
3193bb8a7ce0SBram Moolenaardef Test_too_many_arguments()
3194bb8a7ce0SBram Moolenaar  var lines =<< trim END
3195bb8a7ce0SBram Moolenaar    echo [0, 1, 2]->map(() => 123)
3196bb8a7ce0SBram Moolenaar  END
3197bb8a7ce0SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1106: 2 arguments too many', 1)
3198bb8a7ce0SBram Moolenaar
3199bb8a7ce0SBram Moolenaar  lines =<< trim END
3200bb8a7ce0SBram Moolenaar    echo [0, 1, 2]->map((_) => 123)
3201bb8a7ce0SBram Moolenaar  END
3202bb8a7ce0SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1106: One argument too many', 1)
3203bb8a7ce0SBram Moolenaarenddef
3204077a4231SBram Moolenaar
3205a6aa1642SBram Moolenaardef Test_closing_brace_at_start_of_line()
3206a6aa1642SBram Moolenaar  var lines =<< trim END
3207a6aa1642SBram Moolenaar      def Func()
3208a6aa1642SBram Moolenaar      enddef
3209a6aa1642SBram Moolenaar      Func(
3210a6aa1642SBram Moolenaar      )
3211a6aa1642SBram Moolenaar  END
3212a6aa1642SBram Moolenaar  call CheckDefAndScriptSuccess(lines)
3213a6aa1642SBram Moolenaarenddef
3214a6aa1642SBram Moolenaar
3215b033ee2dSBram Moolenaarfunc CreateMydict()
3216b033ee2dSBram Moolenaar  let g:mydict = {}
3217b033ee2dSBram Moolenaar  func g:mydict.afunc()
3218b033ee2dSBram Moolenaar    let g:result = self.key
3219b033ee2dSBram Moolenaar  endfunc
3220b033ee2dSBram Moolenaarendfunc
3221b033ee2dSBram Moolenaar
3222b033ee2dSBram Moolenaardef Test_numbered_function_reference()
3223b033ee2dSBram Moolenaar  CreateMydict()
3224b033ee2dSBram Moolenaar  var output = execute('legacy func g:mydict.afunc')
3225b033ee2dSBram Moolenaar  var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
3226b033ee2dSBram Moolenaar  execute 'function(' .. funcName .. ', [], {key: 42})()'
3227b033ee2dSBram Moolenaar  # check that the function still exists
3228b033ee2dSBram Moolenaar  assert_equal(output, execute('legacy func g:mydict.afunc'))
3229b033ee2dSBram Moolenaar  unlet g:mydict
3230b033ee2dSBram Moolenaarenddef
3231b033ee2dSBram Moolenaar
32322067733bSBram Moolenaarif has('python3')
32332067733bSBram Moolenaar  def Test_python3_heredoc()
32342067733bSBram Moolenaar    py3 << trim EOF
32352067733bSBram Moolenaar      import vim
32362067733bSBram Moolenaar      vim.vars['didit'] = 'yes'
32372067733bSBram Moolenaar    EOF
32382067733bSBram Moolenaar    assert_equal('yes', g:didit)
32392067733bSBram Moolenaar
32402067733bSBram Moolenaar    python3 << trim EOF
32412067733bSBram Moolenaar      import vim
32422067733bSBram Moolenaar      vim.vars['didit'] = 'again'
32432067733bSBram Moolenaar    EOF
32442067733bSBram Moolenaar    assert_equal('again', g:didit)
32452067733bSBram Moolenaar  enddef
32462067733bSBram Moolenaarendif
32472067733bSBram Moolenaar
32482067733bSBram Moolenaar" This messes up syntax highlight, keep near the end.
32492067733bSBram Moolenaarif has('lua')
32502067733bSBram Moolenaar  def Test_lua_heredoc()
32512067733bSBram Moolenaar    g:d = {}
32522067733bSBram Moolenaar    lua << trim EOF
32532067733bSBram Moolenaar        x = vim.eval('g:d')
32542067733bSBram Moolenaar        x['key'] = 'val'
32552067733bSBram Moolenaar    EOF
32562067733bSBram Moolenaar    assert_equal('val', g:d.key)
32572067733bSBram Moolenaar  enddef
32582067733bSBram Moolenaarendif
32592067733bSBram Moolenaar
3260f7779c63SBram Moolenaar
32615deeb3f1SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
3262