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
4415deeb3f1SBram Moolenaarfunc Increment()
4425deeb3f1SBram Moolenaar  let g:counter += 1
4435deeb3f1SBram Moolenaarendfunc
4445deeb3f1SBram Moolenaar
4455deeb3f1SBram Moolenaardef Test_call_ufunc_count()
4465deeb3f1SBram Moolenaar  g:counter = 1
4475deeb3f1SBram Moolenaar  Increment()
4485deeb3f1SBram Moolenaar  Increment()
4495deeb3f1SBram Moolenaar  Increment()
450f5be8cdbSBram Moolenaar  # works with and without :call
451c0c71e9dSBram Moolenaar  g:counter->assert_equal(4)
452c0c71e9dSBram Moolenaar  eval g:counter->assert_equal(4)
4535deeb3f1SBram Moolenaar  unlet g:counter
4545deeb3f1SBram Moolenaarenddef
4555deeb3f1SBram Moolenaar
4565deeb3f1SBram Moolenaardef MyVarargs(arg: string, ...rest: list<string>): string
4577a9cbca0SBram Moolenaar  var res = arg
4585deeb3f1SBram Moolenaar  for s in rest
4595deeb3f1SBram Moolenaar    res ..= ',' .. s
4605deeb3f1SBram Moolenaar  endfor
4615deeb3f1SBram Moolenaar  return res
4625deeb3f1SBram Moolenaarenddef
4635deeb3f1SBram Moolenaar
4645deeb3f1SBram Moolenaardef Test_call_varargs()
465c0c71e9dSBram Moolenaar  MyVarargs('one')->assert_equal('one')
466c0c71e9dSBram Moolenaar  MyVarargs('one', 'two')->assert_equal('one,two')
467c0c71e9dSBram Moolenaar  MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
4685deeb3f1SBram Moolenaarenddef
4695deeb3f1SBram Moolenaar
4705deeb3f1SBram Moolenaardef MyDefaultArgs(name = 'string'): string
4715deeb3f1SBram Moolenaar  return name
4725deeb3f1SBram Moolenaarenddef
4735deeb3f1SBram Moolenaar
474e30f64b4SBram Moolenaardef MyDefaultSecond(name: string, second: bool  = true): string
475e30f64b4SBram Moolenaar  return second ? name : 'none'
476e30f64b4SBram Moolenaarenddef
477e30f64b4SBram Moolenaar
47838a3bfa9SBram Moolenaar
4795deeb3f1SBram Moolenaardef Test_call_default_args()
480c0c71e9dSBram Moolenaar  MyDefaultArgs()->assert_equal('string')
48138a3bfa9SBram Moolenaar  MyDefaultArgs(v:none)->assert_equal('string')
482c0c71e9dSBram Moolenaar  MyDefaultArgs('one')->assert_equal('one')
48338a3bfa9SBram Moolenaar  assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args')
4845deeb3f1SBram Moolenaar
485c0c71e9dSBram Moolenaar  MyDefaultSecond('test')->assert_equal('test')
486c0c71e9dSBram Moolenaar  MyDefaultSecond('test', true)->assert_equal('test')
487c0c71e9dSBram Moolenaar  MyDefaultSecond('test', false)->assert_equal('none')
488e30f64b4SBram Moolenaar
48938a3bfa9SBram Moolenaar  var lines =<< trim END
49038a3bfa9SBram Moolenaar      def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string
49138a3bfa9SBram Moolenaar        return name .. aa .. bb
49238a3bfa9SBram Moolenaar      enddef
49338a3bfa9SBram Moolenaar
49438a3bfa9SBram Moolenaar      MyDefaultThird('->')->assert_equal('->aabb')
49538a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none)->assert_equal('->aabb')
49638a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx')->assert_equal('->xxbb')
49738a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb')
49838a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
49938a3bfa9SBram Moolenaar      MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
50038a3bfa9SBram Moolenaar      MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
501e28d9b3bSBram Moolenaar
502e28d9b3bSBram Moolenaar      def DefArg(mandatory: any, optional = mandatory): string
503e28d9b3bSBram Moolenaar        return mandatory .. optional
504e28d9b3bSBram Moolenaar      enddef
505e28d9b3bSBram Moolenaar      DefArg(1234)->assert_equal('12341234')
506e28d9b3bSBram Moolenaar      DefArg("ok")->assert_equal('okok')
50738a3bfa9SBram Moolenaar  END
50838a3bfa9SBram Moolenaar  CheckDefAndScriptSuccess(lines)
50938a3bfa9SBram Moolenaar
510822ba247SBram Moolenaar  CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
5112d870f8dSBram Moolenaar  delfunc g:Func
5127707228aSBram Moolenaar  CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
5132d870f8dSBram Moolenaar  delfunc g:Func
51434fcb697SYegappan Lakshmanan  CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
51512bce958SBram Moolenaar
51638a3bfa9SBram Moolenaar  lines =<< trim END
51712bce958SBram Moolenaar      vim9script
51812bce958SBram Moolenaar      def Func(a = b == 0 ? 1 : 2, b = 0)
51912bce958SBram Moolenaar      enddef
52012bce958SBram Moolenaar      defcompile
52112bce958SBram Moolenaar  END
52212bce958SBram Moolenaar  CheckScriptFailure(lines, 'E1001: Variable not found: b')
52304b12697SBram Moolenaarenddef
52404b12697SBram Moolenaar
525cef1270dSBram Moolenaardef FuncWithComment(  # comment
526cef1270dSBram Moolenaar  a: number, #comment
527cef1270dSBram Moolenaar  b: bool, # comment
528cef1270dSBram Moolenaar  c: string) #comment
529cef1270dSBram Moolenaar  assert_equal(4, a)
530cef1270dSBram Moolenaar  assert_equal(true, b)
531cef1270dSBram Moolenaar  assert_equal('yes', c)
532cef1270dSBram Moolenaarenddef
533cef1270dSBram Moolenaar
534cef1270dSBram Moolenaardef Test_func_with_comments()
535cef1270dSBram Moolenaar  FuncWithComment(4, true, 'yes')
536cef1270dSBram Moolenaar
537cef1270dSBram Moolenaar  var lines =<< trim END
538cef1270dSBram Moolenaar      def Func(# comment
539cef1270dSBram Moolenaar        arg: string)
540cef1270dSBram Moolenaar      enddef
541cef1270dSBram Moolenaar  END
542cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E125:', 1)
543cef1270dSBram Moolenaar
544cef1270dSBram Moolenaar  lines =<< trim END
545cef1270dSBram Moolenaar      def Func(
546cef1270dSBram Moolenaar        arg: string# comment
547cef1270dSBram Moolenaar        )
548cef1270dSBram Moolenaar      enddef
549cef1270dSBram Moolenaar  END
550cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E475:', 2)
551cef1270dSBram Moolenaar
552cef1270dSBram Moolenaar  lines =<< trim END
553cef1270dSBram Moolenaar      def Func(
554cef1270dSBram Moolenaar        arg: string
555cef1270dSBram Moolenaar        )# comment
556cef1270dSBram Moolenaar      enddef
557cef1270dSBram Moolenaar  END
558cef1270dSBram Moolenaar  CheckScriptFailure(lines, 'E488:', 3)
559cef1270dSBram Moolenaarenddef
560cef1270dSBram Moolenaar
56104b12697SBram Moolenaardef Test_nested_function()
56204b12697SBram Moolenaar  def Nested(arg: string): string
56304b12697SBram Moolenaar    return 'nested ' .. arg
56404b12697SBram Moolenaar  enddef
565c0c71e9dSBram Moolenaar  Nested('function')->assert_equal('nested function')
56604b12697SBram Moolenaar
5670e65d3deSBram Moolenaar  CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
5680e65d3deSBram Moolenaar  CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
5690e65d3deSBram Moolenaar
57004b12697SBram Moolenaar  CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
571bcbf4139SBram Moolenaar  CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
572bcbf4139SBram Moolenaar  CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
5738b848cafSBram Moolenaar
57454021758SBram Moolenaar  var lines =<< trim END
57554021758SBram Moolenaar      def Outer()
57654021758SBram Moolenaar        def Inner()
57754021758SBram Moolenaar          # comment
57854021758SBram Moolenaar        enddef
57954021758SBram Moolenaar        def Inner()
58054021758SBram Moolenaar        enddef
58154021758SBram Moolenaar      enddef
58254021758SBram Moolenaar  END
58354021758SBram Moolenaar  CheckDefFailure(lines, 'E1073:')
58454021758SBram Moolenaar
58554021758SBram Moolenaar  lines =<< trim END
58654021758SBram Moolenaar      def Outer()
58754021758SBram Moolenaar        def Inner()
58854021758SBram Moolenaar          # comment
58954021758SBram Moolenaar        enddef
59054021758SBram Moolenaar        def! Inner()
59154021758SBram Moolenaar        enddef
59254021758SBram Moolenaar      enddef
59354021758SBram Moolenaar  END
59454021758SBram Moolenaar  CheckDefFailure(lines, 'E1117:')
59554021758SBram Moolenaar
59654021758SBram Moolenaar  # nested function inside conditional
59754021758SBram Moolenaar  lines =<< trim END
59854021758SBram Moolenaar      vim9script
59954021758SBram Moolenaar      var thecount = 0
60054021758SBram Moolenaar      if true
60154021758SBram Moolenaar        def Test(): number
60254021758SBram Moolenaar          def TheFunc(): number
60354021758SBram Moolenaar            thecount += 1
60454021758SBram Moolenaar            return thecount
60554021758SBram Moolenaar          enddef
60654021758SBram Moolenaar          return TheFunc()
60754021758SBram Moolenaar        enddef
60854021758SBram Moolenaar      endif
60954021758SBram Moolenaar      defcompile
61054021758SBram Moolenaar      assert_equal(1, Test())
61154021758SBram Moolenaar      assert_equal(2, Test())
61254021758SBram Moolenaar  END
61354021758SBram Moolenaar  CheckScriptSuccess(lines)
6148863bda2SBram Moolenaar
6158863bda2SBram Moolenaar  # also works when "thecount" is inside the "if" block
6168863bda2SBram Moolenaar  lines =<< trim END
6178863bda2SBram Moolenaar      vim9script
6188863bda2SBram Moolenaar      if true
6198863bda2SBram Moolenaar        var thecount = 0
6208863bda2SBram Moolenaar        def Test(): number
6218863bda2SBram Moolenaar          def TheFunc(): number
6228863bda2SBram Moolenaar            thecount += 1
6238863bda2SBram Moolenaar            return thecount
6248863bda2SBram Moolenaar          enddef
6258863bda2SBram Moolenaar          return TheFunc()
6268863bda2SBram Moolenaar        enddef
6278863bda2SBram Moolenaar      endif
6288863bda2SBram Moolenaar      defcompile
6298863bda2SBram Moolenaar      assert_equal(1, Test())
6308863bda2SBram Moolenaar      assert_equal(2, Test())
6318863bda2SBram Moolenaar  END
6328863bda2SBram Moolenaar  CheckScriptSuccess(lines)
6335deeb3f1SBram Moolenaarenddef
6345deeb3f1SBram Moolenaar
635adc8e446SBram Moolenaardef Test_not_nested_function()
636adc8e446SBram Moolenaar  echo printf('%d',
637adc8e446SBram Moolenaar      function('len')('xxx'))
638adc8e446SBram Moolenaarenddef
639adc8e446SBram Moolenaar
640af8edbb8SBram Moolenaarfunc Test_call_default_args_from_func()
641c0c71e9dSBram Moolenaar  call MyDefaultArgs()->assert_equal('string')
642c0c71e9dSBram Moolenaar  call MyDefaultArgs('one')->assert_equal('one')
6439bd5d879SBram Moolenaar  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
644af8edbb8SBram Moolenaarendfunc
645af8edbb8SBram Moolenaar
64638ddf333SBram Moolenaardef Test_nested_global_function()
6477a9cbca0SBram Moolenaar  var lines =<< trim END
64838ddf333SBram Moolenaar      vim9script
64938ddf333SBram Moolenaar      def Outer()
65038ddf333SBram Moolenaar          def g:Inner(): string
65138ddf333SBram Moolenaar              return 'inner'
65238ddf333SBram Moolenaar          enddef
65338ddf333SBram Moolenaar      enddef
654af8edbb8SBram Moolenaar      defcompile
655af8edbb8SBram Moolenaar      Outer()
656c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
657af8edbb8SBram Moolenaar      delfunc g:Inner
658af8edbb8SBram Moolenaar      Outer()
659c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
660af8edbb8SBram Moolenaar      delfunc g:Inner
661af8edbb8SBram Moolenaar      Outer()
662c0c71e9dSBram Moolenaar      g:Inner()->assert_equal('inner')
663af8edbb8SBram Moolenaar      delfunc g:Inner
66438ddf333SBram Moolenaar  END
66538ddf333SBram Moolenaar  CheckScriptSuccess(lines)
6662c79e9d1SBram Moolenaar
6672c79e9d1SBram Moolenaar  lines =<< trim END
6682c79e9d1SBram Moolenaar      vim9script
6692c79e9d1SBram Moolenaar      def Outer()
6702c79e9d1SBram Moolenaar          def g:Inner(): string
6712c79e9d1SBram Moolenaar              return 'inner'
6722c79e9d1SBram Moolenaar          enddef
6732c79e9d1SBram Moolenaar      enddef
6742c79e9d1SBram Moolenaar      defcompile
6752c79e9d1SBram Moolenaar      Outer()
6762c79e9d1SBram Moolenaar      Outer()
6772c79e9d1SBram Moolenaar  END
6782c79e9d1SBram Moolenaar  CheckScriptFailure(lines, "E122:")
679cd45ed03SBram Moolenaar  delfunc g:Inner
680ad486a0fSBram Moolenaar
681ad486a0fSBram Moolenaar  lines =<< trim END
682ad486a0fSBram Moolenaar      vim9script
68358a52f21SBram Moolenaar      def Outer()
68458a52f21SBram Moolenaar        def g:Inner()
6852949cfdbSBram Moolenaar          echo map([1, 2, 3], (_, v) => v + 1)
68658a52f21SBram Moolenaar        enddef
68758a52f21SBram Moolenaar        g:Inner()
68858a52f21SBram Moolenaar      enddef
68958a52f21SBram Moolenaar      Outer()
69058a52f21SBram Moolenaar  END
69158a52f21SBram Moolenaar  CheckScriptSuccess(lines)
69258a52f21SBram Moolenaar  delfunc g:Inner
69358a52f21SBram Moolenaar
69458a52f21SBram Moolenaar  lines =<< trim END
69558a52f21SBram Moolenaar      vim9script
696ad486a0fSBram Moolenaar      def Func()
697ad486a0fSBram Moolenaar        echo 'script'
698ad486a0fSBram Moolenaar      enddef
699ad486a0fSBram Moolenaar      def Outer()
700ad486a0fSBram Moolenaar        def Func()
701ad486a0fSBram Moolenaar          echo 'inner'
702ad486a0fSBram Moolenaar        enddef
703ad486a0fSBram Moolenaar      enddef
704ad486a0fSBram Moolenaar      defcompile
705ad486a0fSBram Moolenaar  END
706ad486a0fSBram Moolenaar  CheckScriptFailure(lines, "E1073:")
70738ddf333SBram Moolenaarenddef
70838ddf333SBram Moolenaar
7096abdcf82SBram Moolenaardef DefListAll()
7106abdcf82SBram Moolenaar  def
7116abdcf82SBram Moolenaarenddef
7126abdcf82SBram Moolenaar
7136abdcf82SBram Moolenaardef DefListOne()
7146abdcf82SBram Moolenaar  def DefListOne
7156abdcf82SBram Moolenaarenddef
7166abdcf82SBram Moolenaar
7176abdcf82SBram Moolenaardef DefListMatches()
7186abdcf82SBram Moolenaar  def /DefList
7196abdcf82SBram Moolenaarenddef
7206abdcf82SBram Moolenaar
7216abdcf82SBram Moolenaardef Test_nested_def_list()
7226abdcf82SBram Moolenaar  var funcs = split(execute('call DefListAll()'), "\n")
7236abdcf82SBram Moolenaar  assert_true(len(funcs) > 10)
7246abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListAll()') >= 0)
7256abdcf82SBram Moolenaar
7266abdcf82SBram Moolenaar  funcs = split(execute('call DefListOne()'), "\n")
7276abdcf82SBram Moolenaar  assert_equal(['   def DefListOne()', '1    def DefListOne', '   enddef'], funcs)
7286abdcf82SBram Moolenaar
7296abdcf82SBram Moolenaar  funcs = split(execute('call DefListMatches()'), "\n")
7306abdcf82SBram Moolenaar  assert_true(len(funcs) >= 3)
7316abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListAll()') >= 0)
7326abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListOne()') >= 0)
7336abdcf82SBram Moolenaar  assert_true(funcs->index('def DefListMatches()') >= 0)
73454021758SBram Moolenaar
73554021758SBram Moolenaar  var lines =<< trim END
73654021758SBram Moolenaar    vim9script
73754021758SBram Moolenaar    def Func()
73854021758SBram Moolenaar      def +Func+
73954021758SBram Moolenaar    enddef
74054021758SBram Moolenaar    defcompile
74154021758SBram Moolenaar  END
74254021758SBram Moolenaar  CheckScriptFailure(lines, 'E476:', 1)
7436abdcf82SBram Moolenaarenddef
7446abdcf82SBram Moolenaar
745333894b1SBram Moolenaardef Test_global_local_function()
7467a9cbca0SBram Moolenaar  var lines =<< trim END
747333894b1SBram Moolenaar      vim9script
748333894b1SBram Moolenaar      def g:Func(): string
749333894b1SBram Moolenaar          return 'global'
750333894b1SBram Moolenaar      enddef
751333894b1SBram Moolenaar      def Func(): string
752333894b1SBram Moolenaar          return 'local'
753333894b1SBram Moolenaar      enddef
754c0c71e9dSBram Moolenaar      g:Func()->assert_equal('global')
755c0c71e9dSBram Moolenaar      Func()->assert_equal('local')
7562d870f8dSBram Moolenaar      delfunc g:Func
757333894b1SBram Moolenaar  END
758333894b1SBram Moolenaar  CheckScriptSuccess(lines)
759035d6e91SBram Moolenaar
760035d6e91SBram Moolenaar  lines =<< trim END
761035d6e91SBram Moolenaar      vim9script
762035d6e91SBram Moolenaar      def g:Funcy()
763035d6e91SBram Moolenaar        echo 'funcy'
764035d6e91SBram Moolenaar      enddef
765035d6e91SBram Moolenaar      s:Funcy()
766035d6e91SBram Moolenaar  END
767035d6e91SBram Moolenaar  CheckScriptFailure(lines, 'E117:')
768333894b1SBram Moolenaarenddef
769333894b1SBram Moolenaar
7700f769815SBram Moolenaardef Test_local_function_shadows_global()
7717a9cbca0SBram Moolenaar  var lines =<< trim END
7720f769815SBram Moolenaar      vim9script
7730f769815SBram Moolenaar      def g:Gfunc(): string
7740f769815SBram Moolenaar        return 'global'
7750f769815SBram Moolenaar      enddef
7760f769815SBram Moolenaar      def AnotherFunc(): number
7777a9cbca0SBram Moolenaar        var Gfunc = function('len')
7780f769815SBram Moolenaar        return Gfunc('testing')
7790f769815SBram Moolenaar      enddef
7800f769815SBram Moolenaar      g:Gfunc()->assert_equal('global')
7810f769815SBram Moolenaar      AnotherFunc()->assert_equal(7)
7820f769815SBram Moolenaar      delfunc g:Gfunc
7830f769815SBram Moolenaar  END
7840f769815SBram Moolenaar  CheckScriptSuccess(lines)
7850f769815SBram Moolenaar
7860f769815SBram Moolenaar  lines =<< trim END
7870f769815SBram Moolenaar      vim9script
7880f769815SBram Moolenaar      def g:Func(): string
7890f769815SBram Moolenaar        return 'global'
7900f769815SBram Moolenaar      enddef
7910f769815SBram Moolenaar      def AnotherFunc()
7920f769815SBram Moolenaar        g:Func = function('len')
7930f769815SBram Moolenaar      enddef
7940f769815SBram Moolenaar      AnotherFunc()
7950f769815SBram Moolenaar  END
7960f769815SBram Moolenaar  CheckScriptFailure(lines, 'E705:')
7970f769815SBram Moolenaar  delfunc g:Func
7980865b15bSBram Moolenaar
7990865b15bSBram Moolenaar  # global function is found without g: prefix
8000865b15bSBram Moolenaar  lines =<< trim END
8010865b15bSBram Moolenaar      vim9script
8020865b15bSBram Moolenaar      def g:Func(): string
8030865b15bSBram Moolenaar        return 'global'
8040865b15bSBram Moolenaar      enddef
8050865b15bSBram Moolenaar      def AnotherFunc(): string
8060865b15bSBram Moolenaar        return Func()
8070865b15bSBram Moolenaar      enddef
8080865b15bSBram Moolenaar      assert_equal('global', AnotherFunc())
8090865b15bSBram Moolenaar    delfunc g:Func
8100865b15bSBram Moolenaar  END
8110865b15bSBram Moolenaar  CheckScriptSuccess(lines)
8120865b15bSBram Moolenaar
8130865b15bSBram Moolenaar  lines =<< trim END
8140865b15bSBram Moolenaar      vim9script
8150865b15bSBram Moolenaar      def g:Func(): string
8160865b15bSBram Moolenaar        return 'global'
8170865b15bSBram Moolenaar      enddef
8180865b15bSBram Moolenaar      assert_equal('global', Func())
8190865b15bSBram Moolenaar      delfunc g:Func
8200865b15bSBram Moolenaar  END
8210865b15bSBram Moolenaar  CheckScriptSuccess(lines)
8220f769815SBram Moolenaarenddef
8230f769815SBram Moolenaar
8245deeb3f1SBram Moolenaarfunc TakesOneArg(arg)
8255deeb3f1SBram Moolenaar  echo a:arg
8265deeb3f1SBram Moolenaarendfunc
8275deeb3f1SBram Moolenaar
8285deeb3f1SBram Moolenaardef Test_call_wrong_args()
829d2c61705SBram Moolenaar  CheckDefFailure(['TakesOneArg()'], 'E119:')
830d2c61705SBram Moolenaar  CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
831d2c61705SBram Moolenaar  CheckDefFailure(['bufnr(xxx)'], 'E1001:')
832d2c61705SBram Moolenaar  CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
833ee8580e5SBram Moolenaar
8347a9cbca0SBram Moolenaar  var lines =<< trim END
835ee8580e5SBram Moolenaar    vim9script
836ee8580e5SBram Moolenaar    def Func(s: string)
837ee8580e5SBram Moolenaar      echo s
838ee8580e5SBram Moolenaar    enddef
839ee8580e5SBram Moolenaar    Func([])
840ee8580e5SBram Moolenaar  END
8417707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
842b185a407SBram Moolenaar
843b185a407SBram Moolenaar  lines =<< trim END
844b185a407SBram Moolenaar    vim9script
845b4893b84SBram Moolenaar    var name = 'piet'
846b4893b84SBram Moolenaar    def FuncOne(name: string)
847b4893b84SBram Moolenaar      echo nr
848b4893b84SBram Moolenaar    enddef
849b4893b84SBram Moolenaar  END
850057e84afSBram Moolenaar  CheckScriptFailure(lines, 'E1168:')
851b4893b84SBram Moolenaar
852b4893b84SBram Moolenaar  lines =<< trim END
853b4893b84SBram Moolenaar    vim9script
854b185a407SBram Moolenaar    def FuncOne(nr: number)
855b185a407SBram Moolenaar      echo nr
856b185a407SBram Moolenaar    enddef
857b185a407SBram Moolenaar    def FuncTwo()
858b185a407SBram Moolenaar      FuncOne()
859b185a407SBram Moolenaar    enddef
860b185a407SBram Moolenaar    defcompile
861b185a407SBram Moolenaar  END
862b185a407SBram Moolenaar  writefile(lines, 'Xscript')
8637a9cbca0SBram Moolenaar  var didCatch = false
864b185a407SBram Moolenaar  try
865b185a407SBram Moolenaar    source Xscript
866b185a407SBram Moolenaar  catch
867b185a407SBram Moolenaar    assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
868b185a407SBram Moolenaar    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
869b185a407SBram Moolenaar    didCatch = true
870b185a407SBram Moolenaar  endtry
871b185a407SBram Moolenaar  assert_true(didCatch)
872b185a407SBram Moolenaar
873b185a407SBram Moolenaar  lines =<< trim END
874b185a407SBram Moolenaar    vim9script
875b185a407SBram Moolenaar    def FuncOne(nr: number)
876b185a407SBram Moolenaar      echo nr
877b185a407SBram Moolenaar    enddef
878b185a407SBram Moolenaar    def FuncTwo()
879b185a407SBram Moolenaar      FuncOne(1, 2)
880b185a407SBram Moolenaar    enddef
881b185a407SBram Moolenaar    defcompile
882b185a407SBram Moolenaar  END
883b185a407SBram Moolenaar  writefile(lines, 'Xscript')
884b185a407SBram Moolenaar  didCatch = false
885b185a407SBram Moolenaar  try
886b185a407SBram Moolenaar    source Xscript
887b185a407SBram Moolenaar  catch
888b185a407SBram Moolenaar    assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
889b185a407SBram Moolenaar    assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
890b185a407SBram Moolenaar    didCatch = true
891b185a407SBram Moolenaar  endtry
892b185a407SBram Moolenaar  assert_true(didCatch)
893b185a407SBram Moolenaar
894b185a407SBram Moolenaar  delete('Xscript')
8955deeb3f1SBram Moolenaarenddef
8965deeb3f1SBram Moolenaar
8975082471fSBram Moolenaardef Test_call_funcref_wrong_args()
8985082471fSBram Moolenaar  var head =<< trim END
8995082471fSBram Moolenaar      vim9script
9005082471fSBram Moolenaar      def Func3(a1: string, a2: number, a3: list<number>)
9015082471fSBram Moolenaar        echo a1 .. a2 .. a3[0]
9025082471fSBram Moolenaar      enddef
9035082471fSBram Moolenaar      def Testme()
9045082471fSBram Moolenaar        var funcMap: dict<func> = {func: Func3}
9055082471fSBram Moolenaar  END
9065082471fSBram Moolenaar  var tail =<< trim END
9075082471fSBram Moolenaar      enddef
9085082471fSBram Moolenaar      Testme()
9095082471fSBram Moolenaar  END
9105082471fSBram Moolenaar  CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail)
9115082471fSBram Moolenaar
9125082471fSBram Moolenaar  CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:')
9135082471fSBram Moolenaar  CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:')
91432b3f820SBram Moolenaar
91532b3f820SBram Moolenaar  var lines =<< trim END
91632b3f820SBram Moolenaar      vim9script
91732b3f820SBram Moolenaar      var Ref: func(number): any
91832b3f820SBram Moolenaar      Ref = (j) => !j
91932b3f820SBram Moolenaar      echo Ref(false)
92032b3f820SBram Moolenaar  END
92132b3f820SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
92232b3f820SBram Moolenaar
92332b3f820SBram Moolenaar  lines =<< trim END
92432b3f820SBram Moolenaar      vim9script
92532b3f820SBram Moolenaar      var Ref: func(number): any
92632b3f820SBram Moolenaar      Ref = (j) => !j
92732b3f820SBram Moolenaar      call Ref(false)
92832b3f820SBram Moolenaar  END
92932b3f820SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4)
9305082471fSBram Moolenaarenddef
9315082471fSBram Moolenaar
932b4d16cb1SBram Moolenaardef Test_call_lambda_args()
9332a38908bSBram Moolenaar  var lines =<< trim END
9342a38908bSBram Moolenaar    var Callback = (..._) => 'anything'
9352a38908bSBram Moolenaar    assert_equal('anything', Callback())
9362a38908bSBram Moolenaar    assert_equal('anything', Callback(1))
9372a38908bSBram Moolenaar    assert_equal('anything', Callback('a', 2))
9381088b694SBram Moolenaar
9391088b694SBram Moolenaar    assert_equal('xyz', ((a: string): string => a)('xyz'))
9402a38908bSBram Moolenaar  END
9412a38908bSBram Moolenaar  CheckDefAndScriptSuccess(lines)
9422a38908bSBram Moolenaar
9432949cfdbSBram Moolenaar  CheckDefFailure(['echo ((i) => 0)()'],
9442949cfdbSBram Moolenaar                  'E119: Not enough arguments for function: ((i) => 0)()')
945b4d16cb1SBram Moolenaar
9462a38908bSBram Moolenaar  lines =<< trim END
9472949cfdbSBram Moolenaar      var Ref = (x: number, y: number) => x + y
948b4d16cb1SBram Moolenaar      echo Ref(1, 'x')
949b4d16cb1SBram Moolenaar  END
950b4d16cb1SBram Moolenaar  CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string')
951e68b02a1SBram Moolenaar
952e68b02a1SBram Moolenaar  lines =<< trim END
953e68b02a1SBram Moolenaar    var Ref: func(job, string, number)
954e68b02a1SBram Moolenaar    Ref = (x, y) => 0
955e68b02a1SBram Moolenaar  END
956e68b02a1SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1012:')
957e68b02a1SBram Moolenaar
958e68b02a1SBram Moolenaar  lines =<< trim END
959e68b02a1SBram Moolenaar    var Ref: func(job, string)
960e68b02a1SBram Moolenaar    Ref = (x, y, z) => 0
961e68b02a1SBram Moolenaar  END
962e68b02a1SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1012:')
963057e84afSBram Moolenaar
964057e84afSBram Moolenaar  lines =<< trim END
965057e84afSBram Moolenaar      var one = 1
966057e84afSBram Moolenaar      var l = [1, 2, 3]
967057e84afSBram Moolenaar      echo map(l, (one) => one)
968057e84afSBram Moolenaar  END
969057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
970057e84afSBram Moolenaar  CheckScriptFailure(['vim9script'] + lines, 'E1168:')
971057e84afSBram Moolenaar
972057e84afSBram Moolenaar  lines =<< trim END
97314ded11fSBram Moolenaar    var Ref: func(any, ?any): bool
97414ded11fSBram Moolenaar    Ref = (_, y = 1) => false
97514ded11fSBram Moolenaar  END
97614ded11fSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1172:')
97714ded11fSBram Moolenaar
97814ded11fSBram Moolenaar  lines =<< trim END
979015cf103SBram Moolenaar      var a = 0
980015cf103SBram Moolenaar      var b = (a == 0 ? 1 : 2)
981015cf103SBram Moolenaar      assert_equal(1, b)
98298f9a5f4SBram Moolenaar      var txt = 'a'
98398f9a5f4SBram Moolenaar      b = (txt =~ 'x' ? 1 : 2)
98498f9a5f4SBram Moolenaar      assert_equal(2, b)
985015cf103SBram Moolenaar  END
986015cf103SBram Moolenaar  CheckDefAndScriptSuccess(lines)
987015cf103SBram Moolenaar
988015cf103SBram Moolenaar  lines =<< trim END
989057e84afSBram Moolenaar      def ShadowLocal()
990057e84afSBram Moolenaar        var one = 1
991057e84afSBram Moolenaar        var l = [1, 2, 3]
992057e84afSBram Moolenaar        echo map(l, (one) => one)
993057e84afSBram Moolenaar      enddef
994057e84afSBram Moolenaar  END
995057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
996057e84afSBram Moolenaar
997057e84afSBram Moolenaar  lines =<< trim END
998057e84afSBram Moolenaar      def Shadowarg(one: number)
999057e84afSBram Moolenaar        var l = [1, 2, 3]
1000057e84afSBram Moolenaar        echo map(l, (one) => one)
1001057e84afSBram Moolenaar      enddef
1002057e84afSBram Moolenaar  END
1003057e84afSBram Moolenaar  CheckDefFailure(lines, 'E1167:')
1004767034c5SBram Moolenaar
1005767034c5SBram Moolenaar  lines =<< trim END
1006767034c5SBram Moolenaar    echo ((a) => a)('aa', 'bb')
1007767034c5SBram Moolenaar  END
1008767034c5SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E118:', 1)
1009c4c56425SBram Moolenaar
1010c4c56425SBram Moolenaar  lines =<< trim END
1011c4c56425SBram Moolenaar    echo 'aa'->((a) => a)('bb')
1012c4c56425SBram Moolenaar  END
1013c4c56425SBram Moolenaar  CheckDefFailure(lines, 'E118: Too many arguments for function: ->((a) => a)(''bb'')', 1)
1014c4c56425SBram Moolenaar  CheckScriptFailure(['vim9script'] + lines, 'E118: Too many arguments for function: <lambda>', 2)
1015b4d16cb1SBram Moolenaarenddef
1016b4d16cb1SBram Moolenaar
10175f91e74bSBram Moolenaardef FilterWithCond(x: string, Cond: func(string): bool): bool
10185f91e74bSBram Moolenaar  return Cond(x)
10195f91e74bSBram Moolenaarenddef
10205f91e74bSBram Moolenaar
10210346b799SBram Moolenaardef Test_lambda_return_type()
10220346b799SBram Moolenaar  var lines =<< trim END
10230346b799SBram Moolenaar    var Ref = (): => 123
10240346b799SBram Moolenaar  END
10250346b799SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1157:', 1)
10265f91e74bSBram Moolenaar
1027611728f8SYegappan Lakshmanan  # no space before the return type
1028611728f8SYegappan Lakshmanan  lines =<< trim END
1029611728f8SYegappan Lakshmanan    var Ref = (x):number => x + 1
1030611728f8SYegappan Lakshmanan  END
1031611728f8SYegappan Lakshmanan  CheckDefAndScriptFailure(lines, 'E1069:', 1)
1032611728f8SYegappan Lakshmanan
10335f91e74bSBram Moolenaar  # this works
10345f91e74bSBram Moolenaar  for x in ['foo', 'boo']
10355f91e74bSBram Moolenaar    echo FilterWithCond(x, (v) => v =~ '^b')
10365f91e74bSBram Moolenaar  endfor
10375f91e74bSBram Moolenaar
10385f91e74bSBram Moolenaar  # this fails
10395f91e74bSBram Moolenaar  lines =<< trim END
10405f91e74bSBram Moolenaar      echo FilterWithCond('foo', (v) => v .. '^b')
10415f91e74bSBram Moolenaar  END
10425f91e74bSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
1043a9931535SBram Moolenaar
1044a9931535SBram Moolenaar  lines =<< trim END
1045a9931535SBram Moolenaar      var Lambda1 = (x) => {
1046a9931535SBram Moolenaar              return x
1047a9931535SBram Moolenaar              }
1048a9931535SBram Moolenaar      assert_equal('asdf', Lambda1('asdf'))
1049a9931535SBram Moolenaar      var Lambda2 = (x): string => {
1050a9931535SBram Moolenaar              return x
1051a9931535SBram Moolenaar              }
1052a9931535SBram Moolenaar      assert_equal('foo', Lambda2('foo'))
1053a9931535SBram Moolenaar  END
1054a9931535SBram Moolenaar  CheckDefAndScriptSuccess(lines)
1055a9931535SBram Moolenaar
1056a9931535SBram Moolenaar  lines =<< trim END
1057a9931535SBram Moolenaar      var Lambda = (x): string => {
1058a9931535SBram Moolenaar              return x
1059a9931535SBram Moolenaar              }
1060a9931535SBram Moolenaar      echo Lambda(['foo'])
1061a9931535SBram Moolenaar  END
1062a9931535SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1012:')
10630346b799SBram Moolenaarenddef
10640346b799SBram Moolenaar
1065709664ccSBram Moolenaardef Test_lambda_uses_assigned_var()
1066709664ccSBram Moolenaar  CheckDefSuccess([
1067709664ccSBram Moolenaar        'var x: any = "aaa"'
10682949cfdbSBram Moolenaar        'x = filter(["bbb"], (_, v) => v =~ x)'])
1069709664ccSBram Moolenaarenddef
1070709664ccSBram Moolenaar
107118062fcaSBram Moolenaardef Test_pass_legacy_lambda_to_def_func()
107218062fcaSBram Moolenaar  var lines =<< trim END
107318062fcaSBram Moolenaar      vim9script
107418062fcaSBram Moolenaar      func Foo()
107518062fcaSBram Moolenaar        eval s:Bar({x -> 0})
107618062fcaSBram Moolenaar      endfunc
107718062fcaSBram Moolenaar      def Bar(y: any)
107818062fcaSBram Moolenaar      enddef
107918062fcaSBram Moolenaar      Foo()
108018062fcaSBram Moolenaar  END
108118062fcaSBram Moolenaar  CheckScriptSuccess(lines)
1082831bdf86SBram Moolenaar
1083831bdf86SBram Moolenaar  lines =<< trim END
1084831bdf86SBram Moolenaar      vim9script
10857a40ff00SBram Moolenaar      def g:TestFunc(f: func)
1086831bdf86SBram Moolenaar      enddef
1087831bdf86SBram Moolenaar      legacy call g:TestFunc({-> 0})
1088831bdf86SBram Moolenaar      delfunc g:TestFunc
1089831bdf86SBram Moolenaar
1090831bdf86SBram Moolenaar      def g:TestFunc(f: func(number))
1091831bdf86SBram Moolenaar      enddef
1092831bdf86SBram Moolenaar      legacy call g:TestFunc({nr -> 0})
1093831bdf86SBram Moolenaar      delfunc g:TestFunc
1094831bdf86SBram Moolenaar  END
1095831bdf86SBram Moolenaar  CheckScriptSuccess(lines)
109618062fcaSBram Moolenaarenddef
109718062fcaSBram Moolenaar
10985deeb3f1SBram Moolenaar" Default arg and varargs
10995deeb3f1SBram Moolenaardef MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
11007a9cbca0SBram Moolenaar  var res = one .. ',' .. two
11015deeb3f1SBram Moolenaar  for s in rest
11025deeb3f1SBram Moolenaar    res ..= ',' .. s
11035deeb3f1SBram Moolenaar  endfor
11045deeb3f1SBram Moolenaar  return res
11055deeb3f1SBram Moolenaarenddef
11065deeb3f1SBram Moolenaar
11075deeb3f1SBram Moolenaardef Test_call_def_varargs()
11089bd5d879SBram Moolenaar  assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
1109c0c71e9dSBram Moolenaar  MyDefVarargs('one')->assert_equal('one,foo')
1110c0c71e9dSBram Moolenaar  MyDefVarargs('one', 'two')->assert_equal('one,two')
1111c0c71e9dSBram Moolenaar  MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
111224aa48b7SBram Moolenaar  CheckDefFailure(['MyDefVarargs("one", 22)'],
11137707228aSBram Moolenaar      'E1013: Argument 2: type mismatch, expected string but got number')
111424aa48b7SBram Moolenaar  CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
11157707228aSBram Moolenaar      'E1013: Argument 3: type mismatch, expected string but got number')
111624aa48b7SBram Moolenaar
11177a9cbca0SBram Moolenaar  var lines =<< trim END
111824aa48b7SBram Moolenaar      vim9script
111924aa48b7SBram Moolenaar      def Func(...l: list<string>)
112024aa48b7SBram Moolenaar        echo l
112124aa48b7SBram Moolenaar      enddef
112224aa48b7SBram Moolenaar      Func('a', 'b', 'c')
112324aa48b7SBram Moolenaar  END
112424aa48b7SBram Moolenaar  CheckScriptSuccess(lines)
112524aa48b7SBram Moolenaar
112624aa48b7SBram Moolenaar  lines =<< trim END
112724aa48b7SBram Moolenaar      vim9script
112824aa48b7SBram Moolenaar      def Func(...l: list<string>)
112924aa48b7SBram Moolenaar        echo l
113024aa48b7SBram Moolenaar      enddef
113124aa48b7SBram Moolenaar      Func()
113224aa48b7SBram Moolenaar  END
113324aa48b7SBram Moolenaar  CheckScriptSuccess(lines)
113424aa48b7SBram Moolenaar
113524aa48b7SBram Moolenaar  lines =<< trim END
113624aa48b7SBram Moolenaar      vim9script
11372a38908bSBram Moolenaar      def Func(...l: list<any>)
11382f8cbc4bSBram Moolenaar        echo l
11392f8cbc4bSBram Moolenaar      enddef
11402f8cbc4bSBram Moolenaar      Func(0)
11412f8cbc4bSBram Moolenaar  END
11422f8cbc4bSBram Moolenaar  CheckScriptSuccess(lines)
11432f8cbc4bSBram Moolenaar
11442f8cbc4bSBram Moolenaar  lines =<< trim END
11452f8cbc4bSBram Moolenaar      vim9script
11462a38908bSBram Moolenaar      def Func(...l: any)
11472a38908bSBram Moolenaar        echo l
11482a38908bSBram Moolenaar      enddef
11492a38908bSBram Moolenaar      Func(0)
11502a38908bSBram Moolenaar  END
11512a38908bSBram Moolenaar  CheckScriptFailure(lines, 'E1180:', 2)
11522a38908bSBram Moolenaar
11532a38908bSBram Moolenaar  lines =<< trim END
11542a38908bSBram Moolenaar      vim9script
115528022727SBram Moolenaar      def Func(..._l: list<string>)
115628022727SBram Moolenaar        echo _l
115728022727SBram Moolenaar      enddef
115828022727SBram Moolenaar      Func('a', 'b', 'c')
115928022727SBram Moolenaar  END
116028022727SBram Moolenaar  CheckScriptSuccess(lines)
116128022727SBram Moolenaar
116228022727SBram Moolenaar  lines =<< trim END
116328022727SBram Moolenaar      vim9script
116424aa48b7SBram Moolenaar      def Func(...l: list<string>)
116524aa48b7SBram Moolenaar        echo l
116624aa48b7SBram Moolenaar      enddef
116724aa48b7SBram Moolenaar      Func(1, 2, 3)
116824aa48b7SBram Moolenaar  END
11697707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
117024aa48b7SBram Moolenaar
117124aa48b7SBram Moolenaar  lines =<< trim END
117224aa48b7SBram Moolenaar      vim9script
117324aa48b7SBram Moolenaar      def Func(...l: list<string>)
117424aa48b7SBram Moolenaar        echo l
117524aa48b7SBram Moolenaar      enddef
117624aa48b7SBram Moolenaar      Func('a', 9)
117724aa48b7SBram Moolenaar  END
11787707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
117924aa48b7SBram Moolenaar
118024aa48b7SBram Moolenaar  lines =<< trim END
118124aa48b7SBram Moolenaar      vim9script
118224aa48b7SBram Moolenaar      def Func(...l: list<string>)
118324aa48b7SBram Moolenaar        echo l
118424aa48b7SBram Moolenaar      enddef
118524aa48b7SBram Moolenaar      Func(1, 'a')
118624aa48b7SBram Moolenaar  END
11877707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
11884f53b79bSBram Moolenaar
11894f53b79bSBram Moolenaar  lines =<< trim END
11904f53b79bSBram Moolenaar      vim9script
11914f53b79bSBram Moolenaar      def Func(  # some comment
11924f53b79bSBram Moolenaar                ...l = []
11934f53b79bSBram Moolenaar                )
11944f53b79bSBram Moolenaar        echo l
11954f53b79bSBram Moolenaar      enddef
11964f53b79bSBram Moolenaar  END
11974f53b79bSBram Moolenaar  CheckScriptFailure(lines, 'E1160:')
11986ce46b99SBram Moolenaar
11996ce46b99SBram Moolenaar  lines =<< trim END
12006ce46b99SBram Moolenaar      vim9script
12016ce46b99SBram Moolenaar      def DoIt()
12026ce46b99SBram Moolenaar        g:Later('')
12036ce46b99SBram Moolenaar      enddef
12046ce46b99SBram Moolenaar      defcompile
12056ce46b99SBram Moolenaar      def g:Later(...l:  list<number>)
12066ce46b99SBram Moolenaar      enddef
12076ce46b99SBram Moolenaar      DoIt()
12086ce46b99SBram Moolenaar  END
12096ce46b99SBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got string')
12105deeb3f1SBram Moolenaarenddef
12115deeb3f1SBram Moolenaar
12121378fbc4SBram Moolenaarlet s:value = ''
12131378fbc4SBram Moolenaar
12141378fbc4SBram Moolenaardef FuncOneDefArg(opt = 'text')
12151378fbc4SBram Moolenaar  s:value = opt
12161378fbc4SBram Moolenaarenddef
12171378fbc4SBram Moolenaar
12181378fbc4SBram Moolenaardef FuncTwoDefArg(nr = 123, opt = 'text'): string
12191378fbc4SBram Moolenaar  return nr .. opt
12201378fbc4SBram Moolenaarenddef
12211378fbc4SBram Moolenaar
12221378fbc4SBram Moolenaardef FuncVarargs(...arg: list<string>): string
12231378fbc4SBram Moolenaar  return join(arg, ',')
12241378fbc4SBram Moolenaarenddef
12251378fbc4SBram Moolenaar
12261378fbc4SBram Moolenaardef Test_func_type_varargs()
12277a9cbca0SBram Moolenaar  var RefDefArg: func(?string)
12281378fbc4SBram Moolenaar  RefDefArg = FuncOneDefArg
12291378fbc4SBram Moolenaar  RefDefArg()
1230c0c71e9dSBram Moolenaar  s:value->assert_equal('text')
12311378fbc4SBram Moolenaar  RefDefArg('some')
1232c0c71e9dSBram Moolenaar  s:value->assert_equal('some')
12331378fbc4SBram Moolenaar
12347a9cbca0SBram Moolenaar  var RefDef2Arg: func(?number, ?string): string
12351378fbc4SBram Moolenaar  RefDef2Arg = FuncTwoDefArg
1236c0c71e9dSBram Moolenaar  RefDef2Arg()->assert_equal('123text')
1237c0c71e9dSBram Moolenaar  RefDef2Arg(99)->assert_equal('99text')
1238c0c71e9dSBram Moolenaar  RefDef2Arg(77, 'some')->assert_equal('77some')
12391378fbc4SBram Moolenaar
12407a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
12417a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
12421378fbc4SBram Moolenaar
12437a9cbca0SBram Moolenaar  var RefVarargs: func(...list<string>): string
12441378fbc4SBram Moolenaar  RefVarargs = FuncVarargs
1245c0c71e9dSBram Moolenaar  RefVarargs()->assert_equal('')
1246c0c71e9dSBram Moolenaar  RefVarargs('one')->assert_equal('one')
1247c0c71e9dSBram Moolenaar  RefVarargs('one', 'two')->assert_equal('one,two')
12481378fbc4SBram Moolenaar
12497a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
12507a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
12511378fbc4SBram Moolenaarenddef
12521378fbc4SBram Moolenaar
12530b76b42dSBram Moolenaar" Only varargs
12540b76b42dSBram Moolenaardef MyVarargsOnly(...args: list<string>): string
12550b76b42dSBram Moolenaar  return join(args, ',')
12560b76b42dSBram Moolenaarenddef
12570b76b42dSBram Moolenaar
12580b76b42dSBram Moolenaardef Test_call_varargs_only()
1259c0c71e9dSBram Moolenaar  MyVarargsOnly()->assert_equal('')
1260c0c71e9dSBram Moolenaar  MyVarargsOnly('one')->assert_equal('one')
1261c0c71e9dSBram Moolenaar  MyVarargsOnly('one', 'two')->assert_equal('one,two')
12627707228aSBram Moolenaar  CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
12637707228aSBram Moolenaar  CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
12640b76b42dSBram Moolenaarenddef
12650b76b42dSBram Moolenaar
12665deeb3f1SBram Moolenaardef Test_using_var_as_arg()
12677a9cbca0SBram Moolenaar  writefile(['def Func(x: number)',  'var x = 234', 'enddef', 'defcompile'], 'Xdef')
12689bd5d879SBram Moolenaar  assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
1269d2c61705SBram Moolenaar  delete('Xdef')
12705deeb3f1SBram Moolenaarenddef
12715deeb3f1SBram Moolenaar
1272cb2bdb1cSBram Moolenaardef DictArg(arg: dict<string>)
1273cb2bdb1cSBram Moolenaar  arg['key'] = 'value'
1274cb2bdb1cSBram Moolenaarenddef
1275cb2bdb1cSBram Moolenaar
1276cb2bdb1cSBram Moolenaardef ListArg(arg: list<string>)
1277cb2bdb1cSBram Moolenaar  arg[0] = 'value'
1278cb2bdb1cSBram Moolenaarenddef
1279cb2bdb1cSBram Moolenaar
1280cb2bdb1cSBram Moolenaardef Test_assign_to_argument()
1281f5be8cdbSBram Moolenaar  # works for dict and list
12827a9cbca0SBram Moolenaar  var d: dict<string> = {}
1283cb2bdb1cSBram Moolenaar  DictArg(d)
1284c0c71e9dSBram Moolenaar  d['key']->assert_equal('value')
12857a9cbca0SBram Moolenaar  var l: list<string> = []
1286cb2bdb1cSBram Moolenaar  ListArg(l)
1287c0c71e9dSBram Moolenaar  l[0]->assert_equal('value')
1288cb2bdb1cSBram Moolenaar
1289d2c61705SBram Moolenaar  CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
12902d870f8dSBram Moolenaar  delfunc! g:Func
1291cb2bdb1cSBram Moolenaarenddef
1292cb2bdb1cSBram Moolenaar
1293b816dae1SBram Moolenaar" These argument names are reserved in legacy functions.
1294b816dae1SBram Moolenaardef WithReservedNames(firstline: string, lastline: string): string
1295b816dae1SBram Moolenaar  return firstline .. lastline
1296b816dae1SBram Moolenaarenddef
1297b816dae1SBram Moolenaar
1298b816dae1SBram Moolenaardef Test_argument_names()
1299b816dae1SBram Moolenaar  assert_equal('OK', WithReservedNames('O', 'K'))
1300b816dae1SBram Moolenaarenddef
1301b816dae1SBram Moolenaar
13025deeb3f1SBram Moolenaardef Test_call_func_defined_later()
1303c0c71e9dSBram Moolenaar  g:DefinedLater('one')->assert_equal('one')
13049bd5d879SBram Moolenaar  assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
13055deeb3f1SBram Moolenaarenddef
13065deeb3f1SBram Moolenaar
13071df8b3fbSBram Moolenaarfunc DefinedLater(arg)
13081df8b3fbSBram Moolenaar  return a:arg
13091df8b3fbSBram Moolenaarendfunc
13101df8b3fbSBram Moolenaar
13111df8b3fbSBram Moolenaardef Test_call_funcref()
1312c0c71e9dSBram Moolenaar  g:SomeFunc('abc')->assert_equal(3)
13139bd5d879SBram Moolenaar  assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
13149bd5d879SBram Moolenaar  assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
13152f1980f7SBram Moolenaar
13167a9cbca0SBram Moolenaar  var lines =<< trim END
13172f1980f7SBram Moolenaar    vim9script
13182f1980f7SBram Moolenaar    def RetNumber(): number
13192f1980f7SBram Moolenaar      return 123
13202f1980f7SBram Moolenaar    enddef
13217a9cbca0SBram Moolenaar    var Funcref: func: number = function('RetNumber')
1322c0c71e9dSBram Moolenaar    Funcref()->assert_equal(123)
13232f1980f7SBram Moolenaar  END
13242f1980f7SBram Moolenaar  CheckScriptSuccess(lines)
13250f60e80fSBram Moolenaar
13260f60e80fSBram Moolenaar  lines =<< trim END
13270f60e80fSBram Moolenaar    vim9script
13280f60e80fSBram Moolenaar    def RetNumber(): number
13290f60e80fSBram Moolenaar      return 123
13300f60e80fSBram Moolenaar    enddef
13310f60e80fSBram Moolenaar    def Bar(F: func: number): number
13320f60e80fSBram Moolenaar      return F()
13330f60e80fSBram Moolenaar    enddef
13347a9cbca0SBram Moolenaar    var Funcref = function('RetNumber')
1335c0c71e9dSBram Moolenaar    Bar(Funcref)->assert_equal(123)
13360f60e80fSBram Moolenaar  END
13370f60e80fSBram Moolenaar  CheckScriptSuccess(lines)
1338bfba8651SBram Moolenaar
1339bfba8651SBram Moolenaar  lines =<< trim END
1340bfba8651SBram Moolenaar    vim9script
1341bfba8651SBram Moolenaar    def UseNumber(nr: number)
1342bfba8651SBram Moolenaar      echo nr
1343bfba8651SBram Moolenaar    enddef
13447a9cbca0SBram Moolenaar    var Funcref: func(number) = function('UseNumber')
1345bfba8651SBram Moolenaar    Funcref(123)
1346bfba8651SBram Moolenaar  END
1347bfba8651SBram Moolenaar  CheckScriptSuccess(lines)
1348b8070e31SBram Moolenaar
1349b8070e31SBram Moolenaar  lines =<< trim END
1350b8070e31SBram Moolenaar    vim9script
1351b8070e31SBram Moolenaar    def UseNumber(nr: number)
1352b8070e31SBram Moolenaar      echo nr
1353b8070e31SBram Moolenaar    enddef
13547a9cbca0SBram Moolenaar    var Funcref: func(string) = function('UseNumber')
1355b8070e31SBram Moolenaar  END
13565e654230SBram Moolenaar  CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
13574fc224caSBram Moolenaar
13584fc224caSBram Moolenaar  lines =<< trim END
13594fc224caSBram Moolenaar    vim9script
13604fc224caSBram Moolenaar    def EchoNr(nr = 34)
13614fc224caSBram Moolenaar      g:echo = nr
13624fc224caSBram Moolenaar    enddef
13637a9cbca0SBram Moolenaar    var Funcref: func(?number) = function('EchoNr')
13644fc224caSBram Moolenaar    Funcref()
1365c0c71e9dSBram Moolenaar    g:echo->assert_equal(34)
13664fc224caSBram Moolenaar    Funcref(123)
1367c0c71e9dSBram Moolenaar    g:echo->assert_equal(123)
13684fc224caSBram Moolenaar  END
13694fc224caSBram Moolenaar  CheckScriptSuccess(lines)
1370ace6132aSBram Moolenaar
1371ace6132aSBram Moolenaar  lines =<< trim END
1372ace6132aSBram Moolenaar    vim9script
1373ace6132aSBram Moolenaar    def EchoList(...l: list<number>)
1374ace6132aSBram Moolenaar      g:echo = l
1375ace6132aSBram Moolenaar    enddef
13767a9cbca0SBram Moolenaar    var Funcref: func(...list<number>) = function('EchoList')
1377ace6132aSBram Moolenaar    Funcref()
1378c0c71e9dSBram Moolenaar    g:echo->assert_equal([])
1379ace6132aSBram Moolenaar    Funcref(1, 2, 3)
1380c0c71e9dSBram Moolenaar    g:echo->assert_equal([1, 2, 3])
1381ace6132aSBram Moolenaar  END
1382ace6132aSBram Moolenaar  CheckScriptSuccess(lines)
138301865adeSBram Moolenaar
138401865adeSBram Moolenaar  lines =<< trim END
138501865adeSBram Moolenaar    vim9script
138601865adeSBram Moolenaar    def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
138701865adeSBram Moolenaar      g:optarg = opt
138801865adeSBram Moolenaar      g:listarg = l
138901865adeSBram Moolenaar      return nr
139001865adeSBram Moolenaar    enddef
13917a9cbca0SBram Moolenaar    var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
1392c0c71e9dSBram Moolenaar    Funcref(10)->assert_equal(10)
1393c0c71e9dSBram Moolenaar    g:optarg->assert_equal(12)
1394c0c71e9dSBram Moolenaar    g:listarg->assert_equal([])
139501865adeSBram Moolenaar
1396c0c71e9dSBram Moolenaar    Funcref(11, 22)->assert_equal(11)
1397c0c71e9dSBram Moolenaar    g:optarg->assert_equal(22)
1398c0c71e9dSBram Moolenaar    g:listarg->assert_equal([])
139901865adeSBram Moolenaar
1400c0c71e9dSBram Moolenaar    Funcref(17, 18, 1, 2, 3)->assert_equal(17)
1401c0c71e9dSBram Moolenaar    g:optarg->assert_equal(18)
1402c0c71e9dSBram Moolenaar    g:listarg->assert_equal([1, 2, 3])
140301865adeSBram Moolenaar  END
140401865adeSBram Moolenaar  CheckScriptSuccess(lines)
14051df8b3fbSBram Moolenaarenddef
14061df8b3fbSBram Moolenaar
14071df8b3fbSBram Moolenaarlet SomeFunc = function('len')
14081df8b3fbSBram Moolenaarlet NotAFunc = 'text'
14091df8b3fbSBram Moolenaar
141099aaf0ceSBram Moolenaardef CombineFuncrefTypes()
1411f5be8cdbSBram Moolenaar  # same arguments, different return type
14127a9cbca0SBram Moolenaar  var Ref1: func(bool): string
14137a9cbca0SBram Moolenaar  var Ref2: func(bool): number
14147a9cbca0SBram Moolenaar  var Ref3: func(bool): any
141599aaf0ceSBram Moolenaar  Ref3 = g:cond ? Ref1 : Ref2
141699aaf0ceSBram Moolenaar
1417f5be8cdbSBram Moolenaar  # different number of arguments
14187a9cbca0SBram Moolenaar  var Refa1: func(bool): number
14197a9cbca0SBram Moolenaar  var Refa2: func(bool, number): number
14207a9cbca0SBram Moolenaar  var Refa3: func: number
142199aaf0ceSBram Moolenaar  Refa3 = g:cond ? Refa1 : Refa2
142299aaf0ceSBram Moolenaar
1423f5be8cdbSBram Moolenaar  # different argument types
14247a9cbca0SBram Moolenaar  var Refb1: func(bool, string): number
14257a9cbca0SBram Moolenaar  var Refb2: func(string, number): number
14267a9cbca0SBram Moolenaar  var Refb3: func(any, any): number
142799aaf0ceSBram Moolenaar  Refb3 = g:cond ? Refb1 : Refb2
142899aaf0ceSBram Moolenaarenddef
142999aaf0ceSBram Moolenaar
14305deeb3f1SBram Moolenaardef FuncWithForwardCall()
14311df8b3fbSBram Moolenaar  return g:DefinedEvenLater("yes")
14325deeb3f1SBram Moolenaarenddef
14335deeb3f1SBram Moolenaar
14345deeb3f1SBram Moolenaardef DefinedEvenLater(arg: string): string
14355deeb3f1SBram Moolenaar  return arg
14365deeb3f1SBram Moolenaarenddef
14375deeb3f1SBram Moolenaar
14385deeb3f1SBram Moolenaardef Test_error_in_nested_function()
1439f5be8cdbSBram Moolenaar  # Error in called function requires unwinding the call stack.
144044d6652dSBram Moolenaar  assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
14415deeb3f1SBram Moolenaarenddef
14425deeb3f1SBram Moolenaar
14435deeb3f1SBram Moolenaardef Test_return_type_wrong()
14445a849da5SBram Moolenaar  CheckScriptFailure([
14455a849da5SBram Moolenaar        'def Func(): number',
14465a849da5SBram Moolenaar        'return "a"',
14475a849da5SBram Moolenaar        'enddef',
14485a849da5SBram Moolenaar        'defcompile'], 'expected number but got string')
14492d870f8dSBram Moolenaar  delfunc! g:Func
14505a849da5SBram Moolenaar  CheckScriptFailure([
14515a849da5SBram Moolenaar        'def Func(): string',
14525a849da5SBram Moolenaar        'return 1',
14535a849da5SBram Moolenaar        'enddef',
14545a849da5SBram Moolenaar        'defcompile'], 'expected string but got number')
14552d870f8dSBram Moolenaar  delfunc! g:Func
14565a849da5SBram Moolenaar  CheckScriptFailure([
14575a849da5SBram Moolenaar        'def Func(): void',
14585a849da5SBram Moolenaar        'return "a"',
14595a849da5SBram Moolenaar        'enddef',
14605a849da5SBram Moolenaar        'defcompile'],
14615a849da5SBram Moolenaar        'E1096: Returning a value in a function without a return type')
14622d870f8dSBram Moolenaar  delfunc! g:Func
14635a849da5SBram Moolenaar  CheckScriptFailure([
14645a849da5SBram Moolenaar        'def Func()',
14655a849da5SBram Moolenaar        'return "a"',
14665a849da5SBram Moolenaar        'enddef',
14675a849da5SBram Moolenaar        'defcompile'],
14685a849da5SBram Moolenaar        'E1096: Returning a value in a function without a return type')
14692d870f8dSBram Moolenaar  delfunc! g:Func
14705deeb3f1SBram Moolenaar
14715a849da5SBram Moolenaar  CheckScriptFailure([
14725a849da5SBram Moolenaar        'def Func(): number',
14735a849da5SBram Moolenaar        'return',
14745a849da5SBram Moolenaar        'enddef',
14755a849da5SBram Moolenaar        'defcompile'], 'E1003:')
14762d870f8dSBram Moolenaar  delfunc! g:Func
14775deeb3f1SBram Moolenaar
147833ea9fd4SBram Moolenaar  CheckScriptFailure([
147933ea9fd4SBram Moolenaar        'def Func():number',
148033ea9fd4SBram Moolenaar        'return 123',
148133ea9fd4SBram Moolenaar        'enddef',
148233ea9fd4SBram Moolenaar        'defcompile'], 'E1069:')
148333ea9fd4SBram Moolenaar  delfunc! g:Func
148433ea9fd4SBram Moolenaar
148533ea9fd4SBram Moolenaar  CheckScriptFailure([
148633ea9fd4SBram Moolenaar        'def Func() :number',
148733ea9fd4SBram Moolenaar        'return 123',
148833ea9fd4SBram Moolenaar        'enddef',
148933ea9fd4SBram Moolenaar        'defcompile'], 'E1059:')
149033ea9fd4SBram Moolenaar  delfunc! g:Func
149133ea9fd4SBram Moolenaar
149233ea9fd4SBram Moolenaar  CheckScriptFailure([
149333ea9fd4SBram Moolenaar        'def Func() : number',
149433ea9fd4SBram Moolenaar        'return 123',
149533ea9fd4SBram Moolenaar        'enddef',
149633ea9fd4SBram Moolenaar        'defcompile'], 'E1059:')
149733ea9fd4SBram Moolenaar  delfunc! g:Func
149833ea9fd4SBram Moolenaar
14995deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
15002d870f8dSBram Moolenaar  delfunc! g:Func
15015deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
15022d870f8dSBram Moolenaar  delfunc! g:Func
1503ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
15042d870f8dSBram Moolenaar  delfunc! g:Func
15055a849da5SBram Moolenaar
15065a849da5SBram Moolenaar  CheckScriptFailure([
15075a849da5SBram Moolenaar        'vim9script',
15085a849da5SBram Moolenaar        'def FuncB()',
15095a849da5SBram Moolenaar        '  return 123',
15105a849da5SBram Moolenaar        'enddef',
15115a849da5SBram Moolenaar        'def FuncA()',
15125a849da5SBram Moolenaar        '   FuncB()',
15135a849da5SBram Moolenaar        'enddef',
15145a849da5SBram Moolenaar        'defcompile'], 'E1096:')
15155deeb3f1SBram Moolenaarenddef
15165deeb3f1SBram Moolenaar
15175deeb3f1SBram Moolenaardef Test_arg_type_wrong()
15185deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
1519ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
1520f93c7feaSBram Moolenaar  CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
15216e949784SBram Moolenaar  CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
152234fcb697SYegappan Lakshmanan  CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
152334fcb697SYegappan Lakshmanan  CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
15245deeb3f1SBram Moolenaarenddef
15255deeb3f1SBram Moolenaar
152686cdb8a4SBram Moolenaardef Test_white_space_before_comma()
152786cdb8a4SBram Moolenaar  var lines =<< trim END
152886cdb8a4SBram Moolenaar    vim9script
152986cdb8a4SBram Moolenaar    def Func(a: number , b: number)
153086cdb8a4SBram Moolenaar    enddef
153186cdb8a4SBram Moolenaar  END
153286cdb8a4SBram Moolenaar  CheckScriptFailure(lines, 'E1068:')
1533611728f8SYegappan Lakshmanan  call assert_fails('vim9cmd echo stridx("a" .. "b" , "a")', 'E1068:')
153486cdb8a4SBram Moolenaarenddef
153586cdb8a4SBram Moolenaar
1536608d78fbSBram Moolenaardef Test_white_space_after_comma()
1537608d78fbSBram Moolenaar  var lines =<< trim END
1538608d78fbSBram Moolenaar    vim9script
1539608d78fbSBram Moolenaar    def Func(a: number,b: number)
1540608d78fbSBram Moolenaar    enddef
1541608d78fbSBram Moolenaar  END
1542608d78fbSBram Moolenaar  CheckScriptFailure(lines, 'E1069:')
1543608d78fbSBram Moolenaar
1544608d78fbSBram Moolenaar  # OK in legacy function
1545608d78fbSBram Moolenaar  lines =<< trim END
1546608d78fbSBram Moolenaar    vim9script
1547608d78fbSBram Moolenaar    func Func(a,b)
1548608d78fbSBram Moolenaar    endfunc
1549608d78fbSBram Moolenaar  END
1550608d78fbSBram Moolenaar  CheckScriptSuccess(lines)
1551608d78fbSBram Moolenaarenddef
1552608d78fbSBram Moolenaar
15535deeb3f1SBram Moolenaardef Test_vim9script_call()
15547a9cbca0SBram Moolenaar  var lines =<< trim END
15555deeb3f1SBram Moolenaar    vim9script
15567a9cbca0SBram Moolenaar    var name = ''
15575deeb3f1SBram Moolenaar    def MyFunc(arg: string)
15587a9cbca0SBram Moolenaar       name = arg
15595deeb3f1SBram Moolenaar    enddef
15605deeb3f1SBram Moolenaar    MyFunc('foobar')
15617a9cbca0SBram Moolenaar    name->assert_equal('foobar')
15625deeb3f1SBram Moolenaar
15637a9cbca0SBram Moolenaar    var str = 'barfoo'
15645deeb3f1SBram Moolenaar    str->MyFunc()
15657a9cbca0SBram Moolenaar    name->assert_equal('barfoo')
15665deeb3f1SBram Moolenaar
15676797966dSBram Moolenaar    g:value = 'value'
15685deeb3f1SBram Moolenaar    g:value->MyFunc()
15697a9cbca0SBram Moolenaar    name->assert_equal('value')
15705deeb3f1SBram Moolenaar
15717a9cbca0SBram Moolenaar    var listvar = []
15725deeb3f1SBram Moolenaar    def ListFunc(arg: list<number>)
15735deeb3f1SBram Moolenaar       listvar = arg
15745deeb3f1SBram Moolenaar    enddef
15755deeb3f1SBram Moolenaar    [1, 2, 3]->ListFunc()
1576c0c71e9dSBram Moolenaar    listvar->assert_equal([1, 2, 3])
15775deeb3f1SBram Moolenaar
15787a9cbca0SBram Moolenaar    var dictvar = {}
15795deeb3f1SBram Moolenaar    def DictFunc(arg: dict<number>)
15805deeb3f1SBram Moolenaar       dictvar = arg
15815deeb3f1SBram Moolenaar    enddef
1582e0de171eSBram Moolenaar    {a: 1, b: 2}->DictFunc()
1583e0de171eSBram Moolenaar    dictvar->assert_equal({a: 1, b: 2})
15845deeb3f1SBram Moolenaar    def CompiledDict()
1585e0de171eSBram Moolenaar      {a: 3, b: 4}->DictFunc()
15865deeb3f1SBram Moolenaar    enddef
15875deeb3f1SBram Moolenaar    CompiledDict()
1588e0de171eSBram Moolenaar    dictvar->assert_equal({a: 3, b: 4})
15895deeb3f1SBram Moolenaar
1590e0de171eSBram Moolenaar    {a: 3, b: 4}->DictFunc()
1591e0de171eSBram Moolenaar    dictvar->assert_equal({a: 3, b: 4})
15925deeb3f1SBram Moolenaar
15935deeb3f1SBram Moolenaar    ('text')->MyFunc()
15947a9cbca0SBram Moolenaar    name->assert_equal('text')
15955deeb3f1SBram Moolenaar    ("some")->MyFunc()
15967a9cbca0SBram Moolenaar    name->assert_equal('some')
1597e6b5324eSBram Moolenaar
159813e12b8aSBram Moolenaar    # line starting with single quote is not a mark
159910409562SBram Moolenaar    # line starting with double quote can be a method call
16003d48e25dSBram Moolenaar    'asdfasdf'->MyFunc()
16017a9cbca0SBram Moolenaar    name->assert_equal('asdfasdf')
160210409562SBram Moolenaar    "xyz"->MyFunc()
16037a9cbca0SBram Moolenaar    name->assert_equal('xyz')
16043d48e25dSBram Moolenaar
16053d48e25dSBram Moolenaar    def UseString()
16063d48e25dSBram Moolenaar      'xyork'->MyFunc()
16073d48e25dSBram Moolenaar    enddef
16083d48e25dSBram Moolenaar    UseString()
16097a9cbca0SBram Moolenaar    name->assert_equal('xyork')
16103d48e25dSBram Moolenaar
161110409562SBram Moolenaar    def UseString2()
161210409562SBram Moolenaar      "knife"->MyFunc()
161310409562SBram Moolenaar    enddef
161410409562SBram Moolenaar    UseString2()
16157a9cbca0SBram Moolenaar    name->assert_equal('knife')
161610409562SBram Moolenaar
161713e12b8aSBram Moolenaar    # prepending a colon makes it a mark
161813e12b8aSBram Moolenaar    new
161913e12b8aSBram Moolenaar    setline(1, ['aaa', 'bbb', 'ccc'])
162013e12b8aSBram Moolenaar    normal! 3Gmt1G
162113e12b8aSBram Moolenaar    :'t
1622c0c71e9dSBram Moolenaar    getcurpos()[1]->assert_equal(3)
162313e12b8aSBram Moolenaar    bwipe!
162413e12b8aSBram Moolenaar
1625e6b5324eSBram Moolenaar    MyFunc(
1626e6b5324eSBram Moolenaar        'continued'
1627e6b5324eSBram Moolenaar        )
1628e6b5324eSBram Moolenaar    assert_equal('continued',
16297a9cbca0SBram Moolenaar            name
1630e6b5324eSBram Moolenaar            )
1631e6b5324eSBram Moolenaar
1632e6b5324eSBram Moolenaar    call MyFunc(
1633e6b5324eSBram Moolenaar        'more'
1634e6b5324eSBram Moolenaar          ..
1635e6b5324eSBram Moolenaar          'lines'
1636e6b5324eSBram Moolenaar        )
1637e6b5324eSBram Moolenaar    assert_equal(
1638e6b5324eSBram Moolenaar        'morelines',
16397a9cbca0SBram Moolenaar        name)
16405deeb3f1SBram Moolenaar  END
16415deeb3f1SBram Moolenaar  writefile(lines, 'Xcall.vim')
16425deeb3f1SBram Moolenaar  source Xcall.vim
16435deeb3f1SBram Moolenaar  delete('Xcall.vim')
16445deeb3f1SBram Moolenaarenddef
16455deeb3f1SBram Moolenaar
16465deeb3f1SBram Moolenaardef Test_vim9script_call_fail_decl()
16477a9cbca0SBram Moolenaar  var lines =<< trim END
16485deeb3f1SBram Moolenaar    vim9script
16497a9cbca0SBram Moolenaar    var name = ''
16505deeb3f1SBram Moolenaar    def MyFunc(arg: string)
16517a9cbca0SBram Moolenaar       var name = 123
16525deeb3f1SBram Moolenaar    enddef
1653822ba247SBram Moolenaar    defcompile
16545deeb3f1SBram Moolenaar  END
16556c4bfe4bSBram Moolenaar  CheckScriptFailure(lines, 'E1054:')
16565deeb3f1SBram Moolenaarenddef
16575deeb3f1SBram Moolenaar
165865b9545fSBram Moolenaardef Test_vim9script_call_fail_type()
16597a9cbca0SBram Moolenaar  var lines =<< trim END
166065b9545fSBram Moolenaar    vim9script
166165b9545fSBram Moolenaar    def MyFunc(arg: string)
166265b9545fSBram Moolenaar      echo arg
166365b9545fSBram Moolenaar    enddef
166465b9545fSBram Moolenaar    MyFunc(1234)
166565b9545fSBram Moolenaar  END
16667707228aSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
166765b9545fSBram Moolenaarenddef
166865b9545fSBram Moolenaar
16695deeb3f1SBram Moolenaardef Test_vim9script_call_fail_const()
16707a9cbca0SBram Moolenaar  var lines =<< trim END
16715deeb3f1SBram Moolenaar    vim9script
16725deeb3f1SBram Moolenaar    const var = ''
16735deeb3f1SBram Moolenaar    def MyFunc(arg: string)
16745deeb3f1SBram Moolenaar       var = 'asdf'
16755deeb3f1SBram Moolenaar    enddef
1676822ba247SBram Moolenaar    defcompile
16775deeb3f1SBram Moolenaar  END
16785deeb3f1SBram Moolenaar  writefile(lines, 'Xcall_const.vim')
16799bd5d879SBram Moolenaar  assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
16805deeb3f1SBram Moolenaar  delete('Xcall_const.vim')
16813bdc90b7SBram Moolenaar
16823bdc90b7SBram Moolenaar  lines =<< trim END
16833bdc90b7SBram Moolenaar      const g:Aconst = 77
16843bdc90b7SBram Moolenaar      def Change()
16853bdc90b7SBram Moolenaar        # comment
16863bdc90b7SBram Moolenaar        g:Aconst = 99
16873bdc90b7SBram Moolenaar      enddef
16883bdc90b7SBram Moolenaar      call Change()
16893bdc90b7SBram Moolenaar      unlet g:Aconst
16903bdc90b7SBram Moolenaar  END
16911dcf55d4SBram Moolenaar  CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
16925deeb3f1SBram Moolenaarenddef
16935deeb3f1SBram Moolenaar
16945deeb3f1SBram Moolenaar" Test that inside :function a Python function can be defined, :def is not
16955deeb3f1SBram Moolenaar" recognized.
16965deeb3f1SBram Moolenaarfunc Test_function_python()
16975deeb3f1SBram Moolenaar  CheckFeature python3
1698727345ebSBram Moolenaar  let py = 'python3'
16995deeb3f1SBram Moolenaar  execute py "<< EOF"
17005deeb3f1SBram Moolenaardef do_something():
17015deeb3f1SBram Moolenaar  return 1
17025deeb3f1SBram MoolenaarEOF
17035deeb3f1SBram Moolenaarendfunc
17045deeb3f1SBram Moolenaar
17055deeb3f1SBram Moolenaardef Test_delfunc()
17067a9cbca0SBram Moolenaar  var lines =<< trim END
17075deeb3f1SBram Moolenaar    vim9script
17084c17ad94SBram Moolenaar    def g:GoneSoon()
17095deeb3f1SBram Moolenaar      echo 'hello'
17105deeb3f1SBram Moolenaar    enddef
17115deeb3f1SBram Moolenaar
17125deeb3f1SBram Moolenaar    def CallGoneSoon()
17135deeb3f1SBram Moolenaar      GoneSoon()
17145deeb3f1SBram Moolenaar    enddef
1715822ba247SBram Moolenaar    defcompile
17165deeb3f1SBram Moolenaar
17174c17ad94SBram Moolenaar    delfunc g:GoneSoon
17185deeb3f1SBram Moolenaar    CallGoneSoon()
17195deeb3f1SBram Moolenaar  END
17205deeb3f1SBram Moolenaar  writefile(lines, 'XToDelFunc')
17219bd5d879SBram Moolenaar  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
17229bd5d879SBram Moolenaar  assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
17235deeb3f1SBram Moolenaar
17245deeb3f1SBram Moolenaar  delete('XToDelFunc')
17255deeb3f1SBram Moolenaarenddef
17265deeb3f1SBram Moolenaar
17275deeb3f1SBram Moolenaardef Test_redef_failure()
1728d2c61705SBram Moolenaar  writefile(['def Func0(): string',  'return "Func0"', 'enddef'], 'Xdef')
17295deeb3f1SBram Moolenaar  so Xdef
1730d2c61705SBram Moolenaar  writefile(['def Func1(): string',  'return "Func1"', 'enddef'], 'Xdef')
17315deeb3f1SBram Moolenaar  so Xdef
1732d2c61705SBram Moolenaar  writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
17339bd5d879SBram Moolenaar  assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
1734d2c61705SBram Moolenaar  writefile(['def Func2(): string',  'return "Func2"', 'enddef'], 'Xdef')
17355deeb3f1SBram Moolenaar  so Xdef
1736d2c61705SBram Moolenaar  delete('Xdef')
17375deeb3f1SBram Moolenaar
1738701cc6caSBram Moolenaar  assert_fails('g:Func0()', 'E1091:')
1739c0c71e9dSBram Moolenaar  g:Func1()->assert_equal('Func1')
1740c0c71e9dSBram Moolenaar  g:Func2()->assert_equal('Func2')
17415deeb3f1SBram Moolenaar
17425deeb3f1SBram Moolenaar  delfunc! Func0
17435deeb3f1SBram Moolenaar  delfunc! Func1
17445deeb3f1SBram Moolenaar  delfunc! Func2
17455deeb3f1SBram Moolenaarenddef
17465deeb3f1SBram Moolenaar
1747f93c7feaSBram Moolenaardef Test_vim9script_func()
17487a9cbca0SBram Moolenaar  var lines =<< trim END
1749f93c7feaSBram Moolenaar    vim9script
1750f93c7feaSBram Moolenaar    func Func(arg)
1751f93c7feaSBram Moolenaar      echo a:arg
1752f93c7feaSBram Moolenaar    endfunc
1753f93c7feaSBram Moolenaar    Func('text')
1754f93c7feaSBram Moolenaar  END
1755f93c7feaSBram Moolenaar  writefile(lines, 'XVim9Func')
1756f93c7feaSBram Moolenaar  so XVim9Func
1757f93c7feaSBram Moolenaar
1758f93c7feaSBram Moolenaar  delete('XVim9Func')
1759f93c7feaSBram Moolenaarenddef
1760f93c7feaSBram Moolenaar
17615deeb3f1SBram Moolenaarlet s:funcResult = 0
17625deeb3f1SBram Moolenaar
17635deeb3f1SBram Moolenaardef FuncNoArgNoRet()
17645390099aSBram Moolenaar  s:funcResult = 11
17655deeb3f1SBram Moolenaarenddef
17665deeb3f1SBram Moolenaar
17675deeb3f1SBram Moolenaardef FuncNoArgRetNumber(): number
17685390099aSBram Moolenaar  s:funcResult = 22
17695deeb3f1SBram Moolenaar  return 1234
17705deeb3f1SBram Moolenaarenddef
17715deeb3f1SBram Moolenaar
1772ec5929d0SBram Moolenaardef FuncNoArgRetString(): string
17735390099aSBram Moolenaar  s:funcResult = 45
1774ec5929d0SBram Moolenaar  return 'text'
1775ec5929d0SBram Moolenaarenddef
1776ec5929d0SBram Moolenaar
17775deeb3f1SBram Moolenaardef FuncOneArgNoRet(arg: number)
17785390099aSBram Moolenaar  s:funcResult = arg
17795deeb3f1SBram Moolenaarenddef
17805deeb3f1SBram Moolenaar
17815deeb3f1SBram Moolenaardef FuncOneArgRetNumber(arg: number): number
17825390099aSBram Moolenaar  s:funcResult = arg
17835deeb3f1SBram Moolenaar  return arg
17845deeb3f1SBram Moolenaarenddef
17855deeb3f1SBram Moolenaar
178608938eebSBram Moolenaardef FuncTwoArgNoRet(one: bool, two: number)
17875390099aSBram Moolenaar  s:funcResult = two
178808938eebSBram Moolenaarenddef
178908938eebSBram Moolenaar
1790ec5929d0SBram Moolenaardef FuncOneArgRetString(arg: string): string
1791ec5929d0SBram Moolenaar  return arg
1792ec5929d0SBram Moolenaarenddef
1793ec5929d0SBram Moolenaar
17948922860aSBram Moolenaardef FuncOneArgRetAny(arg: any): any
17958922860aSBram Moolenaar  return arg
17968922860aSBram Moolenaarenddef
17978922860aSBram Moolenaar
17985deeb3f1SBram Moolenaardef Test_func_type()
17997a9cbca0SBram Moolenaar  var Ref1: func()
18005390099aSBram Moolenaar  s:funcResult = 0
18015deeb3f1SBram Moolenaar  Ref1 = FuncNoArgNoRet
18025deeb3f1SBram Moolenaar  Ref1()
1803c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(11)
18044c683750SBram Moolenaar
18057a9cbca0SBram Moolenaar  var Ref2: func
18065390099aSBram Moolenaar  s:funcResult = 0
18074c683750SBram Moolenaar  Ref2 = FuncNoArgNoRet
18084c683750SBram Moolenaar  Ref2()
1809c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(11)
18104c683750SBram Moolenaar
18115390099aSBram Moolenaar  s:funcResult = 0
18124c683750SBram Moolenaar  Ref2 = FuncOneArgNoRet
18134c683750SBram Moolenaar  Ref2(12)
1814c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(12)
18154c683750SBram Moolenaar
18165390099aSBram Moolenaar  s:funcResult = 0
18174c683750SBram Moolenaar  Ref2 = FuncNoArgRetNumber
1818c0c71e9dSBram Moolenaar  Ref2()->assert_equal(1234)
1819c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(22)
18204c683750SBram Moolenaar
18215390099aSBram Moolenaar  s:funcResult = 0
18224c683750SBram Moolenaar  Ref2 = FuncOneArgRetNumber
1823c0c71e9dSBram Moolenaar  Ref2(13)->assert_equal(13)
1824c0c71e9dSBram Moolenaar  s:funcResult->assert_equal(13)
18255deeb3f1SBram Moolenaarenddef
18265deeb3f1SBram Moolenaar
18279978d473SBram Moolenaardef Test_repeat_return_type()
18287a9cbca0SBram Moolenaar  var res = 0
18299978d473SBram Moolenaar  for n in repeat([1], 3)
18309978d473SBram Moolenaar    res += n
18319978d473SBram Moolenaar  endfor
1832c0c71e9dSBram Moolenaar  res->assert_equal(3)
1833fce82b3aSBram Moolenaar
1834fce82b3aSBram Moolenaar  res = 0
1835fce82b3aSBram Moolenaar  for n in add([1, 2], 3)
1836fce82b3aSBram Moolenaar    res += n
1837fce82b3aSBram Moolenaar  endfor
1838c0c71e9dSBram Moolenaar  res->assert_equal(6)
18399978d473SBram Moolenaarenddef
18409978d473SBram Moolenaar
1841846178a7SBram Moolenaardef Test_argv_return_type()
1842846178a7SBram Moolenaar  next fileone filetwo
18437a9cbca0SBram Moolenaar  var res = ''
1844846178a7SBram Moolenaar  for name in argv()
1845846178a7SBram Moolenaar    res ..= name
1846846178a7SBram Moolenaar  endfor
1847c0c71e9dSBram Moolenaar  res->assert_equal('fileonefiletwo')
1848846178a7SBram Moolenaarenddef
1849846178a7SBram Moolenaar
1850ec5929d0SBram Moolenaardef Test_func_type_part()
18517a9cbca0SBram Moolenaar  var RefVoid: func: void
1852ec5929d0SBram Moolenaar  RefVoid = FuncNoArgNoRet
1853ec5929d0SBram Moolenaar  RefVoid = FuncOneArgNoRet
18547a9cbca0SBram Moolenaar  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
18557a9cbca0SBram Moolenaar  CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
1856ec5929d0SBram Moolenaar
18577a9cbca0SBram Moolenaar  var RefAny: func(): any
1858ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetNumber
1859ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetString
18607a9cbca0SBram Moolenaar  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
18617a9cbca0SBram Moolenaar  CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
1862ec5929d0SBram Moolenaar
18636abd3dc2SBram Moolenaar  var RefAnyNoArgs: func: any = RefAny
18646abd3dc2SBram Moolenaar
18657a9cbca0SBram Moolenaar  var RefNr: func: number
1866ec5929d0SBram Moolenaar  RefNr = FuncNoArgRetNumber
1867ec5929d0SBram Moolenaar  RefNr = FuncOneArgRetNumber
18687a9cbca0SBram Moolenaar  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
18697a9cbca0SBram Moolenaar  CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
1870ec5929d0SBram Moolenaar
18717a9cbca0SBram Moolenaar  var RefStr: func: string
1872ec5929d0SBram Moolenaar  RefStr = FuncNoArgRetString
1873ec5929d0SBram Moolenaar  RefStr = FuncOneArgRetString
18747a9cbca0SBram Moolenaar  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
18757a9cbca0SBram Moolenaar  CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
1876ec5929d0SBram Moolenaarenddef
1877ec5929d0SBram Moolenaar
18785deeb3f1SBram Moolenaardef Test_func_type_fails()
18797a9cbca0SBram Moolenaar  CheckDefFailure(['var ref1: func()'], 'E704:')
18805deeb3f1SBram Moolenaar
18817a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
18827a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
18837a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
18847a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
18857a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
18867a9cbca0SBram Moolenaar  CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
188708938eebSBram Moolenaar
18887a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
18897a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
18907a9cbca0SBram 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:')
18917a9cbca0SBram Moolenaar  CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
18925deeb3f1SBram Moolenaarenddef
18935deeb3f1SBram Moolenaar
18948922860aSBram Moolenaardef Test_func_return_type()
18957a9cbca0SBram Moolenaar  var nr: number
18968922860aSBram Moolenaar  nr = FuncNoArgRetNumber()
1897c0c71e9dSBram Moolenaar  nr->assert_equal(1234)
18988922860aSBram Moolenaar
18998922860aSBram Moolenaar  nr = FuncOneArgRetAny(122)
1900c0c71e9dSBram Moolenaar  nr->assert_equal(122)
19018922860aSBram Moolenaar
19027a9cbca0SBram Moolenaar  var str: string
19038922860aSBram Moolenaar  str = FuncOneArgRetAny('yes')
1904c0c71e9dSBram Moolenaar  str->assert_equal('yes')
19058922860aSBram Moolenaar
19067a9cbca0SBram Moolenaar  CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
19078922860aSBram Moolenaarenddef
19088922860aSBram Moolenaar
19096abd3dc2SBram Moolenaardef Test_func_common_type()
19106abd3dc2SBram Moolenaar  def FuncOne(n: number): number
19116abd3dc2SBram Moolenaar    return n
19126abd3dc2SBram Moolenaar  enddef
19136abd3dc2SBram Moolenaar  def FuncTwo(s: string): number
19146abd3dc2SBram Moolenaar    return len(s)
19156abd3dc2SBram Moolenaar  enddef
19166abd3dc2SBram Moolenaar  def FuncThree(n: number, s: string): number
19176abd3dc2SBram Moolenaar    return n + len(s)
19186abd3dc2SBram Moolenaar  enddef
19196abd3dc2SBram Moolenaar  var list = [FuncOne, FuncTwo, FuncThree]
19206abd3dc2SBram Moolenaar  assert_equal(8, list[0](8))
19216abd3dc2SBram Moolenaar  assert_equal(4, list[1]('word'))
19226abd3dc2SBram Moolenaar  assert_equal(7, list[2](3, 'word'))
19236abd3dc2SBram Moolenaarenddef
19246abd3dc2SBram Moolenaar
19255e774c75SBram Moolenaardef MultiLine(
19265e774c75SBram Moolenaar    arg1: string,
19275e774c75SBram Moolenaar    arg2 = 1234,
19285e774c75SBram Moolenaar    ...rest: list<string>
19295e774c75SBram Moolenaar      ): string
19305e774c75SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
19315e774c75SBram Moolenaarenddef
19325e774c75SBram Moolenaar
19332c330432SBram Moolenaardef MultiLineComment(
19342c330432SBram Moolenaar    arg1: string, # comment
19352c330432SBram Moolenaar    arg2 = 1234, # comment
19362c330432SBram Moolenaar    ...rest: list<string> # comment
19372c330432SBram Moolenaar      ): string # comment
19382c330432SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
19392c330432SBram Moolenaarenddef
19402c330432SBram Moolenaar
19415e774c75SBram Moolenaardef Test_multiline()
1942c0c71e9dSBram Moolenaar  MultiLine('text')->assert_equal('text1234')
1943c0c71e9dSBram Moolenaar  MultiLine('text', 777)->assert_equal('text777')
1944c0c71e9dSBram Moolenaar  MultiLine('text', 777, 'one')->assert_equal('text777one')
1945c0c71e9dSBram Moolenaar  MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
19465e774c75SBram Moolenaarenddef
19475e774c75SBram Moolenaar
194823e03252SBram Moolenaarfunc Test_multiline_not_vim9()
1949c0c71e9dSBram Moolenaar  call MultiLine('text')->assert_equal('text1234')
1950c0c71e9dSBram Moolenaar  call MultiLine('text', 777)->assert_equal('text777')
1951c0c71e9dSBram Moolenaar  call MultiLine('text', 777, 'one')->assert_equal('text777one')
1952c0c71e9dSBram Moolenaar  call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
195323e03252SBram Moolenaarendfunc
195423e03252SBram Moolenaar
19555e774c75SBram Moolenaar
1956ee4e0c1eSBram Moolenaar" When using CheckScriptFailure() for the below test, E1010 is generated instead
1957ee4e0c1eSBram Moolenaar" of E1056.
1958ee4e0c1eSBram Moolenaarfunc Test_E1056_1059()
1959ee4e0c1eSBram Moolenaar  let caught_1056 = 0
1960ee4e0c1eSBram Moolenaar  try
1961ee4e0c1eSBram Moolenaar    def F():
1962ee4e0c1eSBram Moolenaar      return 1
1963ee4e0c1eSBram Moolenaar    enddef
1964ee4e0c1eSBram Moolenaar  catch /E1056:/
1965ee4e0c1eSBram Moolenaar    let caught_1056 = 1
1966ee4e0c1eSBram Moolenaar  endtry
1967c0c71e9dSBram Moolenaar  eval caught_1056->assert_equal(1)
1968ee4e0c1eSBram Moolenaar
1969ee4e0c1eSBram Moolenaar  let caught_1059 = 0
1970ee4e0c1eSBram Moolenaar  try
1971ee4e0c1eSBram Moolenaar    def F5(items : list)
1972ee4e0c1eSBram Moolenaar      echo 'a'
1973ee4e0c1eSBram Moolenaar    enddef
1974ee4e0c1eSBram Moolenaar  catch /E1059:/
1975ee4e0c1eSBram Moolenaar    let caught_1059 = 1
1976ee4e0c1eSBram Moolenaar  endtry
1977c0c71e9dSBram Moolenaar  eval caught_1059->assert_equal(1)
1978ee4e0c1eSBram Moolenaarendfunc
19795deeb3f1SBram Moolenaar
1980015f4267SBram Moolenaarfunc DelMe()
1981015f4267SBram Moolenaar  echo 'DelMe'
1982015f4267SBram Moolenaarendfunc
1983015f4267SBram Moolenaar
1984bf8feb5aSBram Moolenaardef Test_error_reporting()
1985bf8feb5aSBram Moolenaar  # comment lines at the start of the function
19867a9cbca0SBram Moolenaar  var lines =<< trim END
1987bf8feb5aSBram Moolenaar    " comment
1988bf8feb5aSBram Moolenaar    def Func()
1989bf8feb5aSBram Moolenaar      # comment
1990bf8feb5aSBram Moolenaar      # comment
1991bf8feb5aSBram Moolenaar      invalid
1992bf8feb5aSBram Moolenaar    enddef
1993bf8feb5aSBram Moolenaar    defcompile
1994bf8feb5aSBram Moolenaar  END
199508052228SBram Moolenaar  writefile(lines, 'Xdef')
1996bf8feb5aSBram Moolenaar  try
1997bf8feb5aSBram Moolenaar    source Xdef
19987517ffdbSBram Moolenaar    assert_report('should have failed')
1999bf8feb5aSBram Moolenaar  catch /E476:/
2000c0c71e9dSBram Moolenaar    v:exception->assert_match('Invalid command: invalid')
2001c0c71e9dSBram Moolenaar    v:throwpoint->assert_match(', line 3$')
2002bf8feb5aSBram Moolenaar  endtry
20032d870f8dSBram Moolenaar  delfunc! g:Func
2004bf8feb5aSBram Moolenaar
2005bf8feb5aSBram Moolenaar  # comment lines after the start of the function
2006bf8feb5aSBram Moolenaar  lines =<< trim END
2007bf8feb5aSBram Moolenaar    " comment
2008bf8feb5aSBram Moolenaar    def Func()
20097a9cbca0SBram Moolenaar      var x = 1234
2010bf8feb5aSBram Moolenaar      # comment
2011bf8feb5aSBram Moolenaar      # comment
2012bf8feb5aSBram Moolenaar      invalid
2013bf8feb5aSBram Moolenaar    enddef
2014bf8feb5aSBram Moolenaar    defcompile
2015bf8feb5aSBram Moolenaar  END
201608052228SBram Moolenaar  writefile(lines, 'Xdef')
2017bf8feb5aSBram Moolenaar  try
2018bf8feb5aSBram Moolenaar    source Xdef
20197517ffdbSBram Moolenaar    assert_report('should have failed')
2020bf8feb5aSBram Moolenaar  catch /E476:/
2021c0c71e9dSBram Moolenaar    v:exception->assert_match('Invalid command: invalid')
2022c0c71e9dSBram Moolenaar    v:throwpoint->assert_match(', line 4$')
2023bf8feb5aSBram Moolenaar  endtry
20242d870f8dSBram Moolenaar  delfunc! g:Func
2025bf8feb5aSBram Moolenaar
20267517ffdbSBram Moolenaar  lines =<< trim END
20277517ffdbSBram Moolenaar    vim9script
20287517ffdbSBram Moolenaar    def Func()
2029e0de171eSBram Moolenaar      var db = {foo: 1, bar: 2}
20307517ffdbSBram Moolenaar      # comment
20317a9cbca0SBram Moolenaar      var x = db.asdf
20327517ffdbSBram Moolenaar    enddef
20337517ffdbSBram Moolenaar    defcompile
20347517ffdbSBram Moolenaar    Func()
20357517ffdbSBram Moolenaar  END
203608052228SBram Moolenaar  writefile(lines, 'Xdef')
20377517ffdbSBram Moolenaar  try
20387517ffdbSBram Moolenaar    source Xdef
20397517ffdbSBram Moolenaar    assert_report('should have failed')
20407517ffdbSBram Moolenaar  catch /E716:/
2041c0c71e9dSBram Moolenaar    v:throwpoint->assert_match('_Func, line 3$')
20427517ffdbSBram Moolenaar  endtry
20432d870f8dSBram Moolenaar  delfunc! g:Func
20447517ffdbSBram Moolenaar
204508052228SBram Moolenaar  delete('Xdef')
2046bf8feb5aSBram Moolenaarenddef
2047bf8feb5aSBram Moolenaar
2048015f4267SBram Moolenaardef Test_deleted_function()
2049015f4267SBram Moolenaar  CheckDefExecFailure([
20507a9cbca0SBram Moolenaar      'var RefMe: func = function("g:DelMe")',
2051015f4267SBram Moolenaar      'delfunc g:DelMe',
2052015f4267SBram Moolenaar      'echo RefMe()'], 'E117:')
2053015f4267SBram Moolenaarenddef
2054015f4267SBram Moolenaar
2055015f4267SBram Moolenaardef Test_unknown_function()
2056015f4267SBram Moolenaar  CheckDefExecFailure([
20577a9cbca0SBram Moolenaar      'var Ref: func = function("NotExist")',
20589b7bf9e9SBram Moolenaar      'delfunc g:NotExist'], 'E700:')
2059015f4267SBram Moolenaarenddef
2060015f4267SBram Moolenaar
2061328eac2bSBram Moolenaardef RefFunc(Ref: func(any): any): string
2062c8cd2b34SBram Moolenaar  return Ref('more')
2063c8cd2b34SBram Moolenaarenddef
2064c8cd2b34SBram Moolenaar
2065c8cd2b34SBram Moolenaardef Test_closure_simple()
20667a9cbca0SBram Moolenaar  var local = 'some '
20672949cfdbSBram Moolenaar  RefFunc((s) => local .. s)->assert_equal('some more')
2068c8cd2b34SBram Moolenaarenddef
2069c8cd2b34SBram Moolenaar
2070bf67ea1aSBram Moolenaardef MakeRef()
20717a9cbca0SBram Moolenaar  var local = 'some '
20722949cfdbSBram Moolenaar  g:Ref = (s) => local .. s
2073bf67ea1aSBram Moolenaarenddef
2074bf67ea1aSBram Moolenaar
2075bf67ea1aSBram Moolenaardef Test_closure_ref_after_return()
2076bf67ea1aSBram Moolenaar  MakeRef()
2077c0c71e9dSBram Moolenaar  g:Ref('thing')->assert_equal('some thing')
2078bf67ea1aSBram Moolenaar  unlet g:Ref
2079bf67ea1aSBram Moolenaarenddef
2080bf67ea1aSBram Moolenaar
20815adc55cbSBram Moolenaardef MakeTwoRefs()
20827a9cbca0SBram Moolenaar  var local = ['some']
20832949cfdbSBram Moolenaar  g:Extend = (s) => local->add(s)
20842949cfdbSBram Moolenaar  g:Read = () => local
20855adc55cbSBram Moolenaarenddef
20865adc55cbSBram Moolenaar
20875adc55cbSBram Moolenaardef Test_closure_two_refs()
20885adc55cbSBram Moolenaar  MakeTwoRefs()
2089c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some')
20905adc55cbSBram Moolenaar  g:Extend('more')
2091c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some more')
20925adc55cbSBram Moolenaar  g:Extend('even')
2093c0c71e9dSBram Moolenaar  join(g:Read(), ' ')->assert_equal('some more even')
20945adc55cbSBram Moolenaar
20955adc55cbSBram Moolenaar  unlet g:Extend
20965adc55cbSBram Moolenaar  unlet g:Read
20975adc55cbSBram Moolenaarenddef
20985adc55cbSBram Moolenaar
20995adc55cbSBram Moolenaardef ReadRef(Ref: func(): list<string>): string
21005adc55cbSBram Moolenaar  return join(Ref(), ' ')
21015adc55cbSBram Moolenaarenddef
21025adc55cbSBram Moolenaar
21035e654230SBram Moolenaardef ExtendRef(Ref: func(string): list<string>, add: string)
21045adc55cbSBram Moolenaar  Ref(add)
21055adc55cbSBram Moolenaarenddef
21065adc55cbSBram Moolenaar
21075adc55cbSBram Moolenaardef Test_closure_two_indirect_refs()
2108f7779c63SBram Moolenaar  MakeTwoRefs()
2109c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some')
21105adc55cbSBram Moolenaar  ExtendRef(g:Extend, 'more')
2111c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some more')
21125adc55cbSBram Moolenaar  ExtendRef(g:Extend, 'even')
2113c0c71e9dSBram Moolenaar  ReadRef(g:Read)->assert_equal('some more even')
21145adc55cbSBram Moolenaar
21155adc55cbSBram Moolenaar  unlet g:Extend
21165adc55cbSBram Moolenaar  unlet g:Read
21175adc55cbSBram Moolenaarenddef
2118bf67ea1aSBram Moolenaar
21192fd4cd75SBram Moolenaardef MakeArgRefs(theArg: string)
21207a9cbca0SBram Moolenaar  var local = 'loc_val'
21212949cfdbSBram Moolenaar  g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s
21222fd4cd75SBram Moolenaarenddef
21232fd4cd75SBram Moolenaar
21242fd4cd75SBram Moolenaardef MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
21257a9cbca0SBram Moolenaar  var local = 'the_loc'
21262949cfdbSBram Moolenaar  g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)
21272fd4cd75SBram Moolenaarenddef
21282fd4cd75SBram Moolenaar
21292fd4cd75SBram Moolenaardef Test_closure_using_argument()
21302fd4cd75SBram Moolenaar  MakeArgRefs('arg_val')
2131c0c71e9dSBram Moolenaar  g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
21322fd4cd75SBram Moolenaar
21332fd4cd75SBram Moolenaar  MakeArgRefsVarargs('arg_val', 'one', 'two')
2134c0c71e9dSBram Moolenaar  g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
21352fd4cd75SBram Moolenaar
21362fd4cd75SBram Moolenaar  unlet g:UseArg
21372fd4cd75SBram Moolenaar  unlet g:UseVararg
213844ec21c4SBram Moolenaar
213944ec21c4SBram Moolenaar  var lines =<< trim END
214044ec21c4SBram Moolenaar      vim9script
214144ec21c4SBram Moolenaar      def Test(Fun: func(number): number): list<number>
214244ec21c4SBram Moolenaar        return map([1, 2, 3], (_, i) => Fun(i))
214344ec21c4SBram Moolenaar      enddef
214444ec21c4SBram Moolenaar      def Inc(nr: number): number
214544ec21c4SBram Moolenaar        return nr + 2
214644ec21c4SBram Moolenaar      enddef
214744ec21c4SBram Moolenaar      assert_equal([3, 4, 5], Test(Inc))
214844ec21c4SBram Moolenaar  END
214944ec21c4SBram Moolenaar  CheckScriptSuccess(lines)
21502fd4cd75SBram Moolenaarenddef
21512fd4cd75SBram Moolenaar
215285d5e2b7SBram Moolenaardef MakeGetAndAppendRefs()
215385d5e2b7SBram Moolenaar  var local = 'a'
215485d5e2b7SBram Moolenaar
215585d5e2b7SBram Moolenaar  def Append(arg: string)
215685d5e2b7SBram Moolenaar    local ..= arg
215785d5e2b7SBram Moolenaar  enddef
215885d5e2b7SBram Moolenaar  g:Append = Append
215985d5e2b7SBram Moolenaar
216085d5e2b7SBram Moolenaar  def Get(): string
216185d5e2b7SBram Moolenaar    return local
216285d5e2b7SBram Moolenaar  enddef
216385d5e2b7SBram Moolenaar  g:Get = Get
216485d5e2b7SBram Moolenaarenddef
216585d5e2b7SBram Moolenaar
216685d5e2b7SBram Moolenaardef Test_closure_append_get()
216785d5e2b7SBram Moolenaar  MakeGetAndAppendRefs()
216885d5e2b7SBram Moolenaar  g:Get()->assert_equal('a')
216985d5e2b7SBram Moolenaar  g:Append('-b')
217085d5e2b7SBram Moolenaar  g:Get()->assert_equal('a-b')
217185d5e2b7SBram Moolenaar  g:Append('-c')
217285d5e2b7SBram Moolenaar  g:Get()->assert_equal('a-b-c')
217385d5e2b7SBram Moolenaar
217485d5e2b7SBram Moolenaar  unlet g:Append
217585d5e2b7SBram Moolenaar  unlet g:Get
217685d5e2b7SBram Moolenaarenddef
2177b68b346eSBram Moolenaar
217804b12697SBram Moolenaardef Test_nested_closure()
21797a9cbca0SBram Moolenaar  var local = 'text'
218004b12697SBram Moolenaar  def Closure(arg: string): string
218104b12697SBram Moolenaar    return local .. arg
218204b12697SBram Moolenaar  enddef
2183c0c71e9dSBram Moolenaar  Closure('!!!')->assert_equal('text!!!')
218404b12697SBram Moolenaarenddef
218504b12697SBram Moolenaar
21866f5b6dfbSBram Moolenaarfunc GetResult(Ref)
21876f5b6dfbSBram Moolenaar  return a:Ref('some')
21886f5b6dfbSBram Moolenaarendfunc
21896f5b6dfbSBram Moolenaar
21906f5b6dfbSBram Moolenaardef Test_call_closure_not_compiled()
21917a9cbca0SBram Moolenaar  var text = 'text'
21922949cfdbSBram Moolenaar  g:Ref = (s) =>  s .. text
2193c0c71e9dSBram Moolenaar  GetResult(g:Ref)->assert_equal('sometext')
21946f5b6dfbSBram Moolenaarenddef
21956f5b6dfbSBram Moolenaar
21967cbfaa51SBram Moolenaardef Test_double_closure_fails()
21977a9cbca0SBram Moolenaar  var lines =<< trim END
21987cbfaa51SBram Moolenaar    vim9script
21997cbfaa51SBram Moolenaar    def Func()
22007a9cbca0SBram Moolenaar      var name = 0
22017cbfaa51SBram Moolenaar      for i in range(2)
22022949cfdbSBram Moolenaar          timer_start(0, () => name)
22037cbfaa51SBram Moolenaar      endfor
22047cbfaa51SBram Moolenaar    enddef
22057cbfaa51SBram Moolenaar    Func()
22067cbfaa51SBram Moolenaar  END
2207148ce7aeSBram Moolenaar  CheckScriptSuccess(lines)
22087cbfaa51SBram Moolenaarenddef
22097cbfaa51SBram Moolenaar
221085d5e2b7SBram Moolenaardef Test_nested_closure_used()
221185d5e2b7SBram Moolenaar  var lines =<< trim END
221285d5e2b7SBram Moolenaar      vim9script
221385d5e2b7SBram Moolenaar      def Func()
221485d5e2b7SBram Moolenaar        var x = 'hello'
22152949cfdbSBram Moolenaar        var Closure = () => x
22162949cfdbSBram Moolenaar        g:Myclosure = () => Closure()
221785d5e2b7SBram Moolenaar      enddef
221885d5e2b7SBram Moolenaar      Func()
221985d5e2b7SBram Moolenaar      assert_equal('hello', g:Myclosure())
222085d5e2b7SBram Moolenaar  END
222185d5e2b7SBram Moolenaar  CheckScriptSuccess(lines)
222285d5e2b7SBram Moolenaarenddef
22230876c785SBram Moolenaar
2224c70bdab0SBram Moolenaardef Test_nested_closure_fails()
22257a9cbca0SBram Moolenaar  var lines =<< trim END
2226c70bdab0SBram Moolenaar    vim9script
2227c70bdab0SBram Moolenaar    def FuncA()
2228c70bdab0SBram Moolenaar      FuncB(0)
2229c70bdab0SBram Moolenaar    enddef
2230c70bdab0SBram Moolenaar    def FuncB(n: number): list<string>
22312949cfdbSBram Moolenaar      return map([0], (_, v) => n)
2232c70bdab0SBram Moolenaar    enddef
2233c70bdab0SBram Moolenaar    FuncA()
2234c70bdab0SBram Moolenaar  END
2235c70bdab0SBram Moolenaar  CheckScriptFailure(lines, 'E1012:')
2236c70bdab0SBram Moolenaarenddef
2237c70bdab0SBram Moolenaar
2238f112f30aSBram Moolenaardef Test_global_closure()
2239f112f30aSBram Moolenaar  var lines =<< trim END
2240f112f30aSBram Moolenaar      vim9script
2241f112f30aSBram Moolenaar      def ReverseEveryNLines(n: number, line1: number, line2: number)
2242f112f30aSBram Moolenaar        var mods = 'sil keepj keepp lockm '
2243f112f30aSBram Moolenaar        var range = ':' .. line1 .. ',' .. line2
2244f112f30aSBram Moolenaar        def g:Offset(): number
2245f112f30aSBram Moolenaar            var offset = (line('.') - line1 + 1) % n
2246f112f30aSBram Moolenaar            return offset != 0 ? offset : n
2247f112f30aSBram Moolenaar        enddef
2248f112f30aSBram Moolenaar        exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
2249f112f30aSBram Moolenaar      enddef
2250f112f30aSBram Moolenaar
2251f112f30aSBram Moolenaar      new
2252f112f30aSBram Moolenaar      repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1)
2253f112f30aSBram Moolenaar      ReverseEveryNLines(3, 1, 9)
2254f112f30aSBram Moolenaar  END
2255f112f30aSBram Moolenaar  CheckScriptSuccess(lines)
2256f112f30aSBram Moolenaar  var expected = repeat(['ccc', 'bbb', 'aaa'], 3)
2257f112f30aSBram Moolenaar  assert_equal(expected, getline(1, 9))
2258f112f30aSBram Moolenaar  bwipe!
2259f112f30aSBram Moolenaarenddef
2260f112f30aSBram Moolenaar
2261cd45ed03SBram Moolenaardef Test_global_closure_called_directly()
2262cd45ed03SBram Moolenaar  var lines =<< trim END
2263cd45ed03SBram Moolenaar      vim9script
2264cd45ed03SBram Moolenaar      def Outer()
2265cd45ed03SBram Moolenaar        var x = 1
2266cd45ed03SBram Moolenaar        def g:Inner()
2267cd45ed03SBram Moolenaar          var y = x
2268cd45ed03SBram Moolenaar          x += 1
2269cd45ed03SBram Moolenaar          assert_equal(1, y)
2270cd45ed03SBram Moolenaar        enddef
2271cd45ed03SBram Moolenaar        g:Inner()
2272cd45ed03SBram Moolenaar        assert_equal(2, x)
2273cd45ed03SBram Moolenaar      enddef
2274cd45ed03SBram Moolenaar      Outer()
2275cd45ed03SBram Moolenaar  END
2276cd45ed03SBram Moolenaar  CheckScriptSuccess(lines)
2277cd45ed03SBram Moolenaar  delfunc g:Inner
2278cd45ed03SBram Moolenaarenddef
2279cd45ed03SBram Moolenaar
228034c54eb6SBram Moolenaardef Test_failure_in_called_function()
228134c54eb6SBram Moolenaar  # this was using the frame index as the return value
228234c54eb6SBram Moolenaar  var lines =<< trim END
228334c54eb6SBram Moolenaar      vim9script
228434c54eb6SBram Moolenaar      au TerminalWinOpen * eval [][0]
228534c54eb6SBram Moolenaar      def PopupTerm(a: any)
228634c54eb6SBram Moolenaar        # make sure typvals on stack are string
228734c54eb6SBram Moolenaar        ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join()
228834c54eb6SBram Moolenaar        FireEvent()
228934c54eb6SBram Moolenaar      enddef
229034c54eb6SBram Moolenaar      def FireEvent()
229134c54eb6SBram Moolenaar          do TerminalWinOpen
229234c54eb6SBram Moolenaar      enddef
229334c54eb6SBram Moolenaar      # use try/catch to make eval fail
229434c54eb6SBram Moolenaar      try
229534c54eb6SBram Moolenaar          call PopupTerm(0)
229634c54eb6SBram Moolenaar      catch
229734c54eb6SBram Moolenaar      endtry
229834c54eb6SBram Moolenaar      au! TerminalWinOpen
229934c54eb6SBram Moolenaar  END
230034c54eb6SBram Moolenaar  CheckScriptSuccess(lines)
230134c54eb6SBram Moolenaarenddef
230234c54eb6SBram Moolenaar
23035366e1aeSBram Moolenaardef Test_nested_lambda()
23045366e1aeSBram Moolenaar  var lines =<< trim END
23055366e1aeSBram Moolenaar    vim9script
23065366e1aeSBram Moolenaar    def Func()
23075366e1aeSBram Moolenaar      var x = 4
23082949cfdbSBram Moolenaar      var Lambda1 = () => 7
23092949cfdbSBram Moolenaar      var Lambda2 = () => [Lambda1(), x]
23105366e1aeSBram Moolenaar      var res = Lambda2()
23115366e1aeSBram Moolenaar      assert_equal([7, 4], res)
23125366e1aeSBram Moolenaar    enddef
23135366e1aeSBram Moolenaar    Func()
23145366e1aeSBram Moolenaar  END
23155366e1aeSBram Moolenaar  CheckScriptSuccess(lines)
23165366e1aeSBram Moolenaarenddef
23175366e1aeSBram Moolenaar
2318c04f2a4cSBram Moolenaardef Test_double_nested_lambda()
2319c04f2a4cSBram Moolenaar  var lines =<< trim END
2320c04f2a4cSBram Moolenaar      vim9script
2321c04f2a4cSBram Moolenaar      def F(head: string): func(string): func(string): string
2322c04f2a4cSBram Moolenaar        return (sep: string): func(string): string => ((tail: string): string => {
2323c04f2a4cSBram Moolenaar            return head .. sep .. tail
2324c04f2a4cSBram Moolenaar          })
2325c04f2a4cSBram Moolenaar      enddef
2326c04f2a4cSBram Moolenaar      assert_equal('hello-there', F('hello')('-')('there'))
2327c04f2a4cSBram Moolenaar  END
2328c04f2a4cSBram Moolenaar  CheckScriptSuccess(lines)
2329c04f2a4cSBram Moolenaarenddef
2330c04f2a4cSBram Moolenaar
2331074f84c0SBram Moolenaardef Test_nested_inline_lambda()
2332074f84c0SBram Moolenaar  var lines =<< trim END
2333074f84c0SBram Moolenaar      vim9script
2334074f84c0SBram Moolenaar      def F(text: string): func(string): func(string): string
2335074f84c0SBram Moolenaar        return (arg: string): func(string): string => ((sep: string): string => {
233623e2e115SBram Moolenaar            return sep .. arg .. text
2337074f84c0SBram Moolenaar          })
2338074f84c0SBram Moolenaar      enddef
233923e2e115SBram Moolenaar      assert_equal('--there++', F('++')('there')('--'))
2340074f84c0SBram Moolenaar  END
2341074f84c0SBram Moolenaar  CheckScriptSuccess(lines)
23425245beb3SBram Moolenaar
23435245beb3SBram Moolenaar  lines =<< trim END
23445245beb3SBram Moolenaar      vim9script
23455245beb3SBram Moolenaar      echo range(4)->mapnew((_, v) => {
23465245beb3SBram Moolenaar        return range(v) ->mapnew((_, s) => {
23475245beb3SBram Moolenaar          return string(s)
23485245beb3SBram Moolenaar          })
23495245beb3SBram Moolenaar        })
23505245beb3SBram Moolenaar  END
23515245beb3SBram Moolenaar  CheckScriptSuccess(lines)
2352c6ba2f9dSBram Moolenaar
2353c6ba2f9dSBram Moolenaar  lines =<< trim END
2354c6ba2f9dSBram Moolenaar      vim9script
2355c6ba2f9dSBram Moolenaar
2356c6ba2f9dSBram Moolenaar      def s:func()
2357c6ba2f9dSBram Moolenaar        range(10)
2358c6ba2f9dSBram Moolenaar          ->mapnew((_, _) => ({
2359c6ba2f9dSBram Moolenaar            key: range(10)->mapnew((_, _) => {
2360c6ba2f9dSBram Moolenaar              return ' '
2361c6ba2f9dSBram Moolenaar            }),
2362c6ba2f9dSBram Moolenaar          }))
2363c6ba2f9dSBram Moolenaar      enddef
2364c6ba2f9dSBram Moolenaar
2365c6ba2f9dSBram Moolenaar      defcomp
2366c6ba2f9dSBram Moolenaar  END
2367c6ba2f9dSBram Moolenaar  CheckScriptSuccess(lines)
2368074f84c0SBram Moolenaarenddef
2369074f84c0SBram Moolenaar
237052bf81c2SBram Moolenaardef Shadowed(): list<number>
23712949cfdbSBram Moolenaar  var FuncList: list<func: number> = [() => 42]
237275ab91ffSBram Moolenaar  return FuncList->mapnew((_, Shadowed) => Shadowed())
237352bf81c2SBram Moolenaarenddef
237452bf81c2SBram Moolenaar
237552bf81c2SBram Moolenaardef Test_lambda_arg_shadows_func()
237652bf81c2SBram Moolenaar  assert_equal([42], Shadowed())
237752bf81c2SBram Moolenaarenddef
237852bf81c2SBram Moolenaar
2379acd4c5e9SBram Moolenaardef Line_continuation_in_def(dir: string = ''): string
23807a9cbca0SBram Moolenaar  var path: string = empty(dir)
2381acd4c5e9SBram Moolenaar          \ ? 'empty'
2382acd4c5e9SBram Moolenaar          \ : 'full'
2383acd4c5e9SBram Moolenaar  return path
2384acd4c5e9SBram Moolenaarenddef
2385acd4c5e9SBram Moolenaar
2386acd4c5e9SBram Moolenaardef Test_line_continuation_in_def()
2387c0c71e9dSBram Moolenaar  Line_continuation_in_def('.')->assert_equal('full')
2388acd4c5e9SBram Moolenaarenddef
2389acd4c5e9SBram Moolenaar
23902ea95b61SBram Moolenaardef Test_script_var_in_lambda()
23912ea95b61SBram Moolenaar  var lines =<< trim END
23922ea95b61SBram Moolenaar      vim9script
23932ea95b61SBram Moolenaar      var script = 'test'
2394bb8a7ce0SBram Moolenaar      assert_equal(['test'], map(['one'], (_, _) => script))
23952ea95b61SBram Moolenaar  END
23962ea95b61SBram Moolenaar  CheckScriptSuccess(lines)
23972ea95b61SBram Moolenaarenddef
23982ea95b61SBram Moolenaar
23995e654230SBram Moolenaardef Line_continuation_in_lambda(): list<string>
24007a9cbca0SBram Moolenaar  var x = range(97, 100)
240175ab91ffSBram Moolenaar      ->mapnew((_, v) => nr2char(v)
24022949cfdbSBram Moolenaar          ->toupper())
24037a4b8980SBram Moolenaar      ->reverse()
24047a4b8980SBram Moolenaar  return x
24057a4b8980SBram Moolenaarenddef
24067a4b8980SBram Moolenaar
24077a4b8980SBram Moolenaardef Test_line_continuation_in_lambda()
2408c0c71e9dSBram Moolenaar  Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
2409f898f7c6SBram Moolenaar
2410f898f7c6SBram Moolenaar  var lines =<< trim END
2411f898f7c6SBram Moolenaar      vim9script
2412f898f7c6SBram Moolenaar      var res = [{n: 1, m: 2, s: 'xxx'}]
2413f898f7c6SBram Moolenaar                ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s',
2414f898f7c6SBram Moolenaar                    v.n,
2415f898f7c6SBram Moolenaar                    v.m,
2416f898f7c6SBram Moolenaar                    substitute(v.s, '.*', 'yyy', '')
2417f898f7c6SBram Moolenaar                    ))
2418f898f7c6SBram Moolenaar      assert_equal(['1:2:yyy'], res)
2419f898f7c6SBram Moolenaar  END
2420f898f7c6SBram Moolenaar  CheckScriptSuccess(lines)
24217a4b8980SBram Moolenaarenddef
24227a4b8980SBram Moolenaar
2423b657198cSBram Moolenaardef Test_list_lambda()
2424b657198cSBram Moolenaar  timer_start(1000, (_) => 0)
2425b657198cSBram Moolenaar  var body = execute(timer_info()[0].callback
2426b657198cSBram Moolenaar         ->string()
2427b657198cSBram Moolenaar         ->substitute("('", ' ', '')
2428b657198cSBram Moolenaar         ->substitute("')", '', '')
2429b657198cSBram Moolenaar         ->substitute('function\zs', ' ', ''))
2430767034c5SBram Moolenaar  assert_match('def <lambda>\d\+(_: any): number\n1  return 0\n   enddef', body)
2431b657198cSBram Moolenaarenddef
2432b657198cSBram Moolenaar
24333c77b6a1SBram Moolenaardef Test_lambda_block_variable()
243488421d6dSBram Moolenaar  var lines =<< trim END
243588421d6dSBram Moolenaar      vim9script
243688421d6dSBram Moolenaar      var flist: list<func>
243788421d6dSBram Moolenaar      for i in range(10)
243888421d6dSBram Moolenaar          var inloop = i
243988421d6dSBram Moolenaar          flist[i] = () => inloop
244088421d6dSBram Moolenaar      endfor
244188421d6dSBram Moolenaar  END
244288421d6dSBram Moolenaar  CheckScriptSuccess(lines)
244388421d6dSBram Moolenaar
244488421d6dSBram Moolenaar  lines =<< trim END
244588421d6dSBram Moolenaar      vim9script
244688421d6dSBram Moolenaar      if true
244788421d6dSBram Moolenaar        var outloop = 5
244888421d6dSBram Moolenaar        var flist: list<func>
244988421d6dSBram Moolenaar        for i in range(10)
245088421d6dSBram Moolenaar          flist[i] = () => outloop
245188421d6dSBram Moolenaar        endfor
245288421d6dSBram Moolenaar      endif
245388421d6dSBram Moolenaar  END
245488421d6dSBram Moolenaar  CheckScriptSuccess(lines)
245588421d6dSBram Moolenaar
245688421d6dSBram Moolenaar  lines =<< trim END
245788421d6dSBram Moolenaar      vim9script
245888421d6dSBram Moolenaar      if true
245988421d6dSBram Moolenaar        var outloop = 5
246088421d6dSBram Moolenaar      endif
246188421d6dSBram Moolenaar      var flist: list<func>
246288421d6dSBram Moolenaar      for i in range(10)
246388421d6dSBram Moolenaar        flist[i] = () => outloop
246488421d6dSBram Moolenaar      endfor
246588421d6dSBram Moolenaar  END
246688421d6dSBram Moolenaar  CheckScriptFailure(lines, 'E1001: Variable not found: outloop', 1)
24673c77b6a1SBram Moolenaar
24683c77b6a1SBram Moolenaar  lines =<< trim END
24693c77b6a1SBram Moolenaar      vim9script
24703c77b6a1SBram Moolenaar      for i in range(10)
24713c77b6a1SBram Moolenaar        var Ref = () => 0
24723c77b6a1SBram Moolenaar      endfor
24733c77b6a1SBram Moolenaar      assert_equal(0, ((i) => 0)(0))
24743c77b6a1SBram Moolenaar  END
24753c77b6a1SBram Moolenaar  CheckScriptSuccess(lines)
247688421d6dSBram Moolenaarenddef
247788421d6dSBram Moolenaar
247896cf4ba8SBram Moolenaardef Test_legacy_lambda()
247996cf4ba8SBram Moolenaar  legacy echo {x -> 'hello ' .. x}('foo')
2480dc4c2309SBram Moolenaar
248196cf4ba8SBram Moolenaar  var lines =<< trim END
248296cf4ba8SBram Moolenaar      echo {x -> 'hello ' .. x}('foo')
248396cf4ba8SBram Moolenaar  END
248496cf4ba8SBram Moolenaar  CheckDefAndScriptFailure(lines, 'E720:')
2485dc4c2309SBram Moolenaar
2486dc4c2309SBram Moolenaar  lines =<< trim END
2487dc4c2309SBram Moolenaar      vim9script
2488dc4c2309SBram Moolenaar      def Func()
2489dc4c2309SBram Moolenaar        echo (() => 'no error')()
2490dc4c2309SBram Moolenaar      enddef
2491dc4c2309SBram Moolenaar      legacy call s:Func()
2492dc4c2309SBram Moolenaar  END
2493dc4c2309SBram Moolenaar  CheckScriptSuccess(lines)
249496cf4ba8SBram Moolenaarenddef
249596cf4ba8SBram Moolenaar
2496ce024c3eSBram Moolenaardef Test_legacy()
2497ce024c3eSBram Moolenaar  var lines =<< trim END
2498ce024c3eSBram Moolenaar      vim9script
2499ce024c3eSBram Moolenaar      func g:LegacyFunction()
2500ce024c3eSBram Moolenaar        let g:legacyvar = 1
2501ce024c3eSBram Moolenaar      endfunc
2502ce024c3eSBram Moolenaar      def Testit()
2503ce024c3eSBram Moolenaar        legacy call g:LegacyFunction()
2504ce024c3eSBram Moolenaar      enddef
2505ce024c3eSBram Moolenaar      Testit()
2506ce024c3eSBram Moolenaar      assert_equal(1, g:legacyvar)
2507ce024c3eSBram Moolenaar      unlet g:legacyvar
2508ce024c3eSBram Moolenaar      delfunc g:LegacyFunction
2509ce024c3eSBram Moolenaar  END
2510ce024c3eSBram Moolenaar  CheckScriptSuccess(lines)
2511ce024c3eSBram Moolenaarenddef
2512ce024c3eSBram Moolenaar
2513c3cb1c92SBram Moolenaardef Test_legacy_errors()
2514c3cb1c92SBram Moolenaar  for cmd in ['if', 'elseif', 'else', 'endif',
2515c3cb1c92SBram Moolenaar              'for', 'endfor', 'continue', 'break',
2516c3cb1c92SBram Moolenaar              'while', 'endwhile',
2517c3cb1c92SBram Moolenaar              'try', 'catch', 'finally', 'endtry']
2518c3cb1c92SBram Moolenaar    CheckDefFailure(['legacy ' .. cmd .. ' expr'], 'E1189:')
2519c3cb1c92SBram Moolenaar  endfor
2520c3cb1c92SBram Moolenaarenddef
2521c3cb1c92SBram Moolenaar
2522ab360526SBram Moolenaardef DoFilterThis(a: string): list<string>
2523ab360526SBram Moolenaar  # closure nested inside another closure using argument
2524ab360526SBram Moolenaar  var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0)
2525ab360526SBram Moolenaar  return ['x', 'y', 'a', 'x2', 'c']->Filter()
2526ab360526SBram Moolenaarenddef
2527ab360526SBram Moolenaar
2528ab360526SBram Moolenaardef Test_nested_closure_using_argument()
2529ab360526SBram Moolenaar  assert_equal(['x', 'x2'], DoFilterThis('x'))
2530ab360526SBram Moolenaarenddef
2531ab360526SBram Moolenaar
25320186e586SBram Moolenaardef Test_triple_nested_closure()
25330186e586SBram Moolenaar  var what = 'x'
25340186e586SBram Moolenaar  var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0
25350186e586SBram Moolenaar  var Filter = (l) => filter(l, (_, v) => Match(v, what))
25360186e586SBram Moolenaar  assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter())
25370186e586SBram Moolenaarenddef
25380186e586SBram Moolenaar
25398f510afcSBram Moolenaarfunc Test_silent_echo()
254047e7d70bSBram Moolenaar  CheckScreendump
254147e7d70bSBram Moolenaar
254247e7d70bSBram Moolenaar  let lines =<< trim END
254347e7d70bSBram Moolenaar    vim9script
254447e7d70bSBram Moolenaar    def EchoNothing()
254547e7d70bSBram Moolenaar      silent echo ''
254647e7d70bSBram Moolenaar    enddef
254747e7d70bSBram Moolenaar    defcompile
254847e7d70bSBram Moolenaar  END
25498f510afcSBram Moolenaar  call writefile(lines, 'XTest_silent_echo')
255047e7d70bSBram Moolenaar
255147e7d70bSBram Moolenaar  " Check that the balloon shows up after a mouse move
255247e7d70bSBram Moolenaar  let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
25538f510afcSBram Moolenaar  call term_sendkeys(buf, ":abc")
255447e7d70bSBram Moolenaar  call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
255547e7d70bSBram Moolenaar
255647e7d70bSBram Moolenaar  " clean up
255747e7d70bSBram Moolenaar  call StopVimInTerminal(buf)
255847e7d70bSBram Moolenaar  call delete('XTest_silent_echo')
25598f510afcSBram Moolenaarendfunc
256047e7d70bSBram Moolenaar
2561171fb923SBram Moolenaardef SilentlyError()
2562171fb923SBram Moolenaar  execute('silent! invalid')
2563171fb923SBram Moolenaar  g:did_it = 'yes'
2564171fb923SBram Moolenaarenddef
2565171fb923SBram Moolenaar
256628ee892aSBram Moolenaarfunc UserError()
256728ee892aSBram Moolenaar  silent! invalid
256828ee892aSBram Moolenaarendfunc
256928ee892aSBram Moolenaar
257028ee892aSBram Moolenaardef SilentlyUserError()
257128ee892aSBram Moolenaar  UserError()
257228ee892aSBram Moolenaar  g:did_it = 'yes'
257328ee892aSBram Moolenaarenddef
2574171fb923SBram Moolenaar
2575171fb923SBram Moolenaar" This can't be a :def function, because the assert would not be reached.
2576171fb923SBram Moolenaarfunc Test_ignore_silent_error()
2577171fb923SBram Moolenaar  let g:did_it = 'no'
2578171fb923SBram Moolenaar  call SilentlyError()
2579171fb923SBram Moolenaar  call assert_equal('yes', g:did_it)
2580171fb923SBram Moolenaar
258128ee892aSBram Moolenaar  let g:did_it = 'no'
258228ee892aSBram Moolenaar  call SilentlyUserError()
258328ee892aSBram Moolenaar  call assert_equal('yes', g:did_it)
2584171fb923SBram Moolenaar
2585171fb923SBram Moolenaar  unlet g:did_it
2586171fb923SBram Moolenaarendfunc
2587171fb923SBram Moolenaar
2588cd030c4bSBram Moolenaardef Test_ignore_silent_error_in_filter()
2589cd030c4bSBram Moolenaar  var lines =<< trim END
2590cd030c4bSBram Moolenaar      vim9script
2591cd030c4bSBram Moolenaar      def Filter(winid: number, key: string): bool
2592cd030c4bSBram Moolenaar          if key == 'o'
2593cd030c4bSBram Moolenaar              silent! eval [][0]
2594cd030c4bSBram Moolenaar              return true
2595cd030c4bSBram Moolenaar          endif
2596cd030c4bSBram Moolenaar          return popup_filter_menu(winid, key)
2597cd030c4bSBram Moolenaar      enddef
2598cd030c4bSBram Moolenaar
2599e0de171eSBram Moolenaar      popup_create('popup', {filter: Filter})
2600cd030c4bSBram Moolenaar      feedkeys("o\r", 'xnt')
2601cd030c4bSBram Moolenaar  END
2602cd030c4bSBram Moolenaar  CheckScriptSuccess(lines)
2603cd030c4bSBram Moolenaarenddef
2604cd030c4bSBram Moolenaar
26054b9bd692SBram Moolenaardef Fibonacci(n: number): number
26064b9bd692SBram Moolenaar  if n < 2
26074b9bd692SBram Moolenaar    return n
26084b9bd692SBram Moolenaar  else
26094b9bd692SBram Moolenaar    return Fibonacci(n - 1) + Fibonacci(n - 2)
26104b9bd692SBram Moolenaar  endif
26114b9bd692SBram Moolenaarenddef
26124b9bd692SBram Moolenaar
2613985116aeSBram Moolenaardef Test_recursive_call()
2614c0c71e9dSBram Moolenaar  Fibonacci(20)->assert_equal(6765)
2615985116aeSBram Moolenaarenddef
2616985116aeSBram Moolenaar
261708f7a41bSBram Moolenaardef TreeWalk(dir: string): list<any>
261875ab91ffSBram Moolenaar  return readdir(dir)->mapnew((_, val) =>
261908f7a41bSBram Moolenaar            fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
26202bede173SBram Moolenaar               ? {[val]: TreeWalk(dir .. '/' .. val)}
262108f7a41bSBram Moolenaar               : val
26222949cfdbSBram Moolenaar             )
262308f7a41bSBram Moolenaarenddef
262408f7a41bSBram Moolenaar
262508f7a41bSBram Moolenaardef Test_closure_in_map()
262608f7a41bSBram Moolenaar  mkdir('XclosureDir/tdir', 'p')
262708f7a41bSBram Moolenaar  writefile(['111'], 'XclosureDir/file1')
262808f7a41bSBram Moolenaar  writefile(['222'], 'XclosureDir/file2')
262908f7a41bSBram Moolenaar  writefile(['333'], 'XclosureDir/tdir/file3')
263008f7a41bSBram Moolenaar
2631e0de171eSBram Moolenaar  TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}])
263208f7a41bSBram Moolenaar
263308f7a41bSBram Moolenaar  delete('XclosureDir', 'rf')
263408f7a41bSBram Moolenaarenddef
263508f7a41bSBram Moolenaar
26367b5d5442SBram Moolenaardef Test_invalid_function_name()
26377b5d5442SBram Moolenaar  var lines =<< trim END
26387b5d5442SBram Moolenaar      vim9script
26397b5d5442SBram Moolenaar      def s: list<string>
26407b5d5442SBram Moolenaar  END
26417b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E129:')
26427b5d5442SBram Moolenaar
26437b5d5442SBram Moolenaar  lines =<< trim END
26447b5d5442SBram Moolenaar      vim9script
26457b5d5442SBram Moolenaar      def g: list<string>
26467b5d5442SBram Moolenaar  END
26477b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E129:')
26487b5d5442SBram Moolenaar
26497b5d5442SBram Moolenaar  lines =<< trim END
26507b5d5442SBram Moolenaar      vim9script
26517b5d5442SBram Moolenaar      def <SID>: list<string>
26527b5d5442SBram Moolenaar  END
26537b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E884:')
26547b5d5442SBram Moolenaar
26557b5d5442SBram Moolenaar  lines =<< trim END
26567b5d5442SBram Moolenaar      vim9script
26577b5d5442SBram Moolenaar      def F list<string>
26587b5d5442SBram Moolenaar  END
26597b5d5442SBram Moolenaar  CheckScriptFailure(lines, 'E488:')
26607b5d5442SBram Moolenaarenddef
26617b5d5442SBram Moolenaar
2662a90afb9aSBram Moolenaardef Test_partial_call()
2663f78da4f9SBram Moolenaar  var lines =<< trim END
2664f78da4f9SBram Moolenaar      var Xsetlist: func
2665f78da4f9SBram Moolenaar      Xsetlist = function('setloclist', [0])
2666e0de171eSBram Moolenaar      Xsetlist([], ' ', {title: 'test'})
2667e0de171eSBram Moolenaar      getloclist(0, {title: 1})->assert_equal({title: 'test'})
2668a90afb9aSBram Moolenaar
2669a90afb9aSBram Moolenaar      Xsetlist = function('setloclist', [0, [], ' '])
2670e0de171eSBram Moolenaar      Xsetlist({title: 'test'})
2671e0de171eSBram Moolenaar      getloclist(0, {title: 1})->assert_equal({title: 'test'})
2672a90afb9aSBram Moolenaar
2673a90afb9aSBram Moolenaar      Xsetlist = function('setqflist')
2674e0de171eSBram Moolenaar      Xsetlist([], ' ', {title: 'test'})
2675e0de171eSBram Moolenaar      getqflist({title: 1})->assert_equal({title: 'test'})
2676a90afb9aSBram Moolenaar
2677a90afb9aSBram Moolenaar      Xsetlist = function('setqflist', [[], ' '])
2678e0de171eSBram Moolenaar      Xsetlist({title: 'test'})
2679e0de171eSBram Moolenaar      getqflist({title: 1})->assert_equal({title: 'test'})
26806abd3dc2SBram Moolenaar
26816abd3dc2SBram Moolenaar      var Len: func: number = function('len', ['word'])
26826abd3dc2SBram Moolenaar      assert_equal(4, Len())
2683f78da4f9SBram Moolenaar
2684f78da4f9SBram Moolenaar      var RepeatFunc = function('repeat', ['o'])
2685f78da4f9SBram Moolenaar      assert_equal('ooooo', RepeatFunc(5))
2686f78da4f9SBram Moolenaar  END
2687f78da4f9SBram Moolenaar  CheckDefAndScriptSuccess(lines)
2688a90afb9aSBram Moolenaarenddef
2689a90afb9aSBram Moolenaar
26902dd0a2c3SBram Moolenaardef Test_cmd_modifier()
26912dd0a2c3SBram Moolenaar  tab echo '0'
2692d2c61705SBram Moolenaar  CheckDefFailure(['5tab echo 3'], 'E16:')
26932dd0a2c3SBram Moolenaarenddef
26942dd0a2c3SBram Moolenaar
26952dd0a2c3SBram Moolenaardef Test_restore_modifiers()
26962dd0a2c3SBram Moolenaar  # check that when compiling a :def function command modifiers are not messed
26972dd0a2c3SBram Moolenaar  # up.
26987a9cbca0SBram Moolenaar  var lines =<< trim END
26992dd0a2c3SBram Moolenaar      vim9script
27002dd0a2c3SBram Moolenaar      set eventignore=
27012dd0a2c3SBram Moolenaar      autocmd QuickFixCmdPost * copen
27022dd0a2c3SBram Moolenaar      def AutocmdsDisabled()
2703c323527dSBram Moolenaar        eval 1 + 2
27042dd0a2c3SBram Moolenaar      enddef
27052dd0a2c3SBram Moolenaar      func Func()
27062dd0a2c3SBram Moolenaar        noautocmd call s:AutocmdsDisabled()
27072dd0a2c3SBram Moolenaar        let g:ei_after = &eventignore
27082dd0a2c3SBram Moolenaar      endfunc
27092dd0a2c3SBram Moolenaar      Func()
27102dd0a2c3SBram Moolenaar  END
27112dd0a2c3SBram Moolenaar  CheckScriptSuccess(lines)
2712c0c71e9dSBram Moolenaar  g:ei_after->assert_equal('')
27132dd0a2c3SBram Moolenaarenddef
27142dd0a2c3SBram Moolenaar
2715dfa3d552SBram Moolenaardef StackTop()
2716c323527dSBram Moolenaar  eval 1 + 2
2717c323527dSBram Moolenaar  eval 2 + 3
2718dfa3d552SBram Moolenaar  # call not on fourth line
2719dfa3d552SBram Moolenaar  StackBot()
2720dfa3d552SBram Moolenaarenddef
2721dfa3d552SBram Moolenaar
2722dfa3d552SBram Moolenaardef StackBot()
2723dfa3d552SBram Moolenaar  # throw an error
2724dfa3d552SBram Moolenaar  eval [][0]
2725dfa3d552SBram Moolenaarenddef
2726dfa3d552SBram Moolenaar
2727dfa3d552SBram Moolenaardef Test_callstack_def()
2728dfa3d552SBram Moolenaar  try
2729dfa3d552SBram Moolenaar    StackTop()
2730dfa3d552SBram Moolenaar  catch
2731c0c71e9dSBram Moolenaar    v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
2732dfa3d552SBram Moolenaar  endtry
2733dfa3d552SBram Moolenaarenddef
2734dfa3d552SBram Moolenaar
2735e8211a33SBram Moolenaar" Re-using spot for variable used in block
2736e8211a33SBram Moolenaardef Test_block_scoped_var()
2737e8211a33SBram Moolenaar  var lines =<< trim END
2738e8211a33SBram Moolenaar      vim9script
2739e8211a33SBram Moolenaar      def Func()
2740e8211a33SBram Moolenaar        var x = ['a', 'b', 'c']
2741e8211a33SBram Moolenaar        if 1
2742e8211a33SBram Moolenaar          var y = 'x'
2743bb8a7ce0SBram Moolenaar          map(x, (_, _) => y)
2744e8211a33SBram Moolenaar        endif
2745e8211a33SBram Moolenaar        var z = x
2746e8211a33SBram Moolenaar        assert_equal(['x', 'x', 'x'], z)
2747e8211a33SBram Moolenaar      enddef
2748e8211a33SBram Moolenaar      Func()
2749e8211a33SBram Moolenaar  END
2750e8211a33SBram Moolenaar  CheckScriptSuccess(lines)
2751e8211a33SBram Moolenaarenddef
2752e8211a33SBram Moolenaar
2753eeece9e4SBram Moolenaardef Test_reset_did_emsg()
2754eeece9e4SBram Moolenaar  var lines =<< trim END
2755eeece9e4SBram Moolenaar      @s = 'blah'
2756eeece9e4SBram Moolenaar      au BufWinLeave * #
2757eeece9e4SBram Moolenaar      def Func()
2758eeece9e4SBram Moolenaar        var winid = popup_create('popup', {})
2759eeece9e4SBram Moolenaar        exe '*s'
2760eeece9e4SBram Moolenaar        popup_close(winid)
2761eeece9e4SBram Moolenaar      enddef
2762eeece9e4SBram Moolenaar      Func()
2763eeece9e4SBram Moolenaar  END
2764eeece9e4SBram Moolenaar  CheckScriptFailure(lines, 'E492:', 8)
27652d870f8dSBram Moolenaar  delfunc! g:Func
2766eeece9e4SBram Moolenaarenddef
2767eeece9e4SBram Moolenaar
276857f799e6SBram Moolenaardef Test_did_emsg_reset()
276957f799e6SBram Moolenaar  # executing an autocommand resets did_emsg, this should not result in a
277057f799e6SBram Moolenaar  # builtin function considered failing
277157f799e6SBram Moolenaar  var lines =<< trim END
277257f799e6SBram Moolenaar      vim9script
277357f799e6SBram Moolenaar      au BufWinLeave * #
277457f799e6SBram Moolenaar      def Func()
2775767034c5SBram Moolenaar          popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()})
277657f799e6SBram Moolenaar          eval [][0]
277757f799e6SBram Moolenaar      enddef
277857f799e6SBram Moolenaar      nno <F3> <cmd>call <sid>Func()<cr>
277957f799e6SBram Moolenaar      feedkeys("\<F3>\e", 'xt')
278057f799e6SBram Moolenaar  END
278157f799e6SBram Moolenaar  writefile(lines, 'XemsgReset')
278257f799e6SBram Moolenaar  assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2)
278357f799e6SBram Moolenaar  delete('XemsgReset')
278457f799e6SBram Moolenaar  nunmap <F3>
278557f799e6SBram Moolenaar  au! BufWinLeave
278657f799e6SBram Moolenaarenddef
278757f799e6SBram Moolenaar
278856602ba1SBram Moolenaardef Test_abort_with_silent_call()
278956602ba1SBram Moolenaar  var lines =<< trim END
279056602ba1SBram Moolenaar      vim9script
279156602ba1SBram Moolenaar      g:result = 'none'
279256602ba1SBram Moolenaar      def Func()
279356602ba1SBram Moolenaar        g:result += 3
279456602ba1SBram Moolenaar        g:result = 'yes'
279556602ba1SBram Moolenaar      enddef
279656602ba1SBram Moolenaar      # error is silenced, but function aborts on error
279756602ba1SBram Moolenaar      silent! Func()
279856602ba1SBram Moolenaar      assert_equal('none', g:result)
279956602ba1SBram Moolenaar      unlet g:result
280056602ba1SBram Moolenaar  END
280156602ba1SBram Moolenaar  CheckScriptSuccess(lines)
280256602ba1SBram Moolenaarenddef
280356602ba1SBram Moolenaar
2804f665e97fSBram Moolenaardef Test_continues_with_silent_error()
2805f665e97fSBram Moolenaar  var lines =<< trim END
2806f665e97fSBram Moolenaar      vim9script
2807f665e97fSBram Moolenaar      g:result = 'none'
2808f665e97fSBram Moolenaar      def Func()
2809f665e97fSBram Moolenaar        silent!  g:result += 3
2810f665e97fSBram Moolenaar        g:result = 'yes'
2811f665e97fSBram Moolenaar      enddef
2812f665e97fSBram Moolenaar      # error is silenced, function does not abort
2813f665e97fSBram Moolenaar      Func()
2814f665e97fSBram Moolenaar      assert_equal('yes', g:result)
2815f665e97fSBram Moolenaar      unlet g:result
2816f665e97fSBram Moolenaar  END
2817f665e97fSBram Moolenaar  CheckScriptSuccess(lines)
2818f665e97fSBram Moolenaarenddef
2819f665e97fSBram Moolenaar
2820af0df47aSBram Moolenaardef Test_abort_even_with_silent()
2821af0df47aSBram Moolenaar  var lines =<< trim END
2822af0df47aSBram Moolenaar      vim9script
2823af0df47aSBram Moolenaar      g:result = 'none'
2824af0df47aSBram Moolenaar      def Func()
2825af0df47aSBram Moolenaar        eval {-> ''}() .. '' .. {}['X']
2826af0df47aSBram Moolenaar        g:result = 'yes'
2827af0df47aSBram Moolenaar      enddef
2828f665e97fSBram Moolenaar      silent! Func()
2829af0df47aSBram Moolenaar      assert_equal('none', g:result)
28304029cabbSBram Moolenaar      unlet g:result
28314029cabbSBram Moolenaar  END
28324029cabbSBram Moolenaar  CheckScriptSuccess(lines)
28334029cabbSBram Moolenaarenddef
28344029cabbSBram Moolenaar
2835f665e97fSBram Moolenaardef Test_cmdmod_silent_restored()
2836f665e97fSBram Moolenaar  var lines =<< trim END
2837f665e97fSBram Moolenaar      vim9script
2838f665e97fSBram Moolenaar      def Func()
2839f665e97fSBram Moolenaar        g:result = 'none'
2840f665e97fSBram Moolenaar        silent! g:result += 3
2841f665e97fSBram Moolenaar        g:result = 'none'
2842f665e97fSBram Moolenaar        g:result += 3
2843f665e97fSBram Moolenaar      enddef
2844f665e97fSBram Moolenaar      Func()
2845f665e97fSBram Moolenaar  END
2846f665e97fSBram Moolenaar  # can't use CheckScriptFailure, it ignores the :silent!
2847f665e97fSBram Moolenaar  var fname = 'Xdefsilent'
2848f665e97fSBram Moolenaar  writefile(lines, fname)
2849f665e97fSBram Moolenaar  var caught = 'no'
2850f665e97fSBram Moolenaar  try
2851f665e97fSBram Moolenaar    exe 'source ' .. fname
2852f665e97fSBram Moolenaar  catch /E1030:/
2853f665e97fSBram Moolenaar    caught = 'yes'
2854f665e97fSBram Moolenaar    assert_match('Func, line 4', v:throwpoint)
2855f665e97fSBram Moolenaar  endtry
2856f665e97fSBram Moolenaar  assert_equal('yes', caught)
2857f665e97fSBram Moolenaar  delete(fname)
2858f665e97fSBram Moolenaarenddef
2859f665e97fSBram Moolenaar
28602fecb531SBram Moolenaardef Test_cmdmod_silent_nested()
28612fecb531SBram Moolenaar  var lines =<< trim END
28622fecb531SBram Moolenaar      vim9script
28632fecb531SBram Moolenaar      var result = ''
28642fecb531SBram Moolenaar
28652fecb531SBram Moolenaar      def Error()
28662fecb531SBram Moolenaar          result ..= 'Eb'
28672fecb531SBram Moolenaar          eval [][0]
28682fecb531SBram Moolenaar          result ..= 'Ea'
28692fecb531SBram Moolenaar      enddef
28702fecb531SBram Moolenaar
28712fecb531SBram Moolenaar      def Crash()
28722fecb531SBram Moolenaar          result ..= 'Cb'
28732fecb531SBram Moolenaar          sil! Error()
28742fecb531SBram Moolenaar          result ..= 'Ca'
28752fecb531SBram Moolenaar      enddef
28762fecb531SBram Moolenaar
28772fecb531SBram Moolenaar      Crash()
28782fecb531SBram Moolenaar      assert_equal('CbEbEaCa', result)
28792fecb531SBram Moolenaar  END
28802fecb531SBram Moolenaar  CheckScriptSuccess(lines)
28812fecb531SBram Moolenaarenddef
28822fecb531SBram Moolenaar
28834029cabbSBram Moolenaardef Test_dict_member_with_silent()
28844029cabbSBram Moolenaar  var lines =<< trim END
28854029cabbSBram Moolenaar      vim9script
28864029cabbSBram Moolenaar      g:result = 'none'
28874029cabbSBram Moolenaar      var d: dict<any>
28884029cabbSBram Moolenaar      def Func()
28894029cabbSBram Moolenaar        try
28902949cfdbSBram Moolenaar          g:result = map([], (_, v) => ({}[v]))->join() .. d['']
28914029cabbSBram Moolenaar        catch
28924029cabbSBram Moolenaar        endtry
28934029cabbSBram Moolenaar      enddef
28944029cabbSBram Moolenaar      silent! Func()
28954029cabbSBram Moolenaar      assert_equal('0', g:result)
28964029cabbSBram Moolenaar      unlet g:result
2897af0df47aSBram Moolenaar  END
2898af0df47aSBram Moolenaar  CheckScriptSuccess(lines)
2899af0df47aSBram Moolenaarenddef
2900af0df47aSBram Moolenaar
2901f904133eSBram Moolenaardef Test_skip_cmds_with_silent()
2902f904133eSBram Moolenaar  var lines =<< trim END
2903f904133eSBram Moolenaar      vim9script
2904f904133eSBram Moolenaar
2905f904133eSBram Moolenaar      def Func(b: bool)
2906f904133eSBram Moolenaar        Crash()
2907f904133eSBram Moolenaar      enddef
2908f904133eSBram Moolenaar
2909f904133eSBram Moolenaar      def Crash()
2910f904133eSBram Moolenaar        sil! :/not found/d _
2911f904133eSBram Moolenaar        sil! :/not found/put _
2912f904133eSBram Moolenaar      enddef
2913f904133eSBram Moolenaar
2914f904133eSBram Moolenaar      Func(true)
2915f904133eSBram Moolenaar  END
2916f904133eSBram Moolenaar  CheckScriptSuccess(lines)
2917f904133eSBram Moolenaarenddef
2918f904133eSBram Moolenaar
29195b3d1bb0SBram Moolenaardef Test_opfunc()
29205b3d1bb0SBram Moolenaar  nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@
29215b3d1bb0SBram Moolenaar  def g:Opfunc(_: any): string
29225b3d1bb0SBram Moolenaar    setline(1, 'ASDF')
29235b3d1bb0SBram Moolenaar    return ''
29245b3d1bb0SBram Moolenaar  enddef
29255b3d1bb0SBram Moolenaar  new
29265b3d1bb0SBram Moolenaar  setline(1, 'asdf')
29275b3d1bb0SBram Moolenaar  feedkeys("\<F3>$", 'x')
29285b3d1bb0SBram Moolenaar  assert_equal('ASDF', getline(1))
29295b3d1bb0SBram Moolenaar
29305b3d1bb0SBram Moolenaar  bwipe!
29315b3d1bb0SBram Moolenaar  nunmap <F3>
29325b3d1bb0SBram Moolenaarenddef
29335b3d1bb0SBram Moolenaar
2934077a4231SBram Moolenaar" this was crashing on exit
2935077a4231SBram Moolenaardef Test_nested_lambda_in_closure()
2936077a4231SBram Moolenaar  var lines =<< trim END
2937077a4231SBram Moolenaar      vim9script
2938227c58a4SBram Moolenaar      command WriteDone writefile(['Done'], 'XnestedDone')
2939077a4231SBram Moolenaar      def Outer()
2940077a4231SBram Moolenaar          def g:Inner()
2941077a4231SBram Moolenaar              echo map([1, 2, 3], {_, v -> v + 1})
2942077a4231SBram Moolenaar          enddef
2943077a4231SBram Moolenaar          g:Inner()
2944077a4231SBram Moolenaar      enddef
2945077a4231SBram Moolenaar      defcompile
2946227c58a4SBram Moolenaar      # not reached
2947077a4231SBram Moolenaar  END
2948227c58a4SBram Moolenaar  if !RunVim([], lines, '--clean -c WriteDone -c quit')
2949077a4231SBram Moolenaar    return
2950077a4231SBram Moolenaar  endif
2951077a4231SBram Moolenaar  assert_equal(['Done'], readfile('XnestedDone'))
2952077a4231SBram Moolenaar  delete('XnestedDone')
2953077a4231SBram Moolenaarenddef
2954077a4231SBram Moolenaar
295504947cc6SBram Moolenaardef Test_check_func_arg_types()
295604947cc6SBram Moolenaar  var lines =<< trim END
295704947cc6SBram Moolenaar      vim9script
295804947cc6SBram Moolenaar      def F1(x: string): string
295904947cc6SBram Moolenaar        return x
296004947cc6SBram Moolenaar      enddef
296104947cc6SBram Moolenaar
296204947cc6SBram Moolenaar      def F2(x: number): number
296304947cc6SBram Moolenaar        return x + 1
296404947cc6SBram Moolenaar      enddef
296504947cc6SBram Moolenaar
296604947cc6SBram Moolenaar      def G(g: func): dict<func>
296704947cc6SBram Moolenaar        return {f: g}
296804947cc6SBram Moolenaar      enddef
296904947cc6SBram Moolenaar
297004947cc6SBram Moolenaar      def H(d: dict<func>): string
297104947cc6SBram Moolenaar        return d.f('a')
297204947cc6SBram Moolenaar      enddef
297304947cc6SBram Moolenaar  END
297404947cc6SBram Moolenaar
297504947cc6SBram Moolenaar  CheckScriptSuccess(lines + ['echo H(G(F1))'])
297604947cc6SBram Moolenaar  CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
297704947cc6SBram Moolenaarenddef
297804947cc6SBram Moolenaar
29796e48b84cSBram Moolenaardef Test_list_any_type_checked()
29806e48b84cSBram Moolenaar  var lines =<< trim END
29816e48b84cSBram Moolenaar      vim9script
29826e48b84cSBram Moolenaar      def Foo()
29836e48b84cSBram Moolenaar        --decl--
29846e48b84cSBram Moolenaar        Bar(l)
29856e48b84cSBram Moolenaar      enddef
29866e48b84cSBram Moolenaar      def Bar(ll: list<dict<any>>)
29876e48b84cSBram Moolenaar      enddef
29886e48b84cSBram Moolenaar      Foo()
29896e48b84cSBram Moolenaar  END
29906e48b84cSBram Moolenaar  lines[2] = 'var l: list<any>'
29916e48b84cSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2)
29926e48b84cSBram Moolenaar
29936e48b84cSBram Moolenaar  lines[2] = 'var l: list<any> = []'
29946e48b84cSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<any>', 2)
29956e48b84cSBram Moolenaar
29966e48b84cSBram Moolenaar  lines[2] = 'var l: list<any> = [11]'
29976e48b84cSBram Moolenaar  CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>', 2)
29986e48b84cSBram Moolenaarenddef
29996e48b84cSBram Moolenaar
3000701cc6caSBram Moolenaardef Test_compile_error()
3001701cc6caSBram Moolenaar  var lines =<< trim END
3002701cc6caSBram Moolenaar    def g:Broken()
3003701cc6caSBram Moolenaar      echo 'a' + {}
3004701cc6caSBram Moolenaar    enddef
3005701cc6caSBram Moolenaar    call g:Broken()
3006701cc6caSBram Moolenaar  END
3007701cc6caSBram Moolenaar  # First call: compilation error
3008701cc6caSBram Moolenaar  CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
3009701cc6caSBram Moolenaar
3010701cc6caSBram Moolenaar  # Second call won't try compiling again
3011701cc6caSBram Moolenaar  assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
3012599410cbSBram Moolenaar  delfunc g:Broken
3013599410cbSBram Moolenaar
3014599410cbSBram Moolenaar  # No error when compiling with :silent!
3015599410cbSBram Moolenaar  lines =<< trim END
3016599410cbSBram Moolenaar    def g:Broken()
3017599410cbSBram Moolenaar      echo 'a' + []
3018599410cbSBram Moolenaar    enddef
3019599410cbSBram Moolenaar    silent! defcompile
3020599410cbSBram Moolenaar  END
3021599410cbSBram Moolenaar  CheckScriptSuccess(lines)
3022599410cbSBram Moolenaar
3023599410cbSBram Moolenaar  # Calling the function won't try compiling again
3024599410cbSBram Moolenaar  assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
3025599410cbSBram Moolenaar  delfunc g:Broken
3026701cc6caSBram Moolenaarenddef
3027701cc6caSBram Moolenaar
3028962c43bfSBram Moolenaardef Test_ignored_argument()
3029962c43bfSBram Moolenaar  var lines =<< trim END
3030962c43bfSBram Moolenaar      vim9script
3031962c43bfSBram Moolenaar      def Ignore(_, _): string
3032962c43bfSBram Moolenaar        return 'yes'
3033962c43bfSBram Moolenaar      enddef
3034962c43bfSBram Moolenaar      assert_equal('yes', Ignore(1, 2))
3035962c43bfSBram Moolenaar
3036962c43bfSBram Moolenaar      func Ok(_)
3037962c43bfSBram Moolenaar        return a:_
3038962c43bfSBram Moolenaar      endfunc
3039962c43bfSBram Moolenaar      assert_equal('ok', Ok('ok'))
3040962c43bfSBram Moolenaar
3041962c43bfSBram Moolenaar      func Oktoo()
3042962c43bfSBram Moolenaar        let _ = 'too'
3043962c43bfSBram Moolenaar        return _
3044962c43bfSBram Moolenaar      endfunc
3045962c43bfSBram Moolenaar      assert_equal('too', Oktoo())
3046da479c75SBram Moolenaar
3047da479c75SBram Moolenaar      assert_equal([[1], [2], [3]], range(3)->mapnew((_, v) => [v]->map((_, w) => w + 1)))
3048962c43bfSBram Moolenaar  END
3049962c43bfSBram Moolenaar  CheckScriptSuccess(lines)
3050962c43bfSBram Moolenaar
3051962c43bfSBram Moolenaar  lines =<< trim END
3052962c43bfSBram Moolenaar      def Ignore(_: string): string
3053962c43bfSBram Moolenaar        return _
3054962c43bfSBram Moolenaar      enddef
3055962c43bfSBram Moolenaar      defcompile
3056962c43bfSBram Moolenaar  END
3057962c43bfSBram Moolenaar  CheckScriptFailure(lines, 'E1181:', 1)
3058962c43bfSBram Moolenaar
3059962c43bfSBram Moolenaar  lines =<< trim END
3060962c43bfSBram Moolenaar      var _ = 1
3061962c43bfSBram Moolenaar  END
3062962c43bfSBram Moolenaar  CheckDefAndScriptFailure(lines, 'E1181:', 1)
306334fcb697SYegappan Lakshmanan
306434fcb697SYegappan Lakshmanan  lines =<< trim END
306534fcb697SYegappan Lakshmanan      var x = _
306634fcb697SYegappan Lakshmanan  END
306734fcb697SYegappan Lakshmanan  CheckDefAndScriptFailure(lines, 'E1181:', 1)
3068962c43bfSBram Moolenaarenddef
3069962c43bfSBram Moolenaar
3070bb8a7ce0SBram Moolenaardef Test_too_many_arguments()
3071bb8a7ce0SBram Moolenaar  var lines =<< trim END
3072bb8a7ce0SBram Moolenaar    echo [0, 1, 2]->map(() => 123)
3073bb8a7ce0SBram Moolenaar  END
3074bb8a7ce0SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1106: 2 arguments too many', 1)
3075bb8a7ce0SBram Moolenaar
3076bb8a7ce0SBram Moolenaar  lines =<< trim END
3077bb8a7ce0SBram Moolenaar    echo [0, 1, 2]->map((_) => 123)
3078bb8a7ce0SBram Moolenaar  END
3079bb8a7ce0SBram Moolenaar  CheckDefExecAndScriptFailure(lines, 'E1106: One argument too many', 1)
3080bb8a7ce0SBram Moolenaarenddef
3081077a4231SBram Moolenaar
3082a6aa1642SBram Moolenaardef Test_closing_brace_at_start_of_line()
3083a6aa1642SBram Moolenaar  var lines =<< trim END
3084a6aa1642SBram Moolenaar      def Func()
3085a6aa1642SBram Moolenaar      enddef
3086a6aa1642SBram Moolenaar      Func(
3087a6aa1642SBram Moolenaar      )
3088a6aa1642SBram Moolenaar  END
3089a6aa1642SBram Moolenaar  call CheckDefAndScriptSuccess(lines)
3090a6aa1642SBram Moolenaarenddef
3091a6aa1642SBram Moolenaar
3092*b033ee2dSBram Moolenaarfunc CreateMydict()
3093*b033ee2dSBram Moolenaar  let g:mydict = {}
3094*b033ee2dSBram Moolenaar  func g:mydict.afunc()
3095*b033ee2dSBram Moolenaar    let g:result = self.key
3096*b033ee2dSBram Moolenaar  endfunc
3097*b033ee2dSBram Moolenaarendfunc
3098*b033ee2dSBram Moolenaar
3099*b033ee2dSBram Moolenaardef Test_numbered_function_reference()
3100*b033ee2dSBram Moolenaar  CreateMydict()
3101*b033ee2dSBram Moolenaar  var output = execute('legacy func g:mydict.afunc')
3102*b033ee2dSBram Moolenaar  var funcName = 'g:' .. substitute(output, '.*function \(\d\+\).*', '\1', '')
3103*b033ee2dSBram Moolenaar  execute 'function(' .. funcName .. ', [], {key: 42})()'
3104*b033ee2dSBram Moolenaar  # check that the function still exists
3105*b033ee2dSBram Moolenaar  assert_equal(output, execute('legacy func g:mydict.afunc'))
3106*b033ee2dSBram Moolenaar  unlet g:mydict
3107*b033ee2dSBram Moolenaarenddef
3108*b033ee2dSBram Moolenaar
31092067733bSBram Moolenaarif has('python3')
31102067733bSBram Moolenaar  def Test_python3_heredoc()
31112067733bSBram Moolenaar    py3 << trim EOF
31122067733bSBram Moolenaar      import vim
31132067733bSBram Moolenaar      vim.vars['didit'] = 'yes'
31142067733bSBram Moolenaar    EOF
31152067733bSBram Moolenaar    assert_equal('yes', g:didit)
31162067733bSBram Moolenaar
31172067733bSBram Moolenaar    python3 << trim EOF
31182067733bSBram Moolenaar      import vim
31192067733bSBram Moolenaar      vim.vars['didit'] = 'again'
31202067733bSBram Moolenaar    EOF
31212067733bSBram Moolenaar    assert_equal('again', g:didit)
31222067733bSBram Moolenaar  enddef
31232067733bSBram Moolenaarendif
31242067733bSBram Moolenaar
31252067733bSBram Moolenaar" This messes up syntax highlight, keep near the end.
31262067733bSBram Moolenaarif has('lua')
31272067733bSBram Moolenaar  def Test_lua_heredoc()
31282067733bSBram Moolenaar    g:d = {}
31292067733bSBram Moolenaar    lua << trim EOF
31302067733bSBram Moolenaar        x = vim.eval('g:d')
31312067733bSBram Moolenaar        x['key'] = 'val'
31322067733bSBram Moolenaar    EOF
31332067733bSBram Moolenaar    assert_equal('val', g:d.key)
31342067733bSBram Moolenaar  enddef
31352067733bSBram Moolenaarendif
31362067733bSBram Moolenaar
3137f7779c63SBram Moolenaar
31385deeb3f1SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
3139