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 770ba48e8cSBram Moolenaardef CallRecursive(n: number): number 780ba48e8cSBram Moolenaar return CallRecursive(n + 1) 790ba48e8cSBram Moolenaarenddef 800ba48e8cSBram Moolenaar 810ba48e8cSBram Moolenaardef CallMapRecursive(l: list<number>): number 822949cfdbSBram Moolenaar return map(l, (_, v) => CallMapRecursive([v]))[0] 830ba48e8cSBram Moolenaarenddef 840ba48e8cSBram Moolenaar 850ba48e8cSBram Moolenaardef Test_funcdepth_error() 860ba48e8cSBram Moolenaar set maxfuncdepth=10 870ba48e8cSBram Moolenaar 880ba48e8cSBram Moolenaar var caught = false 890ba48e8cSBram Moolenaar try 900ba48e8cSBram Moolenaar CallRecursive(1) 910ba48e8cSBram Moolenaar catch /E132:/ 920ba48e8cSBram Moolenaar caught = true 930ba48e8cSBram Moolenaar endtry 940ba48e8cSBram Moolenaar assert_true(caught) 950ba48e8cSBram Moolenaar 960ba48e8cSBram Moolenaar caught = false 970ba48e8cSBram Moolenaar try 980ba48e8cSBram Moolenaar CallMapRecursive([1]) 990ba48e8cSBram Moolenaar catch /E132:/ 1000ba48e8cSBram Moolenaar caught = true 1010ba48e8cSBram Moolenaar endtry 1020ba48e8cSBram Moolenaar assert_true(caught) 1030ba48e8cSBram Moolenaar 1040ba48e8cSBram Moolenaar set maxfuncdepth& 1050ba48e8cSBram Moolenaarenddef 1060ba48e8cSBram Moolenaar 1075178b1b0SBram Moolenaardef Test_endfunc_enddef() 1085178b1b0SBram Moolenaar var lines =<< trim END 1095178b1b0SBram Moolenaar def Test() 1105178b1b0SBram Moolenaar echo 'test' 1115178b1b0SBram Moolenaar endfunc 1125178b1b0SBram Moolenaar enddef 1135178b1b0SBram Moolenaar END 1145178b1b0SBram Moolenaar CheckScriptFailure(lines, 'E1151:', 3) 1155178b1b0SBram Moolenaar 1165178b1b0SBram Moolenaar lines =<< trim END 1175178b1b0SBram Moolenaar def Test() 1185178b1b0SBram Moolenaar func Nested() 1195178b1b0SBram Moolenaar echo 'test' 1205178b1b0SBram Moolenaar enddef 1215178b1b0SBram Moolenaar enddef 1225178b1b0SBram Moolenaar END 1235178b1b0SBram Moolenaar CheckScriptFailure(lines, 'E1152:', 4) 12449f1e9ecSBram Moolenaar 12549f1e9ecSBram Moolenaar lines =<< trim END 12649f1e9ecSBram Moolenaar def Ok() 12749f1e9ecSBram Moolenaar echo 'hello' 12849f1e9ecSBram Moolenaar enddef | echo 'there' 12949f1e9ecSBram Moolenaar def Bad() 13049f1e9ecSBram Moolenaar echo 'hello' 13149f1e9ecSBram Moolenaar enddef there 13249f1e9ecSBram Moolenaar END 13349f1e9ecSBram Moolenaar CheckScriptFailure(lines, 'E1173: Text found after enddef: there', 6) 1345178b1b0SBram Moolenaarenddef 1355178b1b0SBram Moolenaar 136b8ba9b91SBram Moolenaardef Test_missing_endfunc_enddef() 137b8ba9b91SBram Moolenaar var lines =<< trim END 138b8ba9b91SBram Moolenaar vim9script 139b8ba9b91SBram Moolenaar def Test() 140b8ba9b91SBram Moolenaar echo 'test' 141b8ba9b91SBram Moolenaar endef 142b8ba9b91SBram Moolenaar END 143b8ba9b91SBram Moolenaar CheckScriptFailure(lines, 'E1057:', 2) 144b8ba9b91SBram Moolenaar 145b8ba9b91SBram Moolenaar lines =<< trim END 146b8ba9b91SBram Moolenaar vim9script 147b8ba9b91SBram Moolenaar func Some() 148b8ba9b91SBram Moolenaar echo 'test' 149b8ba9b91SBram Moolenaar enfffunc 150b8ba9b91SBram Moolenaar END 151b8ba9b91SBram Moolenaar CheckScriptFailure(lines, 'E126:', 2) 152b8ba9b91SBram Moolenaarenddef 153b8ba9b91SBram Moolenaar 1544efd9948SBram Moolenaardef Test_white_space_before_paren() 1554efd9948SBram Moolenaar var lines =<< trim END 1564efd9948SBram Moolenaar vim9script 1574efd9948SBram Moolenaar def Test () 1584efd9948SBram Moolenaar echo 'test' 1594efd9948SBram Moolenaar enddef 1604efd9948SBram Moolenaar END 1614efd9948SBram Moolenaar CheckScriptFailure(lines, 'E1068:', 2) 1624efd9948SBram Moolenaar 1634efd9948SBram Moolenaar lines =<< trim END 1644efd9948SBram Moolenaar vim9script 1654efd9948SBram Moolenaar func Test () 1664efd9948SBram Moolenaar echo 'test' 1674efd9948SBram Moolenaar endfunc 1684efd9948SBram Moolenaar END 1694efd9948SBram Moolenaar CheckScriptFailure(lines, 'E1068:', 2) 1704efd9948SBram Moolenaar 1714efd9948SBram Moolenaar lines =<< trim END 1724efd9948SBram Moolenaar def Test () 1734efd9948SBram Moolenaar echo 'test' 1744efd9948SBram Moolenaar enddef 1754efd9948SBram Moolenaar END 1764efd9948SBram Moolenaar CheckScriptFailure(lines, 'E1068:', 1) 1774efd9948SBram Moolenaar 1784efd9948SBram Moolenaar lines =<< trim END 1794efd9948SBram Moolenaar func Test () 1804efd9948SBram Moolenaar echo 'test' 1814efd9948SBram Moolenaar endfunc 1824efd9948SBram Moolenaar END 1834efd9948SBram Moolenaar CheckScriptSuccess(lines) 1844efd9948SBram Moolenaarenddef 1854efd9948SBram Moolenaar 186832ea89cSBram Moolenaardef Test_enddef_dict_key() 187832ea89cSBram Moolenaar var d = { 188832ea89cSBram Moolenaar enddef: 'x', 189832ea89cSBram Moolenaar endfunc: 'y', 190832ea89cSBram Moolenaar } 191832ea89cSBram Moolenaar assert_equal({enddef: 'x', endfunc: 'y'}, d) 192832ea89cSBram Moolenaarenddef 193832ea89cSBram Moolenaar 1945deeb3f1SBram Moolenaardef ReturnString(): string 1955deeb3f1SBram Moolenaar return 'string' 1965deeb3f1SBram Moolenaarenddef 1975deeb3f1SBram Moolenaar 1985deeb3f1SBram Moolenaardef ReturnNumber(): number 1995deeb3f1SBram Moolenaar return 123 2005deeb3f1SBram Moolenaarenddef 2015deeb3f1SBram Moolenaar 2025deeb3f1SBram Moolenaarlet g:notNumber = 'string' 2035deeb3f1SBram Moolenaar 2045deeb3f1SBram Moolenaardef ReturnGlobal(): number 2055deeb3f1SBram Moolenaar return g:notNumber 2065deeb3f1SBram Moolenaarenddef 2075deeb3f1SBram Moolenaar 2085deeb3f1SBram Moolenaardef Test_return_something() 209c0c71e9dSBram Moolenaar ReturnString()->assert_equal('string') 210c0c71e9dSBram Moolenaar ReturnNumber()->assert_equal(123) 2115e654230SBram Moolenaar assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal') 2125deeb3f1SBram Moolenaarenddef 2135deeb3f1SBram Moolenaar 214e32e516dSBram Moolenaardef Test_check_argument_type() 215e32e516dSBram Moolenaar var lines =<< trim END 216e32e516dSBram Moolenaar vim9script 217e32e516dSBram Moolenaar def Val(a: number, b: number): number 218e32e516dSBram Moolenaar return 0 219e32e516dSBram Moolenaar enddef 220e32e516dSBram Moolenaar def Func() 221e32e516dSBram Moolenaar var x: any = true 222e32e516dSBram Moolenaar Val(0, x) 223e32e516dSBram Moolenaar enddef 224e32e516dSBram Moolenaar disass Func 225e32e516dSBram Moolenaar Func() 226e32e516dSBram Moolenaar END 227e32e516dSBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got bool', 2) 228e32e516dSBram Moolenaarenddef 229e32e516dSBram Moolenaar 230efd88555SBram Moolenaardef Test_missing_return() 231efd88555SBram Moolenaar CheckDefFailure(['def Missing(): number', 232efd88555SBram Moolenaar ' if g:cond', 233efd88555SBram Moolenaar ' echo "no return"', 234efd88555SBram Moolenaar ' else', 235efd88555SBram Moolenaar ' return 0', 236efd88555SBram Moolenaar ' endif' 237efd88555SBram Moolenaar 'enddef'], 'E1027:') 238efd88555SBram Moolenaar CheckDefFailure(['def Missing(): number', 239efd88555SBram Moolenaar ' if g:cond', 240efd88555SBram Moolenaar ' return 1', 241efd88555SBram Moolenaar ' else', 242efd88555SBram Moolenaar ' echo "no return"', 243efd88555SBram Moolenaar ' endif' 244efd88555SBram Moolenaar 'enddef'], 'E1027:') 245efd88555SBram Moolenaar CheckDefFailure(['def Missing(): number', 246efd88555SBram Moolenaar ' if g:cond', 247efd88555SBram Moolenaar ' return 1', 248efd88555SBram Moolenaar ' else', 249efd88555SBram Moolenaar ' return 2', 250efd88555SBram Moolenaar ' endif' 251efd88555SBram Moolenaar ' return 3' 252efd88555SBram Moolenaar 'enddef'], 'E1095:') 253efd88555SBram Moolenaarenddef 254efd88555SBram Moolenaar 255403dc31fSBram Moolenaardef Test_return_bool() 256403dc31fSBram Moolenaar var lines =<< trim END 257403dc31fSBram Moolenaar vim9script 258403dc31fSBram Moolenaar def MenuFilter(id: number, key: string): bool 259403dc31fSBram Moolenaar return popup_filter_menu(id, key) 260403dc31fSBram Moolenaar enddef 261403dc31fSBram Moolenaar def YesnoFilter(id: number, key: string): bool 262403dc31fSBram Moolenaar return popup_filter_yesno(id, key) 263403dc31fSBram Moolenaar enddef 264403dc31fSBram Moolenaar defcompile 265403dc31fSBram Moolenaar END 266403dc31fSBram Moolenaar CheckScriptSuccess(lines) 267403dc31fSBram Moolenaarenddef 268403dc31fSBram Moolenaar 2695deeb3f1SBram Moolenaarlet s:nothing = 0 2705deeb3f1SBram Moolenaardef ReturnNothing() 2715deeb3f1SBram Moolenaar s:nothing = 1 2725deeb3f1SBram Moolenaar if true 2735deeb3f1SBram Moolenaar return 2745deeb3f1SBram Moolenaar endif 2755deeb3f1SBram Moolenaar s:nothing = 2 2765deeb3f1SBram Moolenaarenddef 2775deeb3f1SBram Moolenaar 2785deeb3f1SBram Moolenaardef Test_return_nothing() 2795deeb3f1SBram Moolenaar ReturnNothing() 280c0c71e9dSBram Moolenaar s:nothing->assert_equal(1) 2815deeb3f1SBram Moolenaarenddef 2825deeb3f1SBram Moolenaar 283648ea76eSBram Moolenaardef Test_return_invalid() 284648ea76eSBram Moolenaar var lines =<< trim END 285648ea76eSBram Moolenaar vim9script 286648ea76eSBram Moolenaar def Func(): invalid 287648ea76eSBram Moolenaar return xxx 288648ea76eSBram Moolenaar enddef 289648ea76eSBram Moolenaar defcompile 290648ea76eSBram Moolenaar END 291648ea76eSBram Moolenaar CheckScriptFailure(lines, 'E1010:', 2) 29231842cd0SBram Moolenaar 29331842cd0SBram Moolenaar lines =<< trim END 29431842cd0SBram Moolenaar vim9script 29531842cd0SBram Moolenaar def Test(Fun: func(number): number): list<number> 29631842cd0SBram Moolenaar return map([1, 2, 3], (_, i) => Fun(i)) 29731842cd0SBram Moolenaar enddef 29831842cd0SBram Moolenaar defcompile 29931842cd0SBram Moolenaar def Inc(nr: number): nr 30031842cd0SBram Moolenaar return nr + 2 30131842cd0SBram Moolenaar enddef 30231842cd0SBram Moolenaar echo Test(Inc) 30331842cd0SBram Moolenaar END 30431842cd0SBram Moolenaar # doing this twice was leaking memory 30531842cd0SBram Moolenaar CheckScriptFailure(lines, 'E1010:') 30631842cd0SBram Moolenaar CheckScriptFailure(lines, 'E1010:') 307648ea76eSBram Moolenaarenddef 308648ea76eSBram Moolenaar 3095deeb3f1SBram Moolenaarfunc Increment() 3105deeb3f1SBram Moolenaar let g:counter += 1 3115deeb3f1SBram Moolenaarendfunc 3125deeb3f1SBram Moolenaar 3135deeb3f1SBram Moolenaardef Test_call_ufunc_count() 3145deeb3f1SBram Moolenaar g:counter = 1 3155deeb3f1SBram Moolenaar Increment() 3165deeb3f1SBram Moolenaar Increment() 3175deeb3f1SBram Moolenaar Increment() 318f5be8cdbSBram Moolenaar # works with and without :call 319c0c71e9dSBram Moolenaar g:counter->assert_equal(4) 320c0c71e9dSBram Moolenaar eval g:counter->assert_equal(4) 3215deeb3f1SBram Moolenaar unlet g:counter 3225deeb3f1SBram Moolenaarenddef 3235deeb3f1SBram Moolenaar 3245deeb3f1SBram Moolenaardef MyVarargs(arg: string, ...rest: list<string>): string 3257a9cbca0SBram Moolenaar var res = arg 3265deeb3f1SBram Moolenaar for s in rest 3275deeb3f1SBram Moolenaar res ..= ',' .. s 3285deeb3f1SBram Moolenaar endfor 3295deeb3f1SBram Moolenaar return res 3305deeb3f1SBram Moolenaarenddef 3315deeb3f1SBram Moolenaar 3325deeb3f1SBram Moolenaardef Test_call_varargs() 333c0c71e9dSBram Moolenaar MyVarargs('one')->assert_equal('one') 334c0c71e9dSBram Moolenaar MyVarargs('one', 'two')->assert_equal('one,two') 335c0c71e9dSBram Moolenaar MyVarargs('one', 'two', 'three')->assert_equal('one,two,three') 3365deeb3f1SBram Moolenaarenddef 3375deeb3f1SBram Moolenaar 3385deeb3f1SBram Moolenaardef MyDefaultArgs(name = 'string'): string 3395deeb3f1SBram Moolenaar return name 3405deeb3f1SBram Moolenaarenddef 3415deeb3f1SBram Moolenaar 342e30f64b4SBram Moolenaardef MyDefaultSecond(name: string, second: bool = true): string 343e30f64b4SBram Moolenaar return second ? name : 'none' 344e30f64b4SBram Moolenaarenddef 345e30f64b4SBram Moolenaar 34638a3bfa9SBram Moolenaar 3475deeb3f1SBram Moolenaardef Test_call_default_args() 348c0c71e9dSBram Moolenaar MyDefaultArgs()->assert_equal('string') 34938a3bfa9SBram Moolenaar MyDefaultArgs(v:none)->assert_equal('string') 350c0c71e9dSBram Moolenaar MyDefaultArgs('one')->assert_equal('one') 35138a3bfa9SBram Moolenaar assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args') 3525deeb3f1SBram Moolenaar 353c0c71e9dSBram Moolenaar MyDefaultSecond('test')->assert_equal('test') 354c0c71e9dSBram Moolenaar MyDefaultSecond('test', true)->assert_equal('test') 355c0c71e9dSBram Moolenaar MyDefaultSecond('test', false)->assert_equal('none') 356e30f64b4SBram Moolenaar 35738a3bfa9SBram Moolenaar var lines =<< trim END 35838a3bfa9SBram Moolenaar def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string 35938a3bfa9SBram Moolenaar return name .. aa .. bb 36038a3bfa9SBram Moolenaar enddef 36138a3bfa9SBram Moolenaar 36238a3bfa9SBram Moolenaar MyDefaultThird('->')->assert_equal('->aabb') 36338a3bfa9SBram Moolenaar MyDefaultThird('->', v:none)->assert_equal('->aabb') 36438a3bfa9SBram Moolenaar MyDefaultThird('->', 'xx')->assert_equal('->xxbb') 36538a3bfa9SBram Moolenaar MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb') 36638a3bfa9SBram Moolenaar MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb') 36738a3bfa9SBram Moolenaar MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy') 36838a3bfa9SBram Moolenaar MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy') 36938a3bfa9SBram Moolenaar END 37038a3bfa9SBram Moolenaar CheckDefAndScriptSuccess(lines) 37138a3bfa9SBram Moolenaar 372822ba247SBram Moolenaar CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 3732d870f8dSBram Moolenaar delfunc g:Func 3747707228aSBram Moolenaar CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string') 3752d870f8dSBram Moolenaar delfunc g:Func 37612bce958SBram Moolenaar 37738a3bfa9SBram Moolenaar lines =<< trim END 37812bce958SBram Moolenaar vim9script 37912bce958SBram Moolenaar def Func(a = b == 0 ? 1 : 2, b = 0) 38012bce958SBram Moolenaar enddef 38112bce958SBram Moolenaar defcompile 38212bce958SBram Moolenaar END 38312bce958SBram Moolenaar CheckScriptFailure(lines, 'E1001: Variable not found: b') 38404b12697SBram Moolenaarenddef 38504b12697SBram Moolenaar 386cef1270dSBram Moolenaardef FuncWithComment( # comment 387cef1270dSBram Moolenaar a: number, #comment 388cef1270dSBram Moolenaar b: bool, # comment 389cef1270dSBram Moolenaar c: string) #comment 390cef1270dSBram Moolenaar assert_equal(4, a) 391cef1270dSBram Moolenaar assert_equal(true, b) 392cef1270dSBram Moolenaar assert_equal('yes', c) 393cef1270dSBram Moolenaarenddef 394cef1270dSBram Moolenaar 395cef1270dSBram Moolenaardef Test_func_with_comments() 396cef1270dSBram Moolenaar FuncWithComment(4, true, 'yes') 397cef1270dSBram Moolenaar 398cef1270dSBram Moolenaar var lines =<< trim END 399cef1270dSBram Moolenaar def Func(# comment 400cef1270dSBram Moolenaar arg: string) 401cef1270dSBram Moolenaar enddef 402cef1270dSBram Moolenaar END 403cef1270dSBram Moolenaar CheckScriptFailure(lines, 'E125:', 1) 404cef1270dSBram Moolenaar 405cef1270dSBram Moolenaar lines =<< trim END 406cef1270dSBram Moolenaar def Func( 407cef1270dSBram Moolenaar arg: string# comment 408cef1270dSBram Moolenaar ) 409cef1270dSBram Moolenaar enddef 410cef1270dSBram Moolenaar END 411cef1270dSBram Moolenaar CheckScriptFailure(lines, 'E475:', 2) 412cef1270dSBram Moolenaar 413cef1270dSBram Moolenaar lines =<< trim END 414cef1270dSBram Moolenaar def Func( 415cef1270dSBram Moolenaar arg: string 416cef1270dSBram Moolenaar )# comment 417cef1270dSBram Moolenaar enddef 418cef1270dSBram Moolenaar END 419cef1270dSBram Moolenaar CheckScriptFailure(lines, 'E488:', 3) 420cef1270dSBram Moolenaarenddef 421cef1270dSBram Moolenaar 42204b12697SBram Moolenaardef Test_nested_function() 42304b12697SBram Moolenaar def Nested(arg: string): string 42404b12697SBram Moolenaar return 'nested ' .. arg 42504b12697SBram Moolenaar enddef 426c0c71e9dSBram Moolenaar Nested('function')->assert_equal('nested function') 42704b12697SBram Moolenaar 4280e65d3deSBram Moolenaar CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 4290e65d3deSBram Moolenaar CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 4300e65d3deSBram Moolenaar 43104b12697SBram Moolenaar CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 432bcbf4139SBram Moolenaar CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:') 433bcbf4139SBram Moolenaar CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:') 4348b848cafSBram Moolenaar 43554021758SBram Moolenaar var lines =<< trim END 43654021758SBram Moolenaar def Outer() 43754021758SBram Moolenaar def Inner() 43854021758SBram Moolenaar # comment 43954021758SBram Moolenaar enddef 44054021758SBram Moolenaar def Inner() 44154021758SBram Moolenaar enddef 44254021758SBram Moolenaar enddef 44354021758SBram Moolenaar END 44454021758SBram Moolenaar CheckDefFailure(lines, 'E1073:') 44554021758SBram Moolenaar 44654021758SBram Moolenaar lines =<< trim END 44754021758SBram Moolenaar def Outer() 44854021758SBram Moolenaar def Inner() 44954021758SBram Moolenaar # comment 45054021758SBram Moolenaar enddef 45154021758SBram Moolenaar def! Inner() 45254021758SBram Moolenaar enddef 45354021758SBram Moolenaar enddef 45454021758SBram Moolenaar END 45554021758SBram Moolenaar CheckDefFailure(lines, 'E1117:') 45654021758SBram Moolenaar 45754021758SBram Moolenaar # nested function inside conditional 45854021758SBram Moolenaar lines =<< trim END 45954021758SBram Moolenaar vim9script 46054021758SBram Moolenaar var thecount = 0 46154021758SBram Moolenaar if true 46254021758SBram Moolenaar def Test(): number 46354021758SBram Moolenaar def TheFunc(): number 46454021758SBram Moolenaar thecount += 1 46554021758SBram Moolenaar return thecount 46654021758SBram Moolenaar enddef 46754021758SBram Moolenaar return TheFunc() 46854021758SBram Moolenaar enddef 46954021758SBram Moolenaar endif 47054021758SBram Moolenaar defcompile 47154021758SBram Moolenaar assert_equal(1, Test()) 47254021758SBram Moolenaar assert_equal(2, Test()) 47354021758SBram Moolenaar END 47454021758SBram Moolenaar CheckScriptSuccess(lines) 4758863bda2SBram Moolenaar 4768863bda2SBram Moolenaar # also works when "thecount" is inside the "if" block 4778863bda2SBram Moolenaar lines =<< trim END 4788863bda2SBram Moolenaar vim9script 4798863bda2SBram Moolenaar if true 4808863bda2SBram Moolenaar var thecount = 0 4818863bda2SBram Moolenaar def Test(): number 4828863bda2SBram Moolenaar def TheFunc(): number 4838863bda2SBram Moolenaar thecount += 1 4848863bda2SBram Moolenaar return thecount 4858863bda2SBram Moolenaar enddef 4868863bda2SBram Moolenaar return TheFunc() 4878863bda2SBram Moolenaar enddef 4888863bda2SBram Moolenaar endif 4898863bda2SBram Moolenaar defcompile 4908863bda2SBram Moolenaar assert_equal(1, Test()) 4918863bda2SBram Moolenaar assert_equal(2, Test()) 4928863bda2SBram Moolenaar END 4938863bda2SBram Moolenaar CheckScriptSuccess(lines) 4945deeb3f1SBram Moolenaarenddef 4955deeb3f1SBram Moolenaar 496adc8e446SBram Moolenaardef Test_not_nested_function() 497adc8e446SBram Moolenaar echo printf('%d', 498adc8e446SBram Moolenaar function('len')('xxx')) 499adc8e446SBram Moolenaarenddef 500adc8e446SBram Moolenaar 501af8edbb8SBram Moolenaarfunc Test_call_default_args_from_func() 502c0c71e9dSBram Moolenaar call MyDefaultArgs()->assert_equal('string') 503c0c71e9dSBram Moolenaar call MyDefaultArgs('one')->assert_equal('one') 5049bd5d879SBram Moolenaar call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func') 505af8edbb8SBram Moolenaarendfunc 506af8edbb8SBram Moolenaar 50738ddf333SBram Moolenaardef Test_nested_global_function() 5087a9cbca0SBram Moolenaar var lines =<< trim END 50938ddf333SBram Moolenaar vim9script 51038ddf333SBram Moolenaar def Outer() 51138ddf333SBram Moolenaar def g:Inner(): string 51238ddf333SBram Moolenaar return 'inner' 51338ddf333SBram Moolenaar enddef 51438ddf333SBram Moolenaar enddef 515af8edbb8SBram Moolenaar defcompile 516af8edbb8SBram Moolenaar Outer() 517c0c71e9dSBram Moolenaar g:Inner()->assert_equal('inner') 518af8edbb8SBram Moolenaar delfunc g:Inner 519af8edbb8SBram Moolenaar Outer() 520c0c71e9dSBram Moolenaar g:Inner()->assert_equal('inner') 521af8edbb8SBram Moolenaar delfunc g:Inner 522af8edbb8SBram Moolenaar Outer() 523c0c71e9dSBram Moolenaar g:Inner()->assert_equal('inner') 524af8edbb8SBram Moolenaar delfunc g:Inner 52538ddf333SBram Moolenaar END 52638ddf333SBram Moolenaar CheckScriptSuccess(lines) 5272c79e9d1SBram Moolenaar 5282c79e9d1SBram Moolenaar lines =<< trim END 5292c79e9d1SBram Moolenaar vim9script 5302c79e9d1SBram Moolenaar def Outer() 5312c79e9d1SBram Moolenaar def g:Inner(): string 5322c79e9d1SBram Moolenaar return 'inner' 5332c79e9d1SBram Moolenaar enddef 5342c79e9d1SBram Moolenaar enddef 5352c79e9d1SBram Moolenaar defcompile 5362c79e9d1SBram Moolenaar Outer() 5372c79e9d1SBram Moolenaar Outer() 5382c79e9d1SBram Moolenaar END 5392c79e9d1SBram Moolenaar CheckScriptFailure(lines, "E122:") 540cd45ed03SBram Moolenaar delfunc g:Inner 541ad486a0fSBram Moolenaar 542ad486a0fSBram Moolenaar lines =<< trim END 543ad486a0fSBram Moolenaar vim9script 54458a52f21SBram Moolenaar def Outer() 54558a52f21SBram Moolenaar def g:Inner() 5462949cfdbSBram Moolenaar echo map([1, 2, 3], (_, v) => v + 1) 54758a52f21SBram Moolenaar enddef 54858a52f21SBram Moolenaar g:Inner() 54958a52f21SBram Moolenaar enddef 55058a52f21SBram Moolenaar Outer() 55158a52f21SBram Moolenaar END 55258a52f21SBram Moolenaar CheckScriptSuccess(lines) 55358a52f21SBram Moolenaar delfunc g:Inner 55458a52f21SBram Moolenaar 55558a52f21SBram Moolenaar lines =<< trim END 55658a52f21SBram Moolenaar vim9script 557ad486a0fSBram Moolenaar def Func() 558ad486a0fSBram Moolenaar echo 'script' 559ad486a0fSBram Moolenaar enddef 560ad486a0fSBram Moolenaar def Outer() 561ad486a0fSBram Moolenaar def Func() 562ad486a0fSBram Moolenaar echo 'inner' 563ad486a0fSBram Moolenaar enddef 564ad486a0fSBram Moolenaar enddef 565ad486a0fSBram Moolenaar defcompile 566ad486a0fSBram Moolenaar END 567ad486a0fSBram Moolenaar CheckScriptFailure(lines, "E1073:") 56838ddf333SBram Moolenaarenddef 56938ddf333SBram Moolenaar 5706abdcf82SBram Moolenaardef DefListAll() 5716abdcf82SBram Moolenaar def 5726abdcf82SBram Moolenaarenddef 5736abdcf82SBram Moolenaar 5746abdcf82SBram Moolenaardef DefListOne() 5756abdcf82SBram Moolenaar def DefListOne 5766abdcf82SBram Moolenaarenddef 5776abdcf82SBram Moolenaar 5786abdcf82SBram Moolenaardef DefListMatches() 5796abdcf82SBram Moolenaar def /DefList 5806abdcf82SBram Moolenaarenddef 5816abdcf82SBram Moolenaar 5826abdcf82SBram Moolenaardef Test_nested_def_list() 5836abdcf82SBram Moolenaar var funcs = split(execute('call DefListAll()'), "\n") 5846abdcf82SBram Moolenaar assert_true(len(funcs) > 10) 5856abdcf82SBram Moolenaar assert_true(funcs->index('def DefListAll()') >= 0) 5866abdcf82SBram Moolenaar 5876abdcf82SBram Moolenaar funcs = split(execute('call DefListOne()'), "\n") 5886abdcf82SBram Moolenaar assert_equal([' def DefListOne()', '1 def DefListOne', ' enddef'], funcs) 5896abdcf82SBram Moolenaar 5906abdcf82SBram Moolenaar funcs = split(execute('call DefListMatches()'), "\n") 5916abdcf82SBram Moolenaar assert_true(len(funcs) >= 3) 5926abdcf82SBram Moolenaar assert_true(funcs->index('def DefListAll()') >= 0) 5936abdcf82SBram Moolenaar assert_true(funcs->index('def DefListOne()') >= 0) 5946abdcf82SBram Moolenaar assert_true(funcs->index('def DefListMatches()') >= 0) 59554021758SBram Moolenaar 59654021758SBram Moolenaar var lines =<< trim END 59754021758SBram Moolenaar vim9script 59854021758SBram Moolenaar def Func() 59954021758SBram Moolenaar def +Func+ 60054021758SBram Moolenaar enddef 60154021758SBram Moolenaar defcompile 60254021758SBram Moolenaar END 60354021758SBram Moolenaar CheckScriptFailure(lines, 'E476:', 1) 6046abdcf82SBram Moolenaarenddef 6056abdcf82SBram Moolenaar 606333894b1SBram Moolenaardef Test_global_local_function() 6077a9cbca0SBram Moolenaar var lines =<< trim END 608333894b1SBram Moolenaar vim9script 609333894b1SBram Moolenaar def g:Func(): string 610333894b1SBram Moolenaar return 'global' 611333894b1SBram Moolenaar enddef 612333894b1SBram Moolenaar def Func(): string 613333894b1SBram Moolenaar return 'local' 614333894b1SBram Moolenaar enddef 615c0c71e9dSBram Moolenaar g:Func()->assert_equal('global') 616c0c71e9dSBram Moolenaar Func()->assert_equal('local') 6172d870f8dSBram Moolenaar delfunc g:Func 618333894b1SBram Moolenaar END 619333894b1SBram Moolenaar CheckScriptSuccess(lines) 620035d6e91SBram Moolenaar 621035d6e91SBram Moolenaar lines =<< trim END 622035d6e91SBram Moolenaar vim9script 623035d6e91SBram Moolenaar def g:Funcy() 624035d6e91SBram Moolenaar echo 'funcy' 625035d6e91SBram Moolenaar enddef 626035d6e91SBram Moolenaar s:Funcy() 627035d6e91SBram Moolenaar END 628035d6e91SBram Moolenaar CheckScriptFailure(lines, 'E117:') 629333894b1SBram Moolenaarenddef 630333894b1SBram Moolenaar 6310f769815SBram Moolenaardef Test_local_function_shadows_global() 6327a9cbca0SBram Moolenaar var lines =<< trim END 6330f769815SBram Moolenaar vim9script 6340f769815SBram Moolenaar def g:Gfunc(): string 6350f769815SBram Moolenaar return 'global' 6360f769815SBram Moolenaar enddef 6370f769815SBram Moolenaar def AnotherFunc(): number 6387a9cbca0SBram Moolenaar var Gfunc = function('len') 6390f769815SBram Moolenaar return Gfunc('testing') 6400f769815SBram Moolenaar enddef 6410f769815SBram Moolenaar g:Gfunc()->assert_equal('global') 6420f769815SBram Moolenaar AnotherFunc()->assert_equal(7) 6430f769815SBram Moolenaar delfunc g:Gfunc 6440f769815SBram Moolenaar END 6450f769815SBram Moolenaar CheckScriptSuccess(lines) 6460f769815SBram Moolenaar 6470f769815SBram Moolenaar lines =<< trim END 6480f769815SBram Moolenaar vim9script 6490f769815SBram Moolenaar def g:Func(): string 6500f769815SBram Moolenaar return 'global' 6510f769815SBram Moolenaar enddef 6520f769815SBram Moolenaar def AnotherFunc() 6530f769815SBram Moolenaar g:Func = function('len') 6540f769815SBram Moolenaar enddef 6550f769815SBram Moolenaar AnotherFunc() 6560f769815SBram Moolenaar END 6570f769815SBram Moolenaar CheckScriptFailure(lines, 'E705:') 6580f769815SBram Moolenaar delfunc g:Func 6590865b15bSBram Moolenaar 6600865b15bSBram Moolenaar # global function is found without g: prefix 6610865b15bSBram Moolenaar lines =<< trim END 6620865b15bSBram Moolenaar vim9script 6630865b15bSBram Moolenaar def g:Func(): string 6640865b15bSBram Moolenaar return 'global' 6650865b15bSBram Moolenaar enddef 6660865b15bSBram Moolenaar def AnotherFunc(): string 6670865b15bSBram Moolenaar return Func() 6680865b15bSBram Moolenaar enddef 6690865b15bSBram Moolenaar assert_equal('global', AnotherFunc()) 6700865b15bSBram Moolenaar delfunc g:Func 6710865b15bSBram Moolenaar END 6720865b15bSBram Moolenaar CheckScriptSuccess(lines) 6730865b15bSBram Moolenaar 6740865b15bSBram Moolenaar lines =<< trim END 6750865b15bSBram Moolenaar vim9script 6760865b15bSBram Moolenaar def g:Func(): string 6770865b15bSBram Moolenaar return 'global' 6780865b15bSBram Moolenaar enddef 6790865b15bSBram Moolenaar assert_equal('global', Func()) 6800865b15bSBram Moolenaar delfunc g:Func 6810865b15bSBram Moolenaar END 6820865b15bSBram Moolenaar CheckScriptSuccess(lines) 6830f769815SBram Moolenaarenddef 6840f769815SBram Moolenaar 6855deeb3f1SBram Moolenaarfunc TakesOneArg(arg) 6865deeb3f1SBram Moolenaar echo a:arg 6875deeb3f1SBram Moolenaarendfunc 6885deeb3f1SBram Moolenaar 6895deeb3f1SBram Moolenaardef Test_call_wrong_args() 690d2c61705SBram Moolenaar CheckDefFailure(['TakesOneArg()'], 'E119:') 691d2c61705SBram Moolenaar CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 692d2c61705SBram Moolenaar CheckDefFailure(['bufnr(xxx)'], 'E1001:') 693d2c61705SBram Moolenaar CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 694ee8580e5SBram Moolenaar 6957a9cbca0SBram Moolenaar var lines =<< trim END 696ee8580e5SBram Moolenaar vim9script 697ee8580e5SBram Moolenaar def Func(s: string) 698ee8580e5SBram Moolenaar echo s 699ee8580e5SBram Moolenaar enddef 700ee8580e5SBram Moolenaar Func([]) 701ee8580e5SBram Moolenaar END 7027707228aSBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5) 703b185a407SBram Moolenaar 704b185a407SBram Moolenaar lines =<< trim END 705b185a407SBram Moolenaar vim9script 706b4893b84SBram Moolenaar var name = 'piet' 707b4893b84SBram Moolenaar def FuncOne(name: string) 708b4893b84SBram Moolenaar echo nr 709b4893b84SBram Moolenaar enddef 710b4893b84SBram Moolenaar END 711057e84afSBram Moolenaar CheckScriptFailure(lines, 'E1168:') 712b4893b84SBram Moolenaar 713b4893b84SBram Moolenaar lines =<< trim END 714b4893b84SBram Moolenaar vim9script 715b185a407SBram Moolenaar def FuncOne(nr: number) 716b185a407SBram Moolenaar echo nr 717b185a407SBram Moolenaar enddef 718b185a407SBram Moolenaar def FuncTwo() 719b185a407SBram Moolenaar FuncOne() 720b185a407SBram Moolenaar enddef 721b185a407SBram Moolenaar defcompile 722b185a407SBram Moolenaar END 723b185a407SBram Moolenaar writefile(lines, 'Xscript') 7247a9cbca0SBram Moolenaar var didCatch = false 725b185a407SBram Moolenaar try 726b185a407SBram Moolenaar source Xscript 727b185a407SBram Moolenaar catch 728b185a407SBram Moolenaar assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception) 729b185a407SBram Moolenaar assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 730b185a407SBram Moolenaar didCatch = true 731b185a407SBram Moolenaar endtry 732b185a407SBram Moolenaar assert_true(didCatch) 733b185a407SBram Moolenaar 734b185a407SBram Moolenaar lines =<< trim END 735b185a407SBram Moolenaar vim9script 736b185a407SBram Moolenaar def FuncOne(nr: number) 737b185a407SBram Moolenaar echo nr 738b185a407SBram Moolenaar enddef 739b185a407SBram Moolenaar def FuncTwo() 740b185a407SBram Moolenaar FuncOne(1, 2) 741b185a407SBram Moolenaar enddef 742b185a407SBram Moolenaar defcompile 743b185a407SBram Moolenaar END 744b185a407SBram Moolenaar writefile(lines, 'Xscript') 745b185a407SBram Moolenaar didCatch = false 746b185a407SBram Moolenaar try 747b185a407SBram Moolenaar source Xscript 748b185a407SBram Moolenaar catch 749b185a407SBram Moolenaar assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception) 750b185a407SBram Moolenaar assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 751b185a407SBram Moolenaar didCatch = true 752b185a407SBram Moolenaar endtry 753b185a407SBram Moolenaar assert_true(didCatch) 754b185a407SBram Moolenaar 755b185a407SBram Moolenaar delete('Xscript') 7565deeb3f1SBram Moolenaarenddef 7575deeb3f1SBram Moolenaar 7585082471fSBram Moolenaardef Test_call_funcref_wrong_args() 7595082471fSBram Moolenaar var head =<< trim END 7605082471fSBram Moolenaar vim9script 7615082471fSBram Moolenaar def Func3(a1: string, a2: number, a3: list<number>) 7625082471fSBram Moolenaar echo a1 .. a2 .. a3[0] 7635082471fSBram Moolenaar enddef 7645082471fSBram Moolenaar def Testme() 7655082471fSBram Moolenaar var funcMap: dict<func> = {func: Func3} 7665082471fSBram Moolenaar END 7675082471fSBram Moolenaar var tail =<< trim END 7685082471fSBram Moolenaar enddef 7695082471fSBram Moolenaar Testme() 7705082471fSBram Moolenaar END 7715082471fSBram Moolenaar CheckScriptSuccess(head + ["funcMap['func']('str', 123, [1, 2, 3])"] + tail) 7725082471fSBram Moolenaar 7735082471fSBram Moolenaar CheckScriptFailure(head + ["funcMap['func']('str', 123)"] + tail, 'E119:') 7745082471fSBram Moolenaar CheckScriptFailure(head + ["funcMap['func']('str', 123, [1], 4)"] + tail, 'E118:') 77532b3f820SBram Moolenaar 77632b3f820SBram Moolenaar var lines =<< trim END 77732b3f820SBram Moolenaar vim9script 77832b3f820SBram Moolenaar var Ref: func(number): any 77932b3f820SBram Moolenaar Ref = (j) => !j 78032b3f820SBram Moolenaar echo Ref(false) 78132b3f820SBram Moolenaar END 78232b3f820SBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4) 78332b3f820SBram Moolenaar 78432b3f820SBram Moolenaar lines =<< trim END 78532b3f820SBram Moolenaar vim9script 78632b3f820SBram Moolenaar var Ref: func(number): any 78732b3f820SBram Moolenaar Ref = (j) => !j 78832b3f820SBram Moolenaar call Ref(false) 78932b3f820SBram Moolenaar END 79032b3f820SBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected number but got bool', 4) 7915082471fSBram Moolenaarenddef 7925082471fSBram Moolenaar 793b4d16cb1SBram Moolenaardef Test_call_lambda_args() 7942a38908bSBram Moolenaar var lines =<< trim END 7952a38908bSBram Moolenaar var Callback = (..._) => 'anything' 7962a38908bSBram Moolenaar assert_equal('anything', Callback()) 7972a38908bSBram Moolenaar assert_equal('anything', Callback(1)) 7982a38908bSBram Moolenaar assert_equal('anything', Callback('a', 2)) 7991088b694SBram Moolenaar 8001088b694SBram Moolenaar assert_equal('xyz', ((a: string): string => a)('xyz')) 8012a38908bSBram Moolenaar END 8022a38908bSBram Moolenaar CheckDefAndScriptSuccess(lines) 8032a38908bSBram Moolenaar 8042949cfdbSBram Moolenaar CheckDefFailure(['echo ((i) => 0)()'], 8052949cfdbSBram Moolenaar 'E119: Not enough arguments for function: ((i) => 0)()') 806b4d16cb1SBram Moolenaar 8072a38908bSBram Moolenaar lines =<< trim END 8082949cfdbSBram Moolenaar var Ref = (x: number, y: number) => x + y 809b4d16cb1SBram Moolenaar echo Ref(1, 'x') 810b4d16cb1SBram Moolenaar END 811b4d16cb1SBram Moolenaar CheckDefFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string') 812e68b02a1SBram Moolenaar 813e68b02a1SBram Moolenaar lines =<< trim END 814e68b02a1SBram Moolenaar var Ref: func(job, string, number) 815e68b02a1SBram Moolenaar Ref = (x, y) => 0 816e68b02a1SBram Moolenaar END 817e68b02a1SBram Moolenaar CheckDefAndScriptFailure(lines, 'E1012:') 818e68b02a1SBram Moolenaar 819e68b02a1SBram Moolenaar lines =<< trim END 820e68b02a1SBram Moolenaar var Ref: func(job, string) 821e68b02a1SBram Moolenaar Ref = (x, y, z) => 0 822e68b02a1SBram Moolenaar END 823e68b02a1SBram Moolenaar CheckDefAndScriptFailure(lines, 'E1012:') 824057e84afSBram Moolenaar 825057e84afSBram Moolenaar lines =<< trim END 826057e84afSBram Moolenaar var one = 1 827057e84afSBram Moolenaar var l = [1, 2, 3] 828057e84afSBram Moolenaar echo map(l, (one) => one) 829057e84afSBram Moolenaar END 830057e84afSBram Moolenaar CheckDefFailure(lines, 'E1167:') 831057e84afSBram Moolenaar CheckScriptFailure(['vim9script'] + lines, 'E1168:') 832057e84afSBram Moolenaar 833057e84afSBram Moolenaar lines =<< trim END 834057e84afSBram Moolenaar def ShadowLocal() 835057e84afSBram Moolenaar var one = 1 836057e84afSBram Moolenaar var l = [1, 2, 3] 837057e84afSBram Moolenaar echo map(l, (one) => one) 838057e84afSBram Moolenaar enddef 839057e84afSBram Moolenaar END 840057e84afSBram Moolenaar CheckDefFailure(lines, 'E1167:') 841057e84afSBram Moolenaar 842057e84afSBram Moolenaar lines =<< trim END 843057e84afSBram Moolenaar def Shadowarg(one: number) 844057e84afSBram Moolenaar var l = [1, 2, 3] 845057e84afSBram Moolenaar echo map(l, (one) => one) 846057e84afSBram Moolenaar enddef 847057e84afSBram Moolenaar END 848057e84afSBram Moolenaar CheckDefFailure(lines, 'E1167:') 849767034c5SBram Moolenaar 850767034c5SBram Moolenaar lines =<< trim END 851767034c5SBram Moolenaar echo ((a) => a)('aa', 'bb') 852767034c5SBram Moolenaar END 853767034c5SBram Moolenaar CheckDefAndScriptFailure(lines, 'E118:', 1) 854b4d16cb1SBram Moolenaarenddef 855b4d16cb1SBram Moolenaar 8565f91e74bSBram Moolenaardef FilterWithCond(x: string, Cond: func(string): bool): bool 8575f91e74bSBram Moolenaar return Cond(x) 8585f91e74bSBram Moolenaarenddef 8595f91e74bSBram Moolenaar 8600346b799SBram Moolenaardef Test_lambda_return_type() 8610346b799SBram Moolenaar var lines =<< trim END 8620346b799SBram Moolenaar var Ref = (): => 123 8630346b799SBram Moolenaar END 8640346b799SBram Moolenaar CheckDefAndScriptFailure(lines, 'E1157:', 1) 8655f91e74bSBram Moolenaar 8665f91e74bSBram Moolenaar # this works 8675f91e74bSBram Moolenaar for x in ['foo', 'boo'] 8685f91e74bSBram Moolenaar echo FilterWithCond(x, (v) => v =~ '^b') 8695f91e74bSBram Moolenaar endfor 8705f91e74bSBram Moolenaar 8715f91e74bSBram Moolenaar # this fails 8725f91e74bSBram Moolenaar lines =<< trim END 8735f91e74bSBram Moolenaar echo FilterWithCond('foo', (v) => v .. '^b') 8745f91e74bSBram Moolenaar END 8755f91e74bSBram Moolenaar CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1) 8760346b799SBram Moolenaarenddef 8770346b799SBram Moolenaar 878709664ccSBram Moolenaardef Test_lambda_uses_assigned_var() 879709664ccSBram Moolenaar CheckDefSuccess([ 880709664ccSBram Moolenaar 'var x: any = "aaa"' 8812949cfdbSBram Moolenaar 'x = filter(["bbb"], (_, v) => v =~ x)']) 882709664ccSBram Moolenaarenddef 883709664ccSBram Moolenaar 88418062fcaSBram Moolenaardef Test_pass_legacy_lambda_to_def_func() 88518062fcaSBram Moolenaar var lines =<< trim END 88618062fcaSBram Moolenaar vim9script 88718062fcaSBram Moolenaar func Foo() 88818062fcaSBram Moolenaar eval s:Bar({x -> 0}) 88918062fcaSBram Moolenaar endfunc 89018062fcaSBram Moolenaar def Bar(y: any) 89118062fcaSBram Moolenaar enddef 89218062fcaSBram Moolenaar Foo() 89318062fcaSBram Moolenaar END 89418062fcaSBram Moolenaar CheckScriptSuccess(lines) 89518062fcaSBram Moolenaarenddef 89618062fcaSBram Moolenaar 8975deeb3f1SBram Moolenaar" Default arg and varargs 8985deeb3f1SBram Moolenaardef MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 8997a9cbca0SBram Moolenaar var res = one .. ',' .. two 9005deeb3f1SBram Moolenaar for s in rest 9015deeb3f1SBram Moolenaar res ..= ',' .. s 9025deeb3f1SBram Moolenaar endfor 9035deeb3f1SBram Moolenaar return res 9045deeb3f1SBram Moolenaarenddef 9055deeb3f1SBram Moolenaar 9065deeb3f1SBram Moolenaardef Test_call_def_varargs() 9079bd5d879SBram Moolenaar assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs') 908c0c71e9dSBram Moolenaar MyDefVarargs('one')->assert_equal('one,foo') 909c0c71e9dSBram Moolenaar MyDefVarargs('one', 'two')->assert_equal('one,two') 910c0c71e9dSBram Moolenaar MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three') 91124aa48b7SBram Moolenaar CheckDefFailure(['MyDefVarargs("one", 22)'], 9127707228aSBram Moolenaar 'E1013: Argument 2: type mismatch, expected string but got number') 91324aa48b7SBram Moolenaar CheckDefFailure(['MyDefVarargs("one", "two", 123)'], 9147707228aSBram Moolenaar 'E1013: Argument 3: type mismatch, expected string but got number') 91524aa48b7SBram Moolenaar 9167a9cbca0SBram Moolenaar var lines =<< trim END 91724aa48b7SBram Moolenaar vim9script 91824aa48b7SBram Moolenaar def Func(...l: list<string>) 91924aa48b7SBram Moolenaar echo l 92024aa48b7SBram Moolenaar enddef 92124aa48b7SBram Moolenaar Func('a', 'b', 'c') 92224aa48b7SBram Moolenaar END 92324aa48b7SBram Moolenaar CheckScriptSuccess(lines) 92424aa48b7SBram Moolenaar 92524aa48b7SBram Moolenaar lines =<< trim END 92624aa48b7SBram Moolenaar vim9script 92724aa48b7SBram Moolenaar def Func(...l: list<string>) 92824aa48b7SBram Moolenaar echo l 92924aa48b7SBram Moolenaar enddef 93024aa48b7SBram Moolenaar Func() 93124aa48b7SBram Moolenaar END 93224aa48b7SBram Moolenaar CheckScriptSuccess(lines) 93324aa48b7SBram Moolenaar 93424aa48b7SBram Moolenaar lines =<< trim END 93524aa48b7SBram Moolenaar vim9script 9362a38908bSBram Moolenaar def Func(...l: list<any>) 9372f8cbc4bSBram Moolenaar echo l 9382f8cbc4bSBram Moolenaar enddef 9392f8cbc4bSBram Moolenaar Func(0) 9402f8cbc4bSBram Moolenaar END 9412f8cbc4bSBram Moolenaar CheckScriptSuccess(lines) 9422f8cbc4bSBram Moolenaar 9432f8cbc4bSBram Moolenaar lines =<< trim END 9442f8cbc4bSBram Moolenaar vim9script 9452a38908bSBram Moolenaar def Func(...l: any) 9462a38908bSBram Moolenaar echo l 9472a38908bSBram Moolenaar enddef 9482a38908bSBram Moolenaar Func(0) 9492a38908bSBram Moolenaar END 9502a38908bSBram Moolenaar CheckScriptFailure(lines, 'E1180:', 2) 9512a38908bSBram Moolenaar 9522a38908bSBram Moolenaar lines =<< trim END 9532a38908bSBram Moolenaar vim9script 95428022727SBram Moolenaar def Func(..._l: list<string>) 95528022727SBram Moolenaar echo _l 95628022727SBram Moolenaar enddef 95728022727SBram Moolenaar Func('a', 'b', 'c') 95828022727SBram Moolenaar END 95928022727SBram Moolenaar CheckScriptSuccess(lines) 96028022727SBram Moolenaar 96128022727SBram Moolenaar lines =<< trim END 96228022727SBram Moolenaar vim9script 96324aa48b7SBram Moolenaar def Func(...l: list<string>) 96424aa48b7SBram Moolenaar echo l 96524aa48b7SBram Moolenaar enddef 96624aa48b7SBram Moolenaar Func(1, 2, 3) 96724aa48b7SBram Moolenaar END 9687707228aSBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 96924aa48b7SBram Moolenaar 97024aa48b7SBram Moolenaar lines =<< trim END 97124aa48b7SBram Moolenaar vim9script 97224aa48b7SBram Moolenaar def Func(...l: list<string>) 97324aa48b7SBram Moolenaar echo l 97424aa48b7SBram Moolenaar enddef 97524aa48b7SBram Moolenaar Func('a', 9) 97624aa48b7SBram Moolenaar END 9777707228aSBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch') 97824aa48b7SBram Moolenaar 97924aa48b7SBram Moolenaar lines =<< trim END 98024aa48b7SBram Moolenaar vim9script 98124aa48b7SBram Moolenaar def Func(...l: list<string>) 98224aa48b7SBram Moolenaar echo l 98324aa48b7SBram Moolenaar enddef 98424aa48b7SBram Moolenaar Func(1, 'a') 98524aa48b7SBram Moolenaar END 9867707228aSBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 9874f53b79bSBram Moolenaar 9884f53b79bSBram Moolenaar lines =<< trim END 9894f53b79bSBram Moolenaar vim9script 9904f53b79bSBram Moolenaar def Func( # some comment 9914f53b79bSBram Moolenaar ...l = [] 9924f53b79bSBram Moolenaar ) 9934f53b79bSBram Moolenaar echo l 9944f53b79bSBram Moolenaar enddef 9954f53b79bSBram Moolenaar END 9964f53b79bSBram Moolenaar CheckScriptFailure(lines, 'E1160:') 9975deeb3f1SBram Moolenaarenddef 9985deeb3f1SBram Moolenaar 9991378fbc4SBram Moolenaarlet s:value = '' 10001378fbc4SBram Moolenaar 10011378fbc4SBram Moolenaardef FuncOneDefArg(opt = 'text') 10021378fbc4SBram Moolenaar s:value = opt 10031378fbc4SBram Moolenaarenddef 10041378fbc4SBram Moolenaar 10051378fbc4SBram Moolenaardef FuncTwoDefArg(nr = 123, opt = 'text'): string 10061378fbc4SBram Moolenaar return nr .. opt 10071378fbc4SBram Moolenaarenddef 10081378fbc4SBram Moolenaar 10091378fbc4SBram Moolenaardef FuncVarargs(...arg: list<string>): string 10101378fbc4SBram Moolenaar return join(arg, ',') 10111378fbc4SBram Moolenaarenddef 10121378fbc4SBram Moolenaar 10131378fbc4SBram Moolenaardef Test_func_type_varargs() 10147a9cbca0SBram Moolenaar var RefDefArg: func(?string) 10151378fbc4SBram Moolenaar RefDefArg = FuncOneDefArg 10161378fbc4SBram Moolenaar RefDefArg() 1017c0c71e9dSBram Moolenaar s:value->assert_equal('text') 10181378fbc4SBram Moolenaar RefDefArg('some') 1019c0c71e9dSBram Moolenaar s:value->assert_equal('some') 10201378fbc4SBram Moolenaar 10217a9cbca0SBram Moolenaar var RefDef2Arg: func(?number, ?string): string 10221378fbc4SBram Moolenaar RefDef2Arg = FuncTwoDefArg 1023c0c71e9dSBram Moolenaar RefDef2Arg()->assert_equal('123text') 1024c0c71e9dSBram Moolenaar RefDef2Arg(99)->assert_equal('99text') 1025c0c71e9dSBram Moolenaar RefDef2Arg(77, 'some')->assert_equal('77some') 10261378fbc4SBram Moolenaar 10277a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:') 10287a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:') 10291378fbc4SBram Moolenaar 10307a9cbca0SBram Moolenaar var RefVarargs: func(...list<string>): string 10311378fbc4SBram Moolenaar RefVarargs = FuncVarargs 1032c0c71e9dSBram Moolenaar RefVarargs()->assert_equal('') 1033c0c71e9dSBram Moolenaar RefVarargs('one')->assert_equal('one') 1034c0c71e9dSBram Moolenaar RefVarargs('one', 'two')->assert_equal('one,two') 10351378fbc4SBram Moolenaar 10367a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:') 10377a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:') 10381378fbc4SBram Moolenaarenddef 10391378fbc4SBram Moolenaar 10400b76b42dSBram Moolenaar" Only varargs 10410b76b42dSBram Moolenaardef MyVarargsOnly(...args: list<string>): string 10420b76b42dSBram Moolenaar return join(args, ',') 10430b76b42dSBram Moolenaarenddef 10440b76b42dSBram Moolenaar 10450b76b42dSBram Moolenaardef Test_call_varargs_only() 1046c0c71e9dSBram Moolenaar MyVarargsOnly()->assert_equal('') 1047c0c71e9dSBram Moolenaar MyVarargsOnly('one')->assert_equal('one') 1048c0c71e9dSBram Moolenaar MyVarargsOnly('one', 'two')->assert_equal('one,two') 10497707228aSBram Moolenaar CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number') 10507707228aSBram Moolenaar CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number') 10510b76b42dSBram Moolenaarenddef 10520b76b42dSBram Moolenaar 10535deeb3f1SBram Moolenaardef Test_using_var_as_arg() 10547a9cbca0SBram Moolenaar writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef') 10559bd5d879SBram Moolenaar assert_fails('so Xdef', 'E1006:', '', 1, 'Func') 1056d2c61705SBram Moolenaar delete('Xdef') 10575deeb3f1SBram Moolenaarenddef 10585deeb3f1SBram Moolenaar 1059cb2bdb1cSBram Moolenaardef DictArg(arg: dict<string>) 1060cb2bdb1cSBram Moolenaar arg['key'] = 'value' 1061cb2bdb1cSBram Moolenaarenddef 1062cb2bdb1cSBram Moolenaar 1063cb2bdb1cSBram Moolenaardef ListArg(arg: list<string>) 1064cb2bdb1cSBram Moolenaar arg[0] = 'value' 1065cb2bdb1cSBram Moolenaarenddef 1066cb2bdb1cSBram Moolenaar 1067cb2bdb1cSBram Moolenaardef Test_assign_to_argument() 1068f5be8cdbSBram Moolenaar # works for dict and list 10697a9cbca0SBram Moolenaar var d: dict<string> = {} 1070cb2bdb1cSBram Moolenaar DictArg(d) 1071c0c71e9dSBram Moolenaar d['key']->assert_equal('value') 10727a9cbca0SBram Moolenaar var l: list<string> = [] 1073cb2bdb1cSBram Moolenaar ListArg(l) 1074c0c71e9dSBram Moolenaar l[0]->assert_equal('value') 1075cb2bdb1cSBram Moolenaar 1076d2c61705SBram Moolenaar CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 10772d870f8dSBram Moolenaar delfunc! g:Func 1078cb2bdb1cSBram Moolenaarenddef 1079cb2bdb1cSBram Moolenaar 1080b816dae1SBram Moolenaar" These argument names are reserved in legacy functions. 1081b816dae1SBram Moolenaardef WithReservedNames(firstline: string, lastline: string): string 1082b816dae1SBram Moolenaar return firstline .. lastline 1083b816dae1SBram Moolenaarenddef 1084b816dae1SBram Moolenaar 1085b816dae1SBram Moolenaardef Test_argument_names() 1086b816dae1SBram Moolenaar assert_equal('OK', WithReservedNames('O', 'K')) 1087b816dae1SBram Moolenaarenddef 1088b816dae1SBram Moolenaar 10895deeb3f1SBram Moolenaardef Test_call_func_defined_later() 1090c0c71e9dSBram Moolenaar g:DefinedLater('one')->assert_equal('one') 10919bd5d879SBram Moolenaar assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') 10925deeb3f1SBram Moolenaarenddef 10935deeb3f1SBram Moolenaar 10941df8b3fbSBram Moolenaarfunc DefinedLater(arg) 10951df8b3fbSBram Moolenaar return a:arg 10961df8b3fbSBram Moolenaarendfunc 10971df8b3fbSBram Moolenaar 10981df8b3fbSBram Moolenaardef Test_call_funcref() 1099c0c71e9dSBram Moolenaar g:SomeFunc('abc')->assert_equal(3) 11009bd5d879SBram Moolenaar assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call 11019bd5d879SBram Moolenaar assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') 11022f1980f7SBram Moolenaar 11037a9cbca0SBram Moolenaar var lines =<< trim END 11042f1980f7SBram Moolenaar vim9script 11052f1980f7SBram Moolenaar def RetNumber(): number 11062f1980f7SBram Moolenaar return 123 11072f1980f7SBram Moolenaar enddef 11087a9cbca0SBram Moolenaar var Funcref: func: number = function('RetNumber') 1109c0c71e9dSBram Moolenaar Funcref()->assert_equal(123) 11102f1980f7SBram Moolenaar END 11112f1980f7SBram Moolenaar CheckScriptSuccess(lines) 11120f60e80fSBram Moolenaar 11130f60e80fSBram Moolenaar lines =<< trim END 11140f60e80fSBram Moolenaar vim9script 11150f60e80fSBram Moolenaar def RetNumber(): number 11160f60e80fSBram Moolenaar return 123 11170f60e80fSBram Moolenaar enddef 11180f60e80fSBram Moolenaar def Bar(F: func: number): number 11190f60e80fSBram Moolenaar return F() 11200f60e80fSBram Moolenaar enddef 11217a9cbca0SBram Moolenaar var Funcref = function('RetNumber') 1122c0c71e9dSBram Moolenaar Bar(Funcref)->assert_equal(123) 11230f60e80fSBram Moolenaar END 11240f60e80fSBram Moolenaar CheckScriptSuccess(lines) 1125bfba8651SBram Moolenaar 1126bfba8651SBram Moolenaar lines =<< trim END 1127bfba8651SBram Moolenaar vim9script 1128bfba8651SBram Moolenaar def UseNumber(nr: number) 1129bfba8651SBram Moolenaar echo nr 1130bfba8651SBram Moolenaar enddef 11317a9cbca0SBram Moolenaar var Funcref: func(number) = function('UseNumber') 1132bfba8651SBram Moolenaar Funcref(123) 1133bfba8651SBram Moolenaar END 1134bfba8651SBram Moolenaar CheckScriptSuccess(lines) 1135b8070e31SBram Moolenaar 1136b8070e31SBram Moolenaar lines =<< trim END 1137b8070e31SBram Moolenaar vim9script 1138b8070e31SBram Moolenaar def UseNumber(nr: number) 1139b8070e31SBram Moolenaar echo nr 1140b8070e31SBram Moolenaar enddef 11417a9cbca0SBram Moolenaar var Funcref: func(string) = function('UseNumber') 1142b8070e31SBram Moolenaar END 11435e654230SBram Moolenaar CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)') 11444fc224caSBram Moolenaar 11454fc224caSBram Moolenaar lines =<< trim END 11464fc224caSBram Moolenaar vim9script 11474fc224caSBram Moolenaar def EchoNr(nr = 34) 11484fc224caSBram Moolenaar g:echo = nr 11494fc224caSBram Moolenaar enddef 11507a9cbca0SBram Moolenaar var Funcref: func(?number) = function('EchoNr') 11514fc224caSBram Moolenaar Funcref() 1152c0c71e9dSBram Moolenaar g:echo->assert_equal(34) 11534fc224caSBram Moolenaar Funcref(123) 1154c0c71e9dSBram Moolenaar g:echo->assert_equal(123) 11554fc224caSBram Moolenaar END 11564fc224caSBram Moolenaar CheckScriptSuccess(lines) 1157ace6132aSBram Moolenaar 1158ace6132aSBram Moolenaar lines =<< trim END 1159ace6132aSBram Moolenaar vim9script 1160ace6132aSBram Moolenaar def EchoList(...l: list<number>) 1161ace6132aSBram Moolenaar g:echo = l 1162ace6132aSBram Moolenaar enddef 11637a9cbca0SBram Moolenaar var Funcref: func(...list<number>) = function('EchoList') 1164ace6132aSBram Moolenaar Funcref() 1165c0c71e9dSBram Moolenaar g:echo->assert_equal([]) 1166ace6132aSBram Moolenaar Funcref(1, 2, 3) 1167c0c71e9dSBram Moolenaar g:echo->assert_equal([1, 2, 3]) 1168ace6132aSBram Moolenaar END 1169ace6132aSBram Moolenaar CheckScriptSuccess(lines) 117001865adeSBram Moolenaar 117101865adeSBram Moolenaar lines =<< trim END 117201865adeSBram Moolenaar vim9script 117301865adeSBram Moolenaar def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 117401865adeSBram Moolenaar g:optarg = opt 117501865adeSBram Moolenaar g:listarg = l 117601865adeSBram Moolenaar return nr 117701865adeSBram Moolenaar enddef 11787a9cbca0SBram Moolenaar var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 1179c0c71e9dSBram Moolenaar Funcref(10)->assert_equal(10) 1180c0c71e9dSBram Moolenaar g:optarg->assert_equal(12) 1181c0c71e9dSBram Moolenaar g:listarg->assert_equal([]) 118201865adeSBram Moolenaar 1183c0c71e9dSBram Moolenaar Funcref(11, 22)->assert_equal(11) 1184c0c71e9dSBram Moolenaar g:optarg->assert_equal(22) 1185c0c71e9dSBram Moolenaar g:listarg->assert_equal([]) 118601865adeSBram Moolenaar 1187c0c71e9dSBram Moolenaar Funcref(17, 18, 1, 2, 3)->assert_equal(17) 1188c0c71e9dSBram Moolenaar g:optarg->assert_equal(18) 1189c0c71e9dSBram Moolenaar g:listarg->assert_equal([1, 2, 3]) 119001865adeSBram Moolenaar END 119101865adeSBram Moolenaar CheckScriptSuccess(lines) 11921df8b3fbSBram Moolenaarenddef 11931df8b3fbSBram Moolenaar 11941df8b3fbSBram Moolenaarlet SomeFunc = function('len') 11951df8b3fbSBram Moolenaarlet NotAFunc = 'text' 11961df8b3fbSBram Moolenaar 119799aaf0ceSBram Moolenaardef CombineFuncrefTypes() 1198f5be8cdbSBram Moolenaar # same arguments, different return type 11997a9cbca0SBram Moolenaar var Ref1: func(bool): string 12007a9cbca0SBram Moolenaar var Ref2: func(bool): number 12017a9cbca0SBram Moolenaar var Ref3: func(bool): any 120299aaf0ceSBram Moolenaar Ref3 = g:cond ? Ref1 : Ref2 120399aaf0ceSBram Moolenaar 1204f5be8cdbSBram Moolenaar # different number of arguments 12057a9cbca0SBram Moolenaar var Refa1: func(bool): number 12067a9cbca0SBram Moolenaar var Refa2: func(bool, number): number 12077a9cbca0SBram Moolenaar var Refa3: func: number 120899aaf0ceSBram Moolenaar Refa3 = g:cond ? Refa1 : Refa2 120999aaf0ceSBram Moolenaar 1210f5be8cdbSBram Moolenaar # different argument types 12117a9cbca0SBram Moolenaar var Refb1: func(bool, string): number 12127a9cbca0SBram Moolenaar var Refb2: func(string, number): number 12137a9cbca0SBram Moolenaar var Refb3: func(any, any): number 121499aaf0ceSBram Moolenaar Refb3 = g:cond ? Refb1 : Refb2 121599aaf0ceSBram Moolenaarenddef 121699aaf0ceSBram Moolenaar 12175deeb3f1SBram Moolenaardef FuncWithForwardCall() 12181df8b3fbSBram Moolenaar return g:DefinedEvenLater("yes") 12195deeb3f1SBram Moolenaarenddef 12205deeb3f1SBram Moolenaar 12215deeb3f1SBram Moolenaardef DefinedEvenLater(arg: string): string 12225deeb3f1SBram Moolenaar return arg 12235deeb3f1SBram Moolenaarenddef 12245deeb3f1SBram Moolenaar 12255deeb3f1SBram Moolenaardef Test_error_in_nested_function() 1226f5be8cdbSBram Moolenaar # Error in called function requires unwinding the call stack. 122744d6652dSBram Moolenaar assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall') 12285deeb3f1SBram Moolenaarenddef 12295deeb3f1SBram Moolenaar 12305deeb3f1SBram Moolenaardef Test_return_type_wrong() 12315a849da5SBram Moolenaar CheckScriptFailure([ 12325a849da5SBram Moolenaar 'def Func(): number', 12335a849da5SBram Moolenaar 'return "a"', 12345a849da5SBram Moolenaar 'enddef', 12355a849da5SBram Moolenaar 'defcompile'], 'expected number but got string') 12362d870f8dSBram Moolenaar delfunc! g:Func 12375a849da5SBram Moolenaar CheckScriptFailure([ 12385a849da5SBram Moolenaar 'def Func(): string', 12395a849da5SBram Moolenaar 'return 1', 12405a849da5SBram Moolenaar 'enddef', 12415a849da5SBram Moolenaar 'defcompile'], 'expected string but got number') 12422d870f8dSBram Moolenaar delfunc! g:Func 12435a849da5SBram Moolenaar CheckScriptFailure([ 12445a849da5SBram Moolenaar 'def Func(): void', 12455a849da5SBram Moolenaar 'return "a"', 12465a849da5SBram Moolenaar 'enddef', 12475a849da5SBram Moolenaar 'defcompile'], 12485a849da5SBram Moolenaar 'E1096: Returning a value in a function without a return type') 12492d870f8dSBram Moolenaar delfunc! g:Func 12505a849da5SBram Moolenaar CheckScriptFailure([ 12515a849da5SBram Moolenaar 'def Func()', 12525a849da5SBram Moolenaar 'return "a"', 12535a849da5SBram Moolenaar 'enddef', 12545a849da5SBram Moolenaar 'defcompile'], 12555a849da5SBram Moolenaar 'E1096: Returning a value in a function without a return type') 12562d870f8dSBram Moolenaar delfunc! g:Func 12575deeb3f1SBram Moolenaar 12585a849da5SBram Moolenaar CheckScriptFailure([ 12595a849da5SBram Moolenaar 'def Func(): number', 12605a849da5SBram Moolenaar 'return', 12615a849da5SBram Moolenaar 'enddef', 12625a849da5SBram Moolenaar 'defcompile'], 'E1003:') 12632d870f8dSBram Moolenaar delfunc! g:Func 12645deeb3f1SBram Moolenaar 12655deeb3f1SBram Moolenaar CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 12662d870f8dSBram Moolenaar delfunc! g:Func 12675deeb3f1SBram Moolenaar CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 12682d870f8dSBram Moolenaar delfunc! g:Func 1269ee4e0c1eSBram Moolenaar CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 12702d870f8dSBram Moolenaar delfunc! g:Func 12715a849da5SBram Moolenaar 12725a849da5SBram Moolenaar CheckScriptFailure([ 12735a849da5SBram Moolenaar 'vim9script', 12745a849da5SBram Moolenaar 'def FuncB()', 12755a849da5SBram Moolenaar ' return 123', 12765a849da5SBram Moolenaar 'enddef', 12775a849da5SBram Moolenaar 'def FuncA()', 12785a849da5SBram Moolenaar ' FuncB()', 12795a849da5SBram Moolenaar 'enddef', 12805a849da5SBram Moolenaar 'defcompile'], 'E1096:') 12815deeb3f1SBram Moolenaarenddef 12825deeb3f1SBram Moolenaar 12835deeb3f1SBram Moolenaardef Test_arg_type_wrong() 12845deeb3f1SBram Moolenaar CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 1285ee4e0c1eSBram Moolenaar CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 1286f93c7feaSBram Moolenaar CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 12876e949784SBram Moolenaar CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 12885deeb3f1SBram Moolenaarenddef 12895deeb3f1SBram Moolenaar 129086cdb8a4SBram Moolenaardef Test_white_space_before_comma() 129186cdb8a4SBram Moolenaar var lines =<< trim END 129286cdb8a4SBram Moolenaar vim9script 129386cdb8a4SBram Moolenaar def Func(a: number , b: number) 129486cdb8a4SBram Moolenaar enddef 129586cdb8a4SBram Moolenaar END 129686cdb8a4SBram Moolenaar CheckScriptFailure(lines, 'E1068:') 129786cdb8a4SBram Moolenaarenddef 129886cdb8a4SBram Moolenaar 1299608d78fbSBram Moolenaardef Test_white_space_after_comma() 1300608d78fbSBram Moolenaar var lines =<< trim END 1301608d78fbSBram Moolenaar vim9script 1302608d78fbSBram Moolenaar def Func(a: number,b: number) 1303608d78fbSBram Moolenaar enddef 1304608d78fbSBram Moolenaar END 1305608d78fbSBram Moolenaar CheckScriptFailure(lines, 'E1069:') 1306608d78fbSBram Moolenaar 1307608d78fbSBram Moolenaar # OK in legacy function 1308608d78fbSBram Moolenaar lines =<< trim END 1309608d78fbSBram Moolenaar vim9script 1310608d78fbSBram Moolenaar func Func(a,b) 1311608d78fbSBram Moolenaar endfunc 1312608d78fbSBram Moolenaar END 1313608d78fbSBram Moolenaar CheckScriptSuccess(lines) 1314608d78fbSBram Moolenaarenddef 1315608d78fbSBram Moolenaar 13165deeb3f1SBram Moolenaardef Test_vim9script_call() 13177a9cbca0SBram Moolenaar var lines =<< trim END 13185deeb3f1SBram Moolenaar vim9script 13197a9cbca0SBram Moolenaar var name = '' 13205deeb3f1SBram Moolenaar def MyFunc(arg: string) 13217a9cbca0SBram Moolenaar name = arg 13225deeb3f1SBram Moolenaar enddef 13235deeb3f1SBram Moolenaar MyFunc('foobar') 13247a9cbca0SBram Moolenaar name->assert_equal('foobar') 13255deeb3f1SBram Moolenaar 13267a9cbca0SBram Moolenaar var str = 'barfoo' 13275deeb3f1SBram Moolenaar str->MyFunc() 13287a9cbca0SBram Moolenaar name->assert_equal('barfoo') 13295deeb3f1SBram Moolenaar 13306797966dSBram Moolenaar g:value = 'value' 13315deeb3f1SBram Moolenaar g:value->MyFunc() 13327a9cbca0SBram Moolenaar name->assert_equal('value') 13335deeb3f1SBram Moolenaar 13347a9cbca0SBram Moolenaar var listvar = [] 13355deeb3f1SBram Moolenaar def ListFunc(arg: list<number>) 13365deeb3f1SBram Moolenaar listvar = arg 13375deeb3f1SBram Moolenaar enddef 13385deeb3f1SBram Moolenaar [1, 2, 3]->ListFunc() 1339c0c71e9dSBram Moolenaar listvar->assert_equal([1, 2, 3]) 13405deeb3f1SBram Moolenaar 13417a9cbca0SBram Moolenaar var dictvar = {} 13425deeb3f1SBram Moolenaar def DictFunc(arg: dict<number>) 13435deeb3f1SBram Moolenaar dictvar = arg 13445deeb3f1SBram Moolenaar enddef 1345e0de171eSBram Moolenaar {a: 1, b: 2}->DictFunc() 1346e0de171eSBram Moolenaar dictvar->assert_equal({a: 1, b: 2}) 13475deeb3f1SBram Moolenaar def CompiledDict() 1348e0de171eSBram Moolenaar {a: 3, b: 4}->DictFunc() 13495deeb3f1SBram Moolenaar enddef 13505deeb3f1SBram Moolenaar CompiledDict() 1351e0de171eSBram Moolenaar dictvar->assert_equal({a: 3, b: 4}) 13525deeb3f1SBram Moolenaar 1353e0de171eSBram Moolenaar {a: 3, b: 4}->DictFunc() 1354e0de171eSBram Moolenaar dictvar->assert_equal({a: 3, b: 4}) 13555deeb3f1SBram Moolenaar 13565deeb3f1SBram Moolenaar ('text')->MyFunc() 13577a9cbca0SBram Moolenaar name->assert_equal('text') 13585deeb3f1SBram Moolenaar ("some")->MyFunc() 13597a9cbca0SBram Moolenaar name->assert_equal('some') 1360e6b5324eSBram Moolenaar 136113e12b8aSBram Moolenaar # line starting with single quote is not a mark 136210409562SBram Moolenaar # line starting with double quote can be a method call 13633d48e25dSBram Moolenaar 'asdfasdf'->MyFunc() 13647a9cbca0SBram Moolenaar name->assert_equal('asdfasdf') 136510409562SBram Moolenaar "xyz"->MyFunc() 13667a9cbca0SBram Moolenaar name->assert_equal('xyz') 13673d48e25dSBram Moolenaar 13683d48e25dSBram Moolenaar def UseString() 13693d48e25dSBram Moolenaar 'xyork'->MyFunc() 13703d48e25dSBram Moolenaar enddef 13713d48e25dSBram Moolenaar UseString() 13727a9cbca0SBram Moolenaar name->assert_equal('xyork') 13733d48e25dSBram Moolenaar 137410409562SBram Moolenaar def UseString2() 137510409562SBram Moolenaar "knife"->MyFunc() 137610409562SBram Moolenaar enddef 137710409562SBram Moolenaar UseString2() 13787a9cbca0SBram Moolenaar name->assert_equal('knife') 137910409562SBram Moolenaar 138013e12b8aSBram Moolenaar # prepending a colon makes it a mark 138113e12b8aSBram Moolenaar new 138213e12b8aSBram Moolenaar setline(1, ['aaa', 'bbb', 'ccc']) 138313e12b8aSBram Moolenaar normal! 3Gmt1G 138413e12b8aSBram Moolenaar :'t 1385c0c71e9dSBram Moolenaar getcurpos()[1]->assert_equal(3) 138613e12b8aSBram Moolenaar bwipe! 138713e12b8aSBram Moolenaar 1388e6b5324eSBram Moolenaar MyFunc( 1389e6b5324eSBram Moolenaar 'continued' 1390e6b5324eSBram Moolenaar ) 1391e6b5324eSBram Moolenaar assert_equal('continued', 13927a9cbca0SBram Moolenaar name 1393e6b5324eSBram Moolenaar ) 1394e6b5324eSBram Moolenaar 1395e6b5324eSBram Moolenaar call MyFunc( 1396e6b5324eSBram Moolenaar 'more' 1397e6b5324eSBram Moolenaar .. 1398e6b5324eSBram Moolenaar 'lines' 1399e6b5324eSBram Moolenaar ) 1400e6b5324eSBram Moolenaar assert_equal( 1401e6b5324eSBram Moolenaar 'morelines', 14027a9cbca0SBram Moolenaar name) 14035deeb3f1SBram Moolenaar END 14045deeb3f1SBram Moolenaar writefile(lines, 'Xcall.vim') 14055deeb3f1SBram Moolenaar source Xcall.vim 14065deeb3f1SBram Moolenaar delete('Xcall.vim') 14075deeb3f1SBram Moolenaarenddef 14085deeb3f1SBram Moolenaar 14095deeb3f1SBram Moolenaardef Test_vim9script_call_fail_decl() 14107a9cbca0SBram Moolenaar var lines =<< trim END 14115deeb3f1SBram Moolenaar vim9script 14127a9cbca0SBram Moolenaar var name = '' 14135deeb3f1SBram Moolenaar def MyFunc(arg: string) 14147a9cbca0SBram Moolenaar var name = 123 14155deeb3f1SBram Moolenaar enddef 1416822ba247SBram Moolenaar defcompile 14175deeb3f1SBram Moolenaar END 14186c4bfe4bSBram Moolenaar CheckScriptFailure(lines, 'E1054:') 14195deeb3f1SBram Moolenaarenddef 14205deeb3f1SBram Moolenaar 142165b9545fSBram Moolenaardef Test_vim9script_call_fail_type() 14227a9cbca0SBram Moolenaar var lines =<< trim END 142365b9545fSBram Moolenaar vim9script 142465b9545fSBram Moolenaar def MyFunc(arg: string) 142565b9545fSBram Moolenaar echo arg 142665b9545fSBram Moolenaar enddef 142765b9545fSBram Moolenaar MyFunc(1234) 142865b9545fSBram Moolenaar END 14297707228aSBram Moolenaar CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number') 143065b9545fSBram Moolenaarenddef 143165b9545fSBram Moolenaar 14325deeb3f1SBram Moolenaardef Test_vim9script_call_fail_const() 14337a9cbca0SBram Moolenaar var lines =<< trim END 14345deeb3f1SBram Moolenaar vim9script 14355deeb3f1SBram Moolenaar const var = '' 14365deeb3f1SBram Moolenaar def MyFunc(arg: string) 14375deeb3f1SBram Moolenaar var = 'asdf' 14385deeb3f1SBram Moolenaar enddef 1439822ba247SBram Moolenaar defcompile 14405deeb3f1SBram Moolenaar END 14415deeb3f1SBram Moolenaar writefile(lines, 'Xcall_const.vim') 14429bd5d879SBram Moolenaar assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') 14435deeb3f1SBram Moolenaar delete('Xcall_const.vim') 14443bdc90b7SBram Moolenaar 14453bdc90b7SBram Moolenaar lines =<< trim END 14463bdc90b7SBram Moolenaar const g:Aconst = 77 14473bdc90b7SBram Moolenaar def Change() 14483bdc90b7SBram Moolenaar # comment 14493bdc90b7SBram Moolenaar g:Aconst = 99 14503bdc90b7SBram Moolenaar enddef 14513bdc90b7SBram Moolenaar call Change() 14523bdc90b7SBram Moolenaar unlet g:Aconst 14533bdc90b7SBram Moolenaar END 14541dcf55d4SBram Moolenaar CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2) 14555deeb3f1SBram Moolenaarenddef 14565deeb3f1SBram Moolenaar 14575deeb3f1SBram Moolenaar" Test that inside :function a Python function can be defined, :def is not 14585deeb3f1SBram Moolenaar" recognized. 14595deeb3f1SBram Moolenaarfunc Test_function_python() 14605deeb3f1SBram Moolenaar CheckFeature python3 1461727345ebSBram Moolenaar let py = 'python3' 14625deeb3f1SBram Moolenaar execute py "<< EOF" 14635deeb3f1SBram Moolenaardef do_something(): 14645deeb3f1SBram Moolenaar return 1 14655deeb3f1SBram MoolenaarEOF 14665deeb3f1SBram Moolenaarendfunc 14675deeb3f1SBram Moolenaar 14685deeb3f1SBram Moolenaardef Test_delfunc() 14697a9cbca0SBram Moolenaar var lines =<< trim END 14705deeb3f1SBram Moolenaar vim9script 14714c17ad94SBram Moolenaar def g:GoneSoon() 14725deeb3f1SBram Moolenaar echo 'hello' 14735deeb3f1SBram Moolenaar enddef 14745deeb3f1SBram Moolenaar 14755deeb3f1SBram Moolenaar def CallGoneSoon() 14765deeb3f1SBram Moolenaar GoneSoon() 14775deeb3f1SBram Moolenaar enddef 1478822ba247SBram Moolenaar defcompile 14795deeb3f1SBram Moolenaar 14804c17ad94SBram Moolenaar delfunc g:GoneSoon 14815deeb3f1SBram Moolenaar CallGoneSoon() 14825deeb3f1SBram Moolenaar END 14835deeb3f1SBram Moolenaar writefile(lines, 'XToDelFunc') 14849bd5d879SBram Moolenaar assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 14859bd5d879SBram Moolenaar assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 14865deeb3f1SBram Moolenaar 14875deeb3f1SBram Moolenaar delete('XToDelFunc') 14885deeb3f1SBram Moolenaarenddef 14895deeb3f1SBram Moolenaar 14905deeb3f1SBram Moolenaardef Test_redef_failure() 1491d2c61705SBram Moolenaar writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 14925deeb3f1SBram Moolenaar so Xdef 1493d2c61705SBram Moolenaar writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 14945deeb3f1SBram Moolenaar so Xdef 1495d2c61705SBram Moolenaar writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 14969bd5d879SBram Moolenaar assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') 1497d2c61705SBram Moolenaar writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 14985deeb3f1SBram Moolenaar so Xdef 1499d2c61705SBram Moolenaar delete('Xdef') 15005deeb3f1SBram Moolenaar 1501701cc6caSBram Moolenaar assert_fails('g:Func0()', 'E1091:') 1502c0c71e9dSBram Moolenaar g:Func1()->assert_equal('Func1') 1503c0c71e9dSBram Moolenaar g:Func2()->assert_equal('Func2') 15045deeb3f1SBram Moolenaar 15055deeb3f1SBram Moolenaar delfunc! Func0 15065deeb3f1SBram Moolenaar delfunc! Func1 15075deeb3f1SBram Moolenaar delfunc! Func2 15085deeb3f1SBram Moolenaarenddef 15095deeb3f1SBram Moolenaar 1510f93c7feaSBram Moolenaardef Test_vim9script_func() 15117a9cbca0SBram Moolenaar var lines =<< trim END 1512f93c7feaSBram Moolenaar vim9script 1513f93c7feaSBram Moolenaar func Func(arg) 1514f93c7feaSBram Moolenaar echo a:arg 1515f93c7feaSBram Moolenaar endfunc 1516f93c7feaSBram Moolenaar Func('text') 1517f93c7feaSBram Moolenaar END 1518f93c7feaSBram Moolenaar writefile(lines, 'XVim9Func') 1519f93c7feaSBram Moolenaar so XVim9Func 1520f93c7feaSBram Moolenaar 1521f93c7feaSBram Moolenaar delete('XVim9Func') 1522f93c7feaSBram Moolenaarenddef 1523f93c7feaSBram Moolenaar 15245deeb3f1SBram Moolenaarlet s:funcResult = 0 15255deeb3f1SBram Moolenaar 15265deeb3f1SBram Moolenaardef FuncNoArgNoRet() 15275390099aSBram Moolenaar s:funcResult = 11 15285deeb3f1SBram Moolenaarenddef 15295deeb3f1SBram Moolenaar 15305deeb3f1SBram Moolenaardef FuncNoArgRetNumber(): number 15315390099aSBram Moolenaar s:funcResult = 22 15325deeb3f1SBram Moolenaar return 1234 15335deeb3f1SBram Moolenaarenddef 15345deeb3f1SBram Moolenaar 1535ec5929d0SBram Moolenaardef FuncNoArgRetString(): string 15365390099aSBram Moolenaar s:funcResult = 45 1537ec5929d0SBram Moolenaar return 'text' 1538ec5929d0SBram Moolenaarenddef 1539ec5929d0SBram Moolenaar 15405deeb3f1SBram Moolenaardef FuncOneArgNoRet(arg: number) 15415390099aSBram Moolenaar s:funcResult = arg 15425deeb3f1SBram Moolenaarenddef 15435deeb3f1SBram Moolenaar 15445deeb3f1SBram Moolenaardef FuncOneArgRetNumber(arg: number): number 15455390099aSBram Moolenaar s:funcResult = arg 15465deeb3f1SBram Moolenaar return arg 15475deeb3f1SBram Moolenaarenddef 15485deeb3f1SBram Moolenaar 154908938eebSBram Moolenaardef FuncTwoArgNoRet(one: bool, two: number) 15505390099aSBram Moolenaar s:funcResult = two 155108938eebSBram Moolenaarenddef 155208938eebSBram Moolenaar 1553ec5929d0SBram Moolenaardef FuncOneArgRetString(arg: string): string 1554ec5929d0SBram Moolenaar return arg 1555ec5929d0SBram Moolenaarenddef 1556ec5929d0SBram Moolenaar 15578922860aSBram Moolenaardef FuncOneArgRetAny(arg: any): any 15588922860aSBram Moolenaar return arg 15598922860aSBram Moolenaarenddef 15608922860aSBram Moolenaar 15615deeb3f1SBram Moolenaardef Test_func_type() 15627a9cbca0SBram Moolenaar var Ref1: func() 15635390099aSBram Moolenaar s:funcResult = 0 15645deeb3f1SBram Moolenaar Ref1 = FuncNoArgNoRet 15655deeb3f1SBram Moolenaar Ref1() 1566c0c71e9dSBram Moolenaar s:funcResult->assert_equal(11) 15674c683750SBram Moolenaar 15687a9cbca0SBram Moolenaar var Ref2: func 15695390099aSBram Moolenaar s:funcResult = 0 15704c683750SBram Moolenaar Ref2 = FuncNoArgNoRet 15714c683750SBram Moolenaar Ref2() 1572c0c71e9dSBram Moolenaar s:funcResult->assert_equal(11) 15734c683750SBram Moolenaar 15745390099aSBram Moolenaar s:funcResult = 0 15754c683750SBram Moolenaar Ref2 = FuncOneArgNoRet 15764c683750SBram Moolenaar Ref2(12) 1577c0c71e9dSBram Moolenaar s:funcResult->assert_equal(12) 15784c683750SBram Moolenaar 15795390099aSBram Moolenaar s:funcResult = 0 15804c683750SBram Moolenaar Ref2 = FuncNoArgRetNumber 1581c0c71e9dSBram Moolenaar Ref2()->assert_equal(1234) 1582c0c71e9dSBram Moolenaar s:funcResult->assert_equal(22) 15834c683750SBram Moolenaar 15845390099aSBram Moolenaar s:funcResult = 0 15854c683750SBram Moolenaar Ref2 = FuncOneArgRetNumber 1586c0c71e9dSBram Moolenaar Ref2(13)->assert_equal(13) 1587c0c71e9dSBram Moolenaar s:funcResult->assert_equal(13) 15885deeb3f1SBram Moolenaarenddef 15895deeb3f1SBram Moolenaar 15909978d473SBram Moolenaardef Test_repeat_return_type() 15917a9cbca0SBram Moolenaar var res = 0 15929978d473SBram Moolenaar for n in repeat([1], 3) 15939978d473SBram Moolenaar res += n 15949978d473SBram Moolenaar endfor 1595c0c71e9dSBram Moolenaar res->assert_equal(3) 1596fce82b3aSBram Moolenaar 1597fce82b3aSBram Moolenaar res = 0 1598fce82b3aSBram Moolenaar for n in add([1, 2], 3) 1599fce82b3aSBram Moolenaar res += n 1600fce82b3aSBram Moolenaar endfor 1601c0c71e9dSBram Moolenaar res->assert_equal(6) 16029978d473SBram Moolenaarenddef 16039978d473SBram Moolenaar 1604846178a7SBram Moolenaardef Test_argv_return_type() 1605846178a7SBram Moolenaar next fileone filetwo 16067a9cbca0SBram Moolenaar var res = '' 1607846178a7SBram Moolenaar for name in argv() 1608846178a7SBram Moolenaar res ..= name 1609846178a7SBram Moolenaar endfor 1610c0c71e9dSBram Moolenaar res->assert_equal('fileonefiletwo') 1611846178a7SBram Moolenaarenddef 1612846178a7SBram Moolenaar 1613ec5929d0SBram Moolenaardef Test_func_type_part() 16147a9cbca0SBram Moolenaar var RefVoid: func: void 1615ec5929d0SBram Moolenaar RefVoid = FuncNoArgNoRet 1616ec5929d0SBram Moolenaar RefVoid = FuncOneArgNoRet 16177a9cbca0SBram Moolenaar CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 16187a9cbca0SBram Moolenaar CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1619ec5929d0SBram Moolenaar 16207a9cbca0SBram Moolenaar var RefAny: func(): any 1621ec5929d0SBram Moolenaar RefAny = FuncNoArgRetNumber 1622ec5929d0SBram Moolenaar RefAny = FuncNoArgRetString 16237a9cbca0SBram Moolenaar CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 16247a9cbca0SBram Moolenaar CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1625ec5929d0SBram Moolenaar 16266abd3dc2SBram Moolenaar var RefAnyNoArgs: func: any = RefAny 16276abd3dc2SBram Moolenaar 16287a9cbca0SBram Moolenaar var RefNr: func: number 1629ec5929d0SBram Moolenaar RefNr = FuncNoArgRetNumber 1630ec5929d0SBram Moolenaar RefNr = FuncOneArgRetNumber 16317a9cbca0SBram Moolenaar CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 16327a9cbca0SBram Moolenaar CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1633ec5929d0SBram Moolenaar 16347a9cbca0SBram Moolenaar var RefStr: func: string 1635ec5929d0SBram Moolenaar RefStr = FuncNoArgRetString 1636ec5929d0SBram Moolenaar RefStr = FuncOneArgRetString 16377a9cbca0SBram Moolenaar CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 16387a9cbca0SBram Moolenaar CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1639ec5929d0SBram Moolenaarenddef 1640ec5929d0SBram Moolenaar 16415deeb3f1SBram Moolenaardef Test_func_type_fails() 16427a9cbca0SBram Moolenaar CheckDefFailure(['var ref1: func()'], 'E704:') 16435deeb3f1SBram Moolenaar 16447a9cbca0SBram Moolenaar CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 16457a9cbca0SBram Moolenaar CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 16467a9cbca0SBram Moolenaar CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 16477a9cbca0SBram Moolenaar CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 16487a9cbca0SBram Moolenaar CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 16497a9cbca0SBram Moolenaar CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 165008938eebSBram Moolenaar 16517a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:') 16527a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:') 16537a9cbca0SBram 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:') 16547a9cbca0SBram Moolenaar CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:') 16555deeb3f1SBram Moolenaarenddef 16565deeb3f1SBram Moolenaar 16578922860aSBram Moolenaardef Test_func_return_type() 16587a9cbca0SBram Moolenaar var nr: number 16598922860aSBram Moolenaar nr = FuncNoArgRetNumber() 1660c0c71e9dSBram Moolenaar nr->assert_equal(1234) 16618922860aSBram Moolenaar 16628922860aSBram Moolenaar nr = FuncOneArgRetAny(122) 1663c0c71e9dSBram Moolenaar nr->assert_equal(122) 16648922860aSBram Moolenaar 16657a9cbca0SBram Moolenaar var str: string 16668922860aSBram Moolenaar str = FuncOneArgRetAny('yes') 1667c0c71e9dSBram Moolenaar str->assert_equal('yes') 16688922860aSBram Moolenaar 16697a9cbca0SBram Moolenaar CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number') 16708922860aSBram Moolenaarenddef 16718922860aSBram Moolenaar 16726abd3dc2SBram Moolenaardef Test_func_common_type() 16736abd3dc2SBram Moolenaar def FuncOne(n: number): number 16746abd3dc2SBram Moolenaar return n 16756abd3dc2SBram Moolenaar enddef 16766abd3dc2SBram Moolenaar def FuncTwo(s: string): number 16776abd3dc2SBram Moolenaar return len(s) 16786abd3dc2SBram Moolenaar enddef 16796abd3dc2SBram Moolenaar def FuncThree(n: number, s: string): number 16806abd3dc2SBram Moolenaar return n + len(s) 16816abd3dc2SBram Moolenaar enddef 16826abd3dc2SBram Moolenaar var list = [FuncOne, FuncTwo, FuncThree] 16836abd3dc2SBram Moolenaar assert_equal(8, list[0](8)) 16846abd3dc2SBram Moolenaar assert_equal(4, list[1]('word')) 16856abd3dc2SBram Moolenaar assert_equal(7, list[2](3, 'word')) 16866abd3dc2SBram Moolenaarenddef 16876abd3dc2SBram Moolenaar 16885e774c75SBram Moolenaardef MultiLine( 16895e774c75SBram Moolenaar arg1: string, 16905e774c75SBram Moolenaar arg2 = 1234, 16915e774c75SBram Moolenaar ...rest: list<string> 16925e774c75SBram Moolenaar ): string 16935e774c75SBram Moolenaar return arg1 .. arg2 .. join(rest, '-') 16945e774c75SBram Moolenaarenddef 16955e774c75SBram Moolenaar 16962c330432SBram Moolenaardef MultiLineComment( 16972c330432SBram Moolenaar arg1: string, # comment 16982c330432SBram Moolenaar arg2 = 1234, # comment 16992c330432SBram Moolenaar ...rest: list<string> # comment 17002c330432SBram Moolenaar ): string # comment 17012c330432SBram Moolenaar return arg1 .. arg2 .. join(rest, '-') 17022c330432SBram Moolenaarenddef 17032c330432SBram Moolenaar 17045e774c75SBram Moolenaardef Test_multiline() 1705c0c71e9dSBram Moolenaar MultiLine('text')->assert_equal('text1234') 1706c0c71e9dSBram Moolenaar MultiLine('text', 777)->assert_equal('text777') 1707c0c71e9dSBram Moolenaar MultiLine('text', 777, 'one')->assert_equal('text777one') 1708c0c71e9dSBram Moolenaar MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 17095e774c75SBram Moolenaarenddef 17105e774c75SBram Moolenaar 171123e03252SBram Moolenaarfunc Test_multiline_not_vim9() 1712c0c71e9dSBram Moolenaar call MultiLine('text')->assert_equal('text1234') 1713c0c71e9dSBram Moolenaar call MultiLine('text', 777)->assert_equal('text777') 1714c0c71e9dSBram Moolenaar call MultiLine('text', 777, 'one')->assert_equal('text777one') 1715c0c71e9dSBram Moolenaar call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 171623e03252SBram Moolenaarendfunc 171723e03252SBram Moolenaar 17185e774c75SBram Moolenaar 1719ee4e0c1eSBram Moolenaar" When using CheckScriptFailure() for the below test, E1010 is generated instead 1720ee4e0c1eSBram Moolenaar" of E1056. 1721ee4e0c1eSBram Moolenaarfunc Test_E1056_1059() 1722ee4e0c1eSBram Moolenaar let caught_1056 = 0 1723ee4e0c1eSBram Moolenaar try 1724ee4e0c1eSBram Moolenaar def F(): 1725ee4e0c1eSBram Moolenaar return 1 1726ee4e0c1eSBram Moolenaar enddef 1727ee4e0c1eSBram Moolenaar catch /E1056:/ 1728ee4e0c1eSBram Moolenaar let caught_1056 = 1 1729ee4e0c1eSBram Moolenaar endtry 1730c0c71e9dSBram Moolenaar eval caught_1056->assert_equal(1) 1731ee4e0c1eSBram Moolenaar 1732ee4e0c1eSBram Moolenaar let caught_1059 = 0 1733ee4e0c1eSBram Moolenaar try 1734ee4e0c1eSBram Moolenaar def F5(items : list) 1735ee4e0c1eSBram Moolenaar echo 'a' 1736ee4e0c1eSBram Moolenaar enddef 1737ee4e0c1eSBram Moolenaar catch /E1059:/ 1738ee4e0c1eSBram Moolenaar let caught_1059 = 1 1739ee4e0c1eSBram Moolenaar endtry 1740c0c71e9dSBram Moolenaar eval caught_1059->assert_equal(1) 1741ee4e0c1eSBram Moolenaarendfunc 17425deeb3f1SBram Moolenaar 1743015f4267SBram Moolenaarfunc DelMe() 1744015f4267SBram Moolenaar echo 'DelMe' 1745015f4267SBram Moolenaarendfunc 1746015f4267SBram Moolenaar 1747bf8feb5aSBram Moolenaardef Test_error_reporting() 1748bf8feb5aSBram Moolenaar # comment lines at the start of the function 17497a9cbca0SBram Moolenaar var lines =<< trim END 1750bf8feb5aSBram Moolenaar " comment 1751bf8feb5aSBram Moolenaar def Func() 1752bf8feb5aSBram Moolenaar # comment 1753bf8feb5aSBram Moolenaar # comment 1754bf8feb5aSBram Moolenaar invalid 1755bf8feb5aSBram Moolenaar enddef 1756bf8feb5aSBram Moolenaar defcompile 1757bf8feb5aSBram Moolenaar END 175808052228SBram Moolenaar writefile(lines, 'Xdef') 1759bf8feb5aSBram Moolenaar try 1760bf8feb5aSBram Moolenaar source Xdef 17617517ffdbSBram Moolenaar assert_report('should have failed') 1762bf8feb5aSBram Moolenaar catch /E476:/ 1763c0c71e9dSBram Moolenaar v:exception->assert_match('Invalid command: invalid') 1764c0c71e9dSBram Moolenaar v:throwpoint->assert_match(', line 3$') 1765bf8feb5aSBram Moolenaar endtry 17662d870f8dSBram Moolenaar delfunc! g:Func 1767bf8feb5aSBram Moolenaar 1768bf8feb5aSBram Moolenaar # comment lines after the start of the function 1769bf8feb5aSBram Moolenaar lines =<< trim END 1770bf8feb5aSBram Moolenaar " comment 1771bf8feb5aSBram Moolenaar def Func() 17727a9cbca0SBram Moolenaar var x = 1234 1773bf8feb5aSBram Moolenaar # comment 1774bf8feb5aSBram Moolenaar # comment 1775bf8feb5aSBram Moolenaar invalid 1776bf8feb5aSBram Moolenaar enddef 1777bf8feb5aSBram Moolenaar defcompile 1778bf8feb5aSBram Moolenaar END 177908052228SBram Moolenaar writefile(lines, 'Xdef') 1780bf8feb5aSBram Moolenaar try 1781bf8feb5aSBram Moolenaar source Xdef 17827517ffdbSBram Moolenaar assert_report('should have failed') 1783bf8feb5aSBram Moolenaar catch /E476:/ 1784c0c71e9dSBram Moolenaar v:exception->assert_match('Invalid command: invalid') 1785c0c71e9dSBram Moolenaar v:throwpoint->assert_match(', line 4$') 1786bf8feb5aSBram Moolenaar endtry 17872d870f8dSBram Moolenaar delfunc! g:Func 1788bf8feb5aSBram Moolenaar 17897517ffdbSBram Moolenaar lines =<< trim END 17907517ffdbSBram Moolenaar vim9script 17917517ffdbSBram Moolenaar def Func() 1792e0de171eSBram Moolenaar var db = {foo: 1, bar: 2} 17937517ffdbSBram Moolenaar # comment 17947a9cbca0SBram Moolenaar var x = db.asdf 17957517ffdbSBram Moolenaar enddef 17967517ffdbSBram Moolenaar defcompile 17977517ffdbSBram Moolenaar Func() 17987517ffdbSBram Moolenaar END 179908052228SBram Moolenaar writefile(lines, 'Xdef') 18007517ffdbSBram Moolenaar try 18017517ffdbSBram Moolenaar source Xdef 18027517ffdbSBram Moolenaar assert_report('should have failed') 18037517ffdbSBram Moolenaar catch /E716:/ 1804c0c71e9dSBram Moolenaar v:throwpoint->assert_match('_Func, line 3$') 18057517ffdbSBram Moolenaar endtry 18062d870f8dSBram Moolenaar delfunc! g:Func 18077517ffdbSBram Moolenaar 180808052228SBram Moolenaar delete('Xdef') 1809bf8feb5aSBram Moolenaarenddef 1810bf8feb5aSBram Moolenaar 1811015f4267SBram Moolenaardef Test_deleted_function() 1812015f4267SBram Moolenaar CheckDefExecFailure([ 18137a9cbca0SBram Moolenaar 'var RefMe: func = function("g:DelMe")', 1814015f4267SBram Moolenaar 'delfunc g:DelMe', 1815015f4267SBram Moolenaar 'echo RefMe()'], 'E117:') 1816015f4267SBram Moolenaarenddef 1817015f4267SBram Moolenaar 1818015f4267SBram Moolenaardef Test_unknown_function() 1819015f4267SBram Moolenaar CheckDefExecFailure([ 18207a9cbca0SBram Moolenaar 'var Ref: func = function("NotExist")', 18219b7bf9e9SBram Moolenaar 'delfunc g:NotExist'], 'E700:') 1822015f4267SBram Moolenaarenddef 1823015f4267SBram Moolenaar 1824328eac2bSBram Moolenaardef RefFunc(Ref: func(any): any): string 1825c8cd2b34SBram Moolenaar return Ref('more') 1826c8cd2b34SBram Moolenaarenddef 1827c8cd2b34SBram Moolenaar 1828c8cd2b34SBram Moolenaardef Test_closure_simple() 18297a9cbca0SBram Moolenaar var local = 'some ' 18302949cfdbSBram Moolenaar RefFunc((s) => local .. s)->assert_equal('some more') 1831c8cd2b34SBram Moolenaarenddef 1832c8cd2b34SBram Moolenaar 1833bf67ea1aSBram Moolenaardef MakeRef() 18347a9cbca0SBram Moolenaar var local = 'some ' 18352949cfdbSBram Moolenaar g:Ref = (s) => local .. s 1836bf67ea1aSBram Moolenaarenddef 1837bf67ea1aSBram Moolenaar 1838bf67ea1aSBram Moolenaardef Test_closure_ref_after_return() 1839bf67ea1aSBram Moolenaar MakeRef() 1840c0c71e9dSBram Moolenaar g:Ref('thing')->assert_equal('some thing') 1841bf67ea1aSBram Moolenaar unlet g:Ref 1842bf67ea1aSBram Moolenaarenddef 1843bf67ea1aSBram Moolenaar 18445adc55cbSBram Moolenaardef MakeTwoRefs() 18457a9cbca0SBram Moolenaar var local = ['some'] 18462949cfdbSBram Moolenaar g:Extend = (s) => local->add(s) 18472949cfdbSBram Moolenaar g:Read = () => local 18485adc55cbSBram Moolenaarenddef 18495adc55cbSBram Moolenaar 18505adc55cbSBram Moolenaardef Test_closure_two_refs() 18515adc55cbSBram Moolenaar MakeTwoRefs() 1852c0c71e9dSBram Moolenaar join(g:Read(), ' ')->assert_equal('some') 18535adc55cbSBram Moolenaar g:Extend('more') 1854c0c71e9dSBram Moolenaar join(g:Read(), ' ')->assert_equal('some more') 18555adc55cbSBram Moolenaar g:Extend('even') 1856c0c71e9dSBram Moolenaar join(g:Read(), ' ')->assert_equal('some more even') 18575adc55cbSBram Moolenaar 18585adc55cbSBram Moolenaar unlet g:Extend 18595adc55cbSBram Moolenaar unlet g:Read 18605adc55cbSBram Moolenaarenddef 18615adc55cbSBram Moolenaar 18625adc55cbSBram Moolenaardef ReadRef(Ref: func(): list<string>): string 18635adc55cbSBram Moolenaar return join(Ref(), ' ') 18645adc55cbSBram Moolenaarenddef 18655adc55cbSBram Moolenaar 18665e654230SBram Moolenaardef ExtendRef(Ref: func(string): list<string>, add: string) 18675adc55cbSBram Moolenaar Ref(add) 18685adc55cbSBram Moolenaarenddef 18695adc55cbSBram Moolenaar 18705adc55cbSBram Moolenaardef Test_closure_two_indirect_refs() 1871f7779c63SBram Moolenaar MakeTwoRefs() 1872c0c71e9dSBram Moolenaar ReadRef(g:Read)->assert_equal('some') 18735adc55cbSBram Moolenaar ExtendRef(g:Extend, 'more') 1874c0c71e9dSBram Moolenaar ReadRef(g:Read)->assert_equal('some more') 18755adc55cbSBram Moolenaar ExtendRef(g:Extend, 'even') 1876c0c71e9dSBram Moolenaar ReadRef(g:Read)->assert_equal('some more even') 18775adc55cbSBram Moolenaar 18785adc55cbSBram Moolenaar unlet g:Extend 18795adc55cbSBram Moolenaar unlet g:Read 18805adc55cbSBram Moolenaarenddef 1881bf67ea1aSBram Moolenaar 18822fd4cd75SBram Moolenaardef MakeArgRefs(theArg: string) 18837a9cbca0SBram Moolenaar var local = 'loc_val' 18842949cfdbSBram Moolenaar g:UseArg = (s) => theArg .. '/' .. local .. '/' .. s 18852fd4cd75SBram Moolenaarenddef 18862fd4cd75SBram Moolenaar 18872fd4cd75SBram Moolenaardef MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 18887a9cbca0SBram Moolenaar var local = 'the_loc' 18892949cfdbSBram Moolenaar g:UseVararg = (s) => theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest) 18902fd4cd75SBram Moolenaarenddef 18912fd4cd75SBram Moolenaar 18922fd4cd75SBram Moolenaardef Test_closure_using_argument() 18932fd4cd75SBram Moolenaar MakeArgRefs('arg_val') 1894c0c71e9dSBram Moolenaar g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val') 18952fd4cd75SBram Moolenaar 18962fd4cd75SBram Moolenaar MakeArgRefsVarargs('arg_val', 'one', 'two') 1897c0c71e9dSBram Moolenaar g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two') 18982fd4cd75SBram Moolenaar 18992fd4cd75SBram Moolenaar unlet g:UseArg 19002fd4cd75SBram Moolenaar unlet g:UseVararg 190144ec21c4SBram Moolenaar 190244ec21c4SBram Moolenaar var lines =<< trim END 190344ec21c4SBram Moolenaar vim9script 190444ec21c4SBram Moolenaar def Test(Fun: func(number): number): list<number> 190544ec21c4SBram Moolenaar return map([1, 2, 3], (_, i) => Fun(i)) 190644ec21c4SBram Moolenaar enddef 190744ec21c4SBram Moolenaar def Inc(nr: number): number 190844ec21c4SBram Moolenaar return nr + 2 190944ec21c4SBram Moolenaar enddef 191044ec21c4SBram Moolenaar assert_equal([3, 4, 5], Test(Inc)) 191144ec21c4SBram Moolenaar END 191244ec21c4SBram Moolenaar CheckScriptSuccess(lines) 19132fd4cd75SBram Moolenaarenddef 19142fd4cd75SBram Moolenaar 191585d5e2b7SBram Moolenaardef MakeGetAndAppendRefs() 191685d5e2b7SBram Moolenaar var local = 'a' 191785d5e2b7SBram Moolenaar 191885d5e2b7SBram Moolenaar def Append(arg: string) 191985d5e2b7SBram Moolenaar local ..= arg 192085d5e2b7SBram Moolenaar enddef 192185d5e2b7SBram Moolenaar g:Append = Append 192285d5e2b7SBram Moolenaar 192385d5e2b7SBram Moolenaar def Get(): string 192485d5e2b7SBram Moolenaar return local 192585d5e2b7SBram Moolenaar enddef 192685d5e2b7SBram Moolenaar g:Get = Get 192785d5e2b7SBram Moolenaarenddef 192885d5e2b7SBram Moolenaar 192985d5e2b7SBram Moolenaardef Test_closure_append_get() 193085d5e2b7SBram Moolenaar MakeGetAndAppendRefs() 193185d5e2b7SBram Moolenaar g:Get()->assert_equal('a') 193285d5e2b7SBram Moolenaar g:Append('-b') 193385d5e2b7SBram Moolenaar g:Get()->assert_equal('a-b') 193485d5e2b7SBram Moolenaar g:Append('-c') 193585d5e2b7SBram Moolenaar g:Get()->assert_equal('a-b-c') 193685d5e2b7SBram Moolenaar 193785d5e2b7SBram Moolenaar unlet g:Append 193885d5e2b7SBram Moolenaar unlet g:Get 193985d5e2b7SBram Moolenaarenddef 1940b68b346eSBram Moolenaar 194104b12697SBram Moolenaardef Test_nested_closure() 19427a9cbca0SBram Moolenaar var local = 'text' 194304b12697SBram Moolenaar def Closure(arg: string): string 194404b12697SBram Moolenaar return local .. arg 194504b12697SBram Moolenaar enddef 1946c0c71e9dSBram Moolenaar Closure('!!!')->assert_equal('text!!!') 194704b12697SBram Moolenaarenddef 194804b12697SBram Moolenaar 19496f5b6dfbSBram Moolenaarfunc GetResult(Ref) 19506f5b6dfbSBram Moolenaar return a:Ref('some') 19516f5b6dfbSBram Moolenaarendfunc 19526f5b6dfbSBram Moolenaar 19536f5b6dfbSBram Moolenaardef Test_call_closure_not_compiled() 19547a9cbca0SBram Moolenaar var text = 'text' 19552949cfdbSBram Moolenaar g:Ref = (s) => s .. text 1956c0c71e9dSBram Moolenaar GetResult(g:Ref)->assert_equal('sometext') 19576f5b6dfbSBram Moolenaarenddef 19586f5b6dfbSBram Moolenaar 19597cbfaa51SBram Moolenaardef Test_double_closure_fails() 19607a9cbca0SBram Moolenaar var lines =<< trim END 19617cbfaa51SBram Moolenaar vim9script 19627cbfaa51SBram Moolenaar def Func() 19637a9cbca0SBram Moolenaar var name = 0 19647cbfaa51SBram Moolenaar for i in range(2) 19652949cfdbSBram Moolenaar timer_start(0, () => name) 19667cbfaa51SBram Moolenaar endfor 19677cbfaa51SBram Moolenaar enddef 19687cbfaa51SBram Moolenaar Func() 19697cbfaa51SBram Moolenaar END 1970148ce7aeSBram Moolenaar CheckScriptSuccess(lines) 19717cbfaa51SBram Moolenaarenddef 19727cbfaa51SBram Moolenaar 197385d5e2b7SBram Moolenaardef Test_nested_closure_used() 197485d5e2b7SBram Moolenaar var lines =<< trim END 197585d5e2b7SBram Moolenaar vim9script 197685d5e2b7SBram Moolenaar def Func() 197785d5e2b7SBram Moolenaar var x = 'hello' 19782949cfdbSBram Moolenaar var Closure = () => x 19792949cfdbSBram Moolenaar g:Myclosure = () => Closure() 198085d5e2b7SBram Moolenaar enddef 198185d5e2b7SBram Moolenaar Func() 198285d5e2b7SBram Moolenaar assert_equal('hello', g:Myclosure()) 198385d5e2b7SBram Moolenaar END 198485d5e2b7SBram Moolenaar CheckScriptSuccess(lines) 198585d5e2b7SBram Moolenaarenddef 19860876c785SBram Moolenaar 1987c70bdab0SBram Moolenaardef Test_nested_closure_fails() 19887a9cbca0SBram Moolenaar var lines =<< trim END 1989c70bdab0SBram Moolenaar vim9script 1990c70bdab0SBram Moolenaar def FuncA() 1991c70bdab0SBram Moolenaar FuncB(0) 1992c70bdab0SBram Moolenaar enddef 1993c70bdab0SBram Moolenaar def FuncB(n: number): list<string> 19942949cfdbSBram Moolenaar return map([0], (_, v) => n) 1995c70bdab0SBram Moolenaar enddef 1996c70bdab0SBram Moolenaar FuncA() 1997c70bdab0SBram Moolenaar END 1998c70bdab0SBram Moolenaar CheckScriptFailure(lines, 'E1012:') 1999c70bdab0SBram Moolenaarenddef 2000c70bdab0SBram Moolenaar 2001f112f30aSBram Moolenaardef Test_global_closure() 2002f112f30aSBram Moolenaar var lines =<< trim END 2003f112f30aSBram Moolenaar vim9script 2004f112f30aSBram Moolenaar def ReverseEveryNLines(n: number, line1: number, line2: number) 2005f112f30aSBram Moolenaar var mods = 'sil keepj keepp lockm ' 2006f112f30aSBram Moolenaar var range = ':' .. line1 .. ',' .. line2 2007f112f30aSBram Moolenaar def g:Offset(): number 2008f112f30aSBram Moolenaar var offset = (line('.') - line1 + 1) % n 2009f112f30aSBram Moolenaar return offset != 0 ? offset : n 2010f112f30aSBram Moolenaar enddef 2011f112f30aSBram Moolenaar exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()' 2012f112f30aSBram Moolenaar enddef 2013f112f30aSBram Moolenaar 2014f112f30aSBram Moolenaar new 2015f112f30aSBram Moolenaar repeat(['aaa', 'bbb', 'ccc'], 3)->setline(1) 2016f112f30aSBram Moolenaar ReverseEveryNLines(3, 1, 9) 2017f112f30aSBram Moolenaar END 2018f112f30aSBram Moolenaar CheckScriptSuccess(lines) 2019f112f30aSBram Moolenaar var expected = repeat(['ccc', 'bbb', 'aaa'], 3) 2020f112f30aSBram Moolenaar assert_equal(expected, getline(1, 9)) 2021f112f30aSBram Moolenaar bwipe! 2022f112f30aSBram Moolenaarenddef 2023f112f30aSBram Moolenaar 2024cd45ed03SBram Moolenaardef Test_global_closure_called_directly() 2025cd45ed03SBram Moolenaar var lines =<< trim END 2026cd45ed03SBram Moolenaar vim9script 2027cd45ed03SBram Moolenaar def Outer() 2028cd45ed03SBram Moolenaar var x = 1 2029cd45ed03SBram Moolenaar def g:Inner() 2030cd45ed03SBram Moolenaar var y = x 2031cd45ed03SBram Moolenaar x += 1 2032cd45ed03SBram Moolenaar assert_equal(1, y) 2033cd45ed03SBram Moolenaar enddef 2034cd45ed03SBram Moolenaar g:Inner() 2035cd45ed03SBram Moolenaar assert_equal(2, x) 2036cd45ed03SBram Moolenaar enddef 2037cd45ed03SBram Moolenaar Outer() 2038cd45ed03SBram Moolenaar END 2039cd45ed03SBram Moolenaar CheckScriptSuccess(lines) 2040cd45ed03SBram Moolenaar delfunc g:Inner 2041cd45ed03SBram Moolenaarenddef 2042cd45ed03SBram Moolenaar 204334c54eb6SBram Moolenaardef Test_failure_in_called_function() 204434c54eb6SBram Moolenaar # this was using the frame index as the return value 204534c54eb6SBram Moolenaar var lines =<< trim END 204634c54eb6SBram Moolenaar vim9script 204734c54eb6SBram Moolenaar au TerminalWinOpen * eval [][0] 204834c54eb6SBram Moolenaar def PopupTerm(a: any) 204934c54eb6SBram Moolenaar # make sure typvals on stack are string 205034c54eb6SBram Moolenaar ['a', 'b', 'c', 'd', 'e', 'f', 'g']->join() 205134c54eb6SBram Moolenaar FireEvent() 205234c54eb6SBram Moolenaar enddef 205334c54eb6SBram Moolenaar def FireEvent() 205434c54eb6SBram Moolenaar do TerminalWinOpen 205534c54eb6SBram Moolenaar enddef 205634c54eb6SBram Moolenaar # use try/catch to make eval fail 205734c54eb6SBram Moolenaar try 205834c54eb6SBram Moolenaar call PopupTerm(0) 205934c54eb6SBram Moolenaar catch 206034c54eb6SBram Moolenaar endtry 206134c54eb6SBram Moolenaar au! TerminalWinOpen 206234c54eb6SBram Moolenaar END 206334c54eb6SBram Moolenaar CheckScriptSuccess(lines) 206434c54eb6SBram Moolenaarenddef 206534c54eb6SBram Moolenaar 20665366e1aeSBram Moolenaardef Test_nested_lambda() 20675366e1aeSBram Moolenaar var lines =<< trim END 20685366e1aeSBram Moolenaar vim9script 20695366e1aeSBram Moolenaar def Func() 20705366e1aeSBram Moolenaar var x = 4 20712949cfdbSBram Moolenaar var Lambda1 = () => 7 20722949cfdbSBram Moolenaar var Lambda2 = () => [Lambda1(), x] 20735366e1aeSBram Moolenaar var res = Lambda2() 20745366e1aeSBram Moolenaar assert_equal([7, 4], res) 20755366e1aeSBram Moolenaar enddef 20765366e1aeSBram Moolenaar Func() 20775366e1aeSBram Moolenaar END 20785366e1aeSBram Moolenaar CheckScriptSuccess(lines) 20795366e1aeSBram Moolenaarenddef 20805366e1aeSBram Moolenaar 208152bf81c2SBram Moolenaardef Shadowed(): list<number> 20822949cfdbSBram Moolenaar var FuncList: list<func: number> = [() => 42] 208375ab91ffSBram Moolenaar return FuncList->mapnew((_, Shadowed) => Shadowed()) 208452bf81c2SBram Moolenaarenddef 208552bf81c2SBram Moolenaar 208652bf81c2SBram Moolenaardef Test_lambda_arg_shadows_func() 208752bf81c2SBram Moolenaar assert_equal([42], Shadowed()) 208852bf81c2SBram Moolenaarenddef 208952bf81c2SBram Moolenaar 2090acd4c5e9SBram Moolenaardef Line_continuation_in_def(dir: string = ''): string 20917a9cbca0SBram Moolenaar var path: string = empty(dir) 2092acd4c5e9SBram Moolenaar \ ? 'empty' 2093acd4c5e9SBram Moolenaar \ : 'full' 2094acd4c5e9SBram Moolenaar return path 2095acd4c5e9SBram Moolenaarenddef 2096acd4c5e9SBram Moolenaar 2097acd4c5e9SBram Moolenaardef Test_line_continuation_in_def() 2098c0c71e9dSBram Moolenaar Line_continuation_in_def('.')->assert_equal('full') 2099acd4c5e9SBram Moolenaarenddef 2100acd4c5e9SBram Moolenaar 21012ea95b61SBram Moolenaardef Test_script_var_in_lambda() 21022ea95b61SBram Moolenaar var lines =<< trim END 21032ea95b61SBram Moolenaar vim9script 21042ea95b61SBram Moolenaar var script = 'test' 2105*bb8a7ce0SBram Moolenaar assert_equal(['test'], map(['one'], (_, _) => script)) 21062ea95b61SBram Moolenaar END 21072ea95b61SBram Moolenaar CheckScriptSuccess(lines) 21082ea95b61SBram Moolenaarenddef 21092ea95b61SBram Moolenaar 21105e654230SBram Moolenaardef Line_continuation_in_lambda(): list<string> 21117a9cbca0SBram Moolenaar var x = range(97, 100) 211275ab91ffSBram Moolenaar ->mapnew((_, v) => nr2char(v) 21132949cfdbSBram Moolenaar ->toupper()) 21147a4b8980SBram Moolenaar ->reverse() 21157a4b8980SBram Moolenaar return x 21167a4b8980SBram Moolenaarenddef 21177a4b8980SBram Moolenaar 21187a4b8980SBram Moolenaardef Test_line_continuation_in_lambda() 2119c0c71e9dSBram Moolenaar Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 2120f898f7c6SBram Moolenaar 2121f898f7c6SBram Moolenaar var lines =<< trim END 2122f898f7c6SBram Moolenaar vim9script 2123f898f7c6SBram Moolenaar var res = [{n: 1, m: 2, s: 'xxx'}] 2124f898f7c6SBram Moolenaar ->mapnew((_, v: dict<any>): string => printf('%d:%d:%s', 2125f898f7c6SBram Moolenaar v.n, 2126f898f7c6SBram Moolenaar v.m, 2127f898f7c6SBram Moolenaar substitute(v.s, '.*', 'yyy', '') 2128f898f7c6SBram Moolenaar )) 2129f898f7c6SBram Moolenaar assert_equal(['1:2:yyy'], res) 2130f898f7c6SBram Moolenaar END 2131f898f7c6SBram Moolenaar CheckScriptSuccess(lines) 21327a4b8980SBram Moolenaarenddef 21337a4b8980SBram Moolenaar 2134b657198cSBram Moolenaardef Test_list_lambda() 2135b657198cSBram Moolenaar timer_start(1000, (_) => 0) 2136b657198cSBram Moolenaar var body = execute(timer_info()[0].callback 2137b657198cSBram Moolenaar ->string() 2138b657198cSBram Moolenaar ->substitute("('", ' ', '') 2139b657198cSBram Moolenaar ->substitute("')", '', '') 2140b657198cSBram Moolenaar ->substitute('function\zs', ' ', '')) 2141767034c5SBram Moolenaar assert_match('def <lambda>\d\+(_: any): number\n1 return 0\n enddef', body) 2142b657198cSBram Moolenaarenddef 2143b657198cSBram Moolenaar 2144ab360526SBram Moolenaardef DoFilterThis(a: string): list<string> 2145ab360526SBram Moolenaar # closure nested inside another closure using argument 2146ab360526SBram Moolenaar var Filter = (l) => filter(l, (_, v) => stridx(v, a) == 0) 2147ab360526SBram Moolenaar return ['x', 'y', 'a', 'x2', 'c']->Filter() 2148ab360526SBram Moolenaarenddef 2149ab360526SBram Moolenaar 2150ab360526SBram Moolenaardef Test_nested_closure_using_argument() 2151ab360526SBram Moolenaar assert_equal(['x', 'x2'], DoFilterThis('x')) 2152ab360526SBram Moolenaarenddef 2153ab360526SBram Moolenaar 21540186e586SBram Moolenaardef Test_triple_nested_closure() 21550186e586SBram Moolenaar var what = 'x' 21560186e586SBram Moolenaar var Match = (val: string, cmp: string): bool => stridx(val, cmp) == 0 21570186e586SBram Moolenaar var Filter = (l) => filter(l, (_, v) => Match(v, what)) 21580186e586SBram Moolenaar assert_equal(['x', 'x2'], ['x', 'y', 'a', 'x2', 'c']->Filter()) 21590186e586SBram Moolenaarenddef 21600186e586SBram Moolenaar 21618f510afcSBram Moolenaarfunc Test_silent_echo() 216247e7d70bSBram Moolenaar CheckScreendump 216347e7d70bSBram Moolenaar 216447e7d70bSBram Moolenaar let lines =<< trim END 216547e7d70bSBram Moolenaar vim9script 216647e7d70bSBram Moolenaar def EchoNothing() 216747e7d70bSBram Moolenaar silent echo '' 216847e7d70bSBram Moolenaar enddef 216947e7d70bSBram Moolenaar defcompile 217047e7d70bSBram Moolenaar END 21718f510afcSBram Moolenaar call writefile(lines, 'XTest_silent_echo') 217247e7d70bSBram Moolenaar 217347e7d70bSBram Moolenaar " Check that the balloon shows up after a mouse move 217447e7d70bSBram Moolenaar let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 21758f510afcSBram Moolenaar call term_sendkeys(buf, ":abc") 217647e7d70bSBram Moolenaar call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 217747e7d70bSBram Moolenaar 217847e7d70bSBram Moolenaar " clean up 217947e7d70bSBram Moolenaar call StopVimInTerminal(buf) 218047e7d70bSBram Moolenaar call delete('XTest_silent_echo') 21818f510afcSBram Moolenaarendfunc 218247e7d70bSBram Moolenaar 2183171fb923SBram Moolenaardef SilentlyError() 2184171fb923SBram Moolenaar execute('silent! invalid') 2185171fb923SBram Moolenaar g:did_it = 'yes' 2186171fb923SBram Moolenaarenddef 2187171fb923SBram Moolenaar 218828ee892aSBram Moolenaarfunc UserError() 218928ee892aSBram Moolenaar silent! invalid 219028ee892aSBram Moolenaarendfunc 219128ee892aSBram Moolenaar 219228ee892aSBram Moolenaardef SilentlyUserError() 219328ee892aSBram Moolenaar UserError() 219428ee892aSBram Moolenaar g:did_it = 'yes' 219528ee892aSBram Moolenaarenddef 2196171fb923SBram Moolenaar 2197171fb923SBram Moolenaar" This can't be a :def function, because the assert would not be reached. 2198171fb923SBram Moolenaarfunc Test_ignore_silent_error() 2199171fb923SBram Moolenaar let g:did_it = 'no' 2200171fb923SBram Moolenaar call SilentlyError() 2201171fb923SBram Moolenaar call assert_equal('yes', g:did_it) 2202171fb923SBram Moolenaar 220328ee892aSBram Moolenaar let g:did_it = 'no' 220428ee892aSBram Moolenaar call SilentlyUserError() 220528ee892aSBram Moolenaar call assert_equal('yes', g:did_it) 2206171fb923SBram Moolenaar 2207171fb923SBram Moolenaar unlet g:did_it 2208171fb923SBram Moolenaarendfunc 2209171fb923SBram Moolenaar 2210cd030c4bSBram Moolenaardef Test_ignore_silent_error_in_filter() 2211cd030c4bSBram Moolenaar var lines =<< trim END 2212cd030c4bSBram Moolenaar vim9script 2213cd030c4bSBram Moolenaar def Filter(winid: number, key: string): bool 2214cd030c4bSBram Moolenaar if key == 'o' 2215cd030c4bSBram Moolenaar silent! eval [][0] 2216cd030c4bSBram Moolenaar return true 2217cd030c4bSBram Moolenaar endif 2218cd030c4bSBram Moolenaar return popup_filter_menu(winid, key) 2219cd030c4bSBram Moolenaar enddef 2220cd030c4bSBram Moolenaar 2221e0de171eSBram Moolenaar popup_create('popup', {filter: Filter}) 2222cd030c4bSBram Moolenaar feedkeys("o\r", 'xnt') 2223cd030c4bSBram Moolenaar END 2224cd030c4bSBram Moolenaar CheckScriptSuccess(lines) 2225cd030c4bSBram Moolenaarenddef 2226cd030c4bSBram Moolenaar 22274b9bd692SBram Moolenaardef Fibonacci(n: number): number 22284b9bd692SBram Moolenaar if n < 2 22294b9bd692SBram Moolenaar return n 22304b9bd692SBram Moolenaar else 22314b9bd692SBram Moolenaar return Fibonacci(n - 1) + Fibonacci(n - 2) 22324b9bd692SBram Moolenaar endif 22334b9bd692SBram Moolenaarenddef 22344b9bd692SBram Moolenaar 2235985116aeSBram Moolenaardef Test_recursive_call() 2236c0c71e9dSBram Moolenaar Fibonacci(20)->assert_equal(6765) 2237985116aeSBram Moolenaarenddef 2238985116aeSBram Moolenaar 223908f7a41bSBram Moolenaardef TreeWalk(dir: string): list<any> 224075ab91ffSBram Moolenaar return readdir(dir)->mapnew((_, val) => 224108f7a41bSBram Moolenaar fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 22422bede173SBram Moolenaar ? {[val]: TreeWalk(dir .. '/' .. val)} 224308f7a41bSBram Moolenaar : val 22442949cfdbSBram Moolenaar ) 224508f7a41bSBram Moolenaarenddef 224608f7a41bSBram Moolenaar 224708f7a41bSBram Moolenaardef Test_closure_in_map() 224808f7a41bSBram Moolenaar mkdir('XclosureDir/tdir', 'p') 224908f7a41bSBram Moolenaar writefile(['111'], 'XclosureDir/file1') 225008f7a41bSBram Moolenaar writefile(['222'], 'XclosureDir/file2') 225108f7a41bSBram Moolenaar writefile(['333'], 'XclosureDir/tdir/file3') 225208f7a41bSBram Moolenaar 2253e0de171eSBram Moolenaar TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {tdir: ['file3']}]) 225408f7a41bSBram Moolenaar 225508f7a41bSBram Moolenaar delete('XclosureDir', 'rf') 225608f7a41bSBram Moolenaarenddef 225708f7a41bSBram Moolenaar 22587b5d5442SBram Moolenaardef Test_invalid_function_name() 22597b5d5442SBram Moolenaar var lines =<< trim END 22607b5d5442SBram Moolenaar vim9script 22617b5d5442SBram Moolenaar def s: list<string> 22627b5d5442SBram Moolenaar END 22637b5d5442SBram Moolenaar CheckScriptFailure(lines, 'E129:') 22647b5d5442SBram Moolenaar 22657b5d5442SBram Moolenaar lines =<< trim END 22667b5d5442SBram Moolenaar vim9script 22677b5d5442SBram Moolenaar def g: list<string> 22687b5d5442SBram Moolenaar END 22697b5d5442SBram Moolenaar CheckScriptFailure(lines, 'E129:') 22707b5d5442SBram Moolenaar 22717b5d5442SBram Moolenaar lines =<< trim END 22727b5d5442SBram Moolenaar vim9script 22737b5d5442SBram Moolenaar def <SID>: list<string> 22747b5d5442SBram Moolenaar END 22757b5d5442SBram Moolenaar CheckScriptFailure(lines, 'E884:') 22767b5d5442SBram Moolenaar 22777b5d5442SBram Moolenaar lines =<< trim END 22787b5d5442SBram Moolenaar vim9script 22797b5d5442SBram Moolenaar def F list<string> 22807b5d5442SBram Moolenaar END 22817b5d5442SBram Moolenaar CheckScriptFailure(lines, 'E488:') 22827b5d5442SBram Moolenaarenddef 22837b5d5442SBram Moolenaar 2284a90afb9aSBram Moolenaardef Test_partial_call() 22857a9cbca0SBram Moolenaar var Xsetlist = function('setloclist', [0]) 2286e0de171eSBram Moolenaar Xsetlist([], ' ', {title: 'test'}) 2287e0de171eSBram Moolenaar getloclist(0, {title: 1})->assert_equal({title: 'test'}) 2288a90afb9aSBram Moolenaar 2289a90afb9aSBram Moolenaar Xsetlist = function('setloclist', [0, [], ' ']) 2290e0de171eSBram Moolenaar Xsetlist({title: 'test'}) 2291e0de171eSBram Moolenaar getloclist(0, {title: 1})->assert_equal({title: 'test'}) 2292a90afb9aSBram Moolenaar 2293a90afb9aSBram Moolenaar Xsetlist = function('setqflist') 2294e0de171eSBram Moolenaar Xsetlist([], ' ', {title: 'test'}) 2295e0de171eSBram Moolenaar getqflist({title: 1})->assert_equal({title: 'test'}) 2296a90afb9aSBram Moolenaar 2297a90afb9aSBram Moolenaar Xsetlist = function('setqflist', [[], ' ']) 2298e0de171eSBram Moolenaar Xsetlist({title: 'test'}) 2299e0de171eSBram Moolenaar getqflist({title: 1})->assert_equal({title: 'test'}) 23006abd3dc2SBram Moolenaar 23016abd3dc2SBram Moolenaar var Len: func: number = function('len', ['word']) 23026abd3dc2SBram Moolenaar assert_equal(4, Len()) 2303a90afb9aSBram Moolenaarenddef 2304a90afb9aSBram Moolenaar 23052dd0a2c3SBram Moolenaardef Test_cmd_modifier() 23062dd0a2c3SBram Moolenaar tab echo '0' 2307d2c61705SBram Moolenaar CheckDefFailure(['5tab echo 3'], 'E16:') 23082dd0a2c3SBram Moolenaarenddef 23092dd0a2c3SBram Moolenaar 23102dd0a2c3SBram Moolenaardef Test_restore_modifiers() 23112dd0a2c3SBram Moolenaar # check that when compiling a :def function command modifiers are not messed 23122dd0a2c3SBram Moolenaar # up. 23137a9cbca0SBram Moolenaar var lines =<< trim END 23142dd0a2c3SBram Moolenaar vim9script 23152dd0a2c3SBram Moolenaar set eventignore= 23162dd0a2c3SBram Moolenaar autocmd QuickFixCmdPost * copen 23172dd0a2c3SBram Moolenaar def AutocmdsDisabled() 23182dd0a2c3SBram Moolenaar eval 0 23192dd0a2c3SBram Moolenaar enddef 23202dd0a2c3SBram Moolenaar func Func() 23212dd0a2c3SBram Moolenaar noautocmd call s:AutocmdsDisabled() 23222dd0a2c3SBram Moolenaar let g:ei_after = &eventignore 23232dd0a2c3SBram Moolenaar endfunc 23242dd0a2c3SBram Moolenaar Func() 23252dd0a2c3SBram Moolenaar END 23262dd0a2c3SBram Moolenaar CheckScriptSuccess(lines) 2327c0c71e9dSBram Moolenaar g:ei_after->assert_equal('') 23282dd0a2c3SBram Moolenaarenddef 23292dd0a2c3SBram Moolenaar 2330dfa3d552SBram Moolenaardef StackTop() 2331dfa3d552SBram Moolenaar eval 1 2332dfa3d552SBram Moolenaar eval 2 2333dfa3d552SBram Moolenaar # call not on fourth line 2334dfa3d552SBram Moolenaar StackBot() 2335dfa3d552SBram Moolenaarenddef 2336dfa3d552SBram Moolenaar 2337dfa3d552SBram Moolenaardef StackBot() 2338dfa3d552SBram Moolenaar # throw an error 2339dfa3d552SBram Moolenaar eval [][0] 2340dfa3d552SBram Moolenaarenddef 2341dfa3d552SBram Moolenaar 2342dfa3d552SBram Moolenaardef Test_callstack_def() 2343dfa3d552SBram Moolenaar try 2344dfa3d552SBram Moolenaar StackTop() 2345dfa3d552SBram Moolenaar catch 2346c0c71e9dSBram Moolenaar v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 2347dfa3d552SBram Moolenaar endtry 2348dfa3d552SBram Moolenaarenddef 2349dfa3d552SBram Moolenaar 2350e8211a33SBram Moolenaar" Re-using spot for variable used in block 2351e8211a33SBram Moolenaardef Test_block_scoped_var() 2352e8211a33SBram Moolenaar var lines =<< trim END 2353e8211a33SBram Moolenaar vim9script 2354e8211a33SBram Moolenaar def Func() 2355e8211a33SBram Moolenaar var x = ['a', 'b', 'c'] 2356e8211a33SBram Moolenaar if 1 2357e8211a33SBram Moolenaar var y = 'x' 2358*bb8a7ce0SBram Moolenaar map(x, (_, _) => y) 2359e8211a33SBram Moolenaar endif 2360e8211a33SBram Moolenaar var z = x 2361e8211a33SBram Moolenaar assert_equal(['x', 'x', 'x'], z) 2362e8211a33SBram Moolenaar enddef 2363e8211a33SBram Moolenaar Func() 2364e8211a33SBram Moolenaar END 2365e8211a33SBram Moolenaar CheckScriptSuccess(lines) 2366e8211a33SBram Moolenaarenddef 2367e8211a33SBram Moolenaar 2368eeece9e4SBram Moolenaardef Test_reset_did_emsg() 2369eeece9e4SBram Moolenaar var lines =<< trim END 2370eeece9e4SBram Moolenaar @s = 'blah' 2371eeece9e4SBram Moolenaar au BufWinLeave * # 2372eeece9e4SBram Moolenaar def Func() 2373eeece9e4SBram Moolenaar var winid = popup_create('popup', {}) 2374eeece9e4SBram Moolenaar exe '*s' 2375eeece9e4SBram Moolenaar popup_close(winid) 2376eeece9e4SBram Moolenaar enddef 2377eeece9e4SBram Moolenaar Func() 2378eeece9e4SBram Moolenaar END 2379eeece9e4SBram Moolenaar CheckScriptFailure(lines, 'E492:', 8) 23802d870f8dSBram Moolenaar delfunc! g:Func 2381eeece9e4SBram Moolenaarenddef 2382eeece9e4SBram Moolenaar 238357f799e6SBram Moolenaardef Test_did_emsg_reset() 238457f799e6SBram Moolenaar # executing an autocommand resets did_emsg, this should not result in a 238557f799e6SBram Moolenaar # builtin function considered failing 238657f799e6SBram Moolenaar var lines =<< trim END 238757f799e6SBram Moolenaar vim9script 238857f799e6SBram Moolenaar au BufWinLeave * # 238957f799e6SBram Moolenaar def Func() 2390767034c5SBram Moolenaar popup_menu('', {callback: (a, b) => popup_create('', {})->popup_close()}) 239157f799e6SBram Moolenaar eval [][0] 239257f799e6SBram Moolenaar enddef 239357f799e6SBram Moolenaar nno <F3> <cmd>call <sid>Func()<cr> 239457f799e6SBram Moolenaar feedkeys("\<F3>\e", 'xt') 239557f799e6SBram Moolenaar END 239657f799e6SBram Moolenaar writefile(lines, 'XemsgReset') 239757f799e6SBram Moolenaar assert_fails('so XemsgReset', ['E684:', 'E684:'], lines, 2) 239857f799e6SBram Moolenaar delete('XemsgReset') 239957f799e6SBram Moolenaar nunmap <F3> 240057f799e6SBram Moolenaar au! BufWinLeave 240157f799e6SBram Moolenaarenddef 240257f799e6SBram Moolenaar 240356602ba1SBram Moolenaardef Test_abort_with_silent_call() 240456602ba1SBram Moolenaar var lines =<< trim END 240556602ba1SBram Moolenaar vim9script 240656602ba1SBram Moolenaar g:result = 'none' 240756602ba1SBram Moolenaar def Func() 240856602ba1SBram Moolenaar g:result += 3 240956602ba1SBram Moolenaar g:result = 'yes' 241056602ba1SBram Moolenaar enddef 241156602ba1SBram Moolenaar # error is silenced, but function aborts on error 241256602ba1SBram Moolenaar silent! Func() 241356602ba1SBram Moolenaar assert_equal('none', g:result) 241456602ba1SBram Moolenaar unlet g:result 241556602ba1SBram Moolenaar END 241656602ba1SBram Moolenaar CheckScriptSuccess(lines) 241756602ba1SBram Moolenaarenddef 241856602ba1SBram Moolenaar 2419f665e97fSBram Moolenaardef Test_continues_with_silent_error() 2420f665e97fSBram Moolenaar var lines =<< trim END 2421f665e97fSBram Moolenaar vim9script 2422f665e97fSBram Moolenaar g:result = 'none' 2423f665e97fSBram Moolenaar def Func() 2424f665e97fSBram Moolenaar silent! g:result += 3 2425f665e97fSBram Moolenaar g:result = 'yes' 2426f665e97fSBram Moolenaar enddef 2427f665e97fSBram Moolenaar # error is silenced, function does not abort 2428f665e97fSBram Moolenaar Func() 2429f665e97fSBram Moolenaar assert_equal('yes', g:result) 2430f665e97fSBram Moolenaar unlet g:result 2431f665e97fSBram Moolenaar END 2432f665e97fSBram Moolenaar CheckScriptSuccess(lines) 2433f665e97fSBram Moolenaarenddef 2434f665e97fSBram Moolenaar 2435af0df47aSBram Moolenaardef Test_abort_even_with_silent() 2436af0df47aSBram Moolenaar var lines =<< trim END 2437af0df47aSBram Moolenaar vim9script 2438af0df47aSBram Moolenaar g:result = 'none' 2439af0df47aSBram Moolenaar def Func() 2440af0df47aSBram Moolenaar eval {-> ''}() .. '' .. {}['X'] 2441af0df47aSBram Moolenaar g:result = 'yes' 2442af0df47aSBram Moolenaar enddef 2443f665e97fSBram Moolenaar silent! Func() 2444af0df47aSBram Moolenaar assert_equal('none', g:result) 24454029cabbSBram Moolenaar unlet g:result 24464029cabbSBram Moolenaar END 24474029cabbSBram Moolenaar CheckScriptSuccess(lines) 24484029cabbSBram Moolenaarenddef 24494029cabbSBram Moolenaar 2450f665e97fSBram Moolenaardef Test_cmdmod_silent_restored() 2451f665e97fSBram Moolenaar var lines =<< trim END 2452f665e97fSBram Moolenaar vim9script 2453f665e97fSBram Moolenaar def Func() 2454f665e97fSBram Moolenaar g:result = 'none' 2455f665e97fSBram Moolenaar silent! g:result += 3 2456f665e97fSBram Moolenaar g:result = 'none' 2457f665e97fSBram Moolenaar g:result += 3 2458f665e97fSBram Moolenaar enddef 2459f665e97fSBram Moolenaar Func() 2460f665e97fSBram Moolenaar END 2461f665e97fSBram Moolenaar # can't use CheckScriptFailure, it ignores the :silent! 2462f665e97fSBram Moolenaar var fname = 'Xdefsilent' 2463f665e97fSBram Moolenaar writefile(lines, fname) 2464f665e97fSBram Moolenaar var caught = 'no' 2465f665e97fSBram Moolenaar try 2466f665e97fSBram Moolenaar exe 'source ' .. fname 2467f665e97fSBram Moolenaar catch /E1030:/ 2468f665e97fSBram Moolenaar caught = 'yes' 2469f665e97fSBram Moolenaar assert_match('Func, line 4', v:throwpoint) 2470f665e97fSBram Moolenaar endtry 2471f665e97fSBram Moolenaar assert_equal('yes', caught) 2472f665e97fSBram Moolenaar delete(fname) 2473f665e97fSBram Moolenaarenddef 2474f665e97fSBram Moolenaar 24752fecb531SBram Moolenaardef Test_cmdmod_silent_nested() 24762fecb531SBram Moolenaar var lines =<< trim END 24772fecb531SBram Moolenaar vim9script 24782fecb531SBram Moolenaar var result = '' 24792fecb531SBram Moolenaar 24802fecb531SBram Moolenaar def Error() 24812fecb531SBram Moolenaar result ..= 'Eb' 24822fecb531SBram Moolenaar eval [][0] 24832fecb531SBram Moolenaar result ..= 'Ea' 24842fecb531SBram Moolenaar enddef 24852fecb531SBram Moolenaar 24862fecb531SBram Moolenaar def Crash() 24872fecb531SBram Moolenaar result ..= 'Cb' 24882fecb531SBram Moolenaar sil! Error() 24892fecb531SBram Moolenaar result ..= 'Ca' 24902fecb531SBram Moolenaar enddef 24912fecb531SBram Moolenaar 24922fecb531SBram Moolenaar Crash() 24932fecb531SBram Moolenaar assert_equal('CbEbEaCa', result) 24942fecb531SBram Moolenaar END 24952fecb531SBram Moolenaar CheckScriptSuccess(lines) 24962fecb531SBram Moolenaarenddef 24972fecb531SBram Moolenaar 24984029cabbSBram Moolenaardef Test_dict_member_with_silent() 24994029cabbSBram Moolenaar var lines =<< trim END 25004029cabbSBram Moolenaar vim9script 25014029cabbSBram Moolenaar g:result = 'none' 25024029cabbSBram Moolenaar var d: dict<any> 25034029cabbSBram Moolenaar def Func() 25044029cabbSBram Moolenaar try 25052949cfdbSBram Moolenaar g:result = map([], (_, v) => ({}[v]))->join() .. d[''] 25064029cabbSBram Moolenaar catch 25074029cabbSBram Moolenaar endtry 25084029cabbSBram Moolenaar enddef 25094029cabbSBram Moolenaar silent! Func() 25104029cabbSBram Moolenaar assert_equal('0', g:result) 25114029cabbSBram Moolenaar unlet g:result 2512af0df47aSBram Moolenaar END 2513af0df47aSBram Moolenaar CheckScriptSuccess(lines) 2514af0df47aSBram Moolenaarenddef 2515af0df47aSBram Moolenaar 2516f904133eSBram Moolenaardef Test_skip_cmds_with_silent() 2517f904133eSBram Moolenaar var lines =<< trim END 2518f904133eSBram Moolenaar vim9script 2519f904133eSBram Moolenaar 2520f904133eSBram Moolenaar def Func(b: bool) 2521f904133eSBram Moolenaar Crash() 2522f904133eSBram Moolenaar enddef 2523f904133eSBram Moolenaar 2524f904133eSBram Moolenaar def Crash() 2525f904133eSBram Moolenaar sil! :/not found/d _ 2526f904133eSBram Moolenaar sil! :/not found/put _ 2527f904133eSBram Moolenaar enddef 2528f904133eSBram Moolenaar 2529f904133eSBram Moolenaar Func(true) 2530f904133eSBram Moolenaar END 2531f904133eSBram Moolenaar CheckScriptSuccess(lines) 2532f904133eSBram Moolenaarenddef 2533f904133eSBram Moolenaar 25345b3d1bb0SBram Moolenaardef Test_opfunc() 25355b3d1bb0SBram Moolenaar nnoremap <F3> <cmd>set opfunc=Opfunc<cr>g@ 25365b3d1bb0SBram Moolenaar def g:Opfunc(_: any): string 25375b3d1bb0SBram Moolenaar setline(1, 'ASDF') 25385b3d1bb0SBram Moolenaar return '' 25395b3d1bb0SBram Moolenaar enddef 25405b3d1bb0SBram Moolenaar new 25415b3d1bb0SBram Moolenaar setline(1, 'asdf') 25425b3d1bb0SBram Moolenaar feedkeys("\<F3>$", 'x') 25435b3d1bb0SBram Moolenaar assert_equal('ASDF', getline(1)) 25445b3d1bb0SBram Moolenaar 25455b3d1bb0SBram Moolenaar bwipe! 25465b3d1bb0SBram Moolenaar nunmap <F3> 25475b3d1bb0SBram Moolenaarenddef 25485b3d1bb0SBram Moolenaar 2549077a4231SBram Moolenaar" this was crashing on exit 2550077a4231SBram Moolenaardef Test_nested_lambda_in_closure() 2551077a4231SBram Moolenaar var lines =<< trim END 2552077a4231SBram Moolenaar vim9script 2553077a4231SBram Moolenaar def Outer() 2554077a4231SBram Moolenaar def g:Inner() 2555077a4231SBram Moolenaar echo map([1, 2, 3], {_, v -> v + 1}) 2556077a4231SBram Moolenaar enddef 2557077a4231SBram Moolenaar g:Inner() 2558077a4231SBram Moolenaar enddef 2559077a4231SBram Moolenaar defcompile 2560077a4231SBram Moolenaar writefile(['Done'], 'XnestedDone') 2561077a4231SBram Moolenaar quit 2562077a4231SBram Moolenaar END 2563077a4231SBram Moolenaar if !RunVim([], lines, '--clean') 2564077a4231SBram Moolenaar return 2565077a4231SBram Moolenaar endif 2566077a4231SBram Moolenaar assert_equal(['Done'], readfile('XnestedDone')) 2567077a4231SBram Moolenaar delete('XnestedDone') 2568077a4231SBram Moolenaarenddef 2569077a4231SBram Moolenaar 257004947cc6SBram Moolenaardef Test_check_func_arg_types() 257104947cc6SBram Moolenaar var lines =<< trim END 257204947cc6SBram Moolenaar vim9script 257304947cc6SBram Moolenaar def F1(x: string): string 257404947cc6SBram Moolenaar return x 257504947cc6SBram Moolenaar enddef 257604947cc6SBram Moolenaar 257704947cc6SBram Moolenaar def F2(x: number): number 257804947cc6SBram Moolenaar return x + 1 257904947cc6SBram Moolenaar enddef 258004947cc6SBram Moolenaar 258104947cc6SBram Moolenaar def G(g: func): dict<func> 258204947cc6SBram Moolenaar return {f: g} 258304947cc6SBram Moolenaar enddef 258404947cc6SBram Moolenaar 258504947cc6SBram Moolenaar def H(d: dict<func>): string 258604947cc6SBram Moolenaar return d.f('a') 258704947cc6SBram Moolenaar enddef 258804947cc6SBram Moolenaar END 258904947cc6SBram Moolenaar 259004947cc6SBram Moolenaar CheckScriptSuccess(lines + ['echo H(G(F1))']) 259104947cc6SBram Moolenaar CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:') 259204947cc6SBram Moolenaarenddef 259304947cc6SBram Moolenaar 2594701cc6caSBram Moolenaardef Test_compile_error() 2595701cc6caSBram Moolenaar var lines =<< trim END 2596701cc6caSBram Moolenaar def g:Broken() 2597701cc6caSBram Moolenaar echo 'a' + {} 2598701cc6caSBram Moolenaar enddef 2599701cc6caSBram Moolenaar call g:Broken() 2600701cc6caSBram Moolenaar END 2601701cc6caSBram Moolenaar # First call: compilation error 2602701cc6caSBram Moolenaar CheckScriptFailure(lines, 'E1051: Wrong argument type for +') 2603701cc6caSBram Moolenaar 2604701cc6caSBram Moolenaar # Second call won't try compiling again 2605701cc6caSBram Moolenaar assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken') 2606599410cbSBram Moolenaar delfunc g:Broken 2607599410cbSBram Moolenaar 2608599410cbSBram Moolenaar # No error when compiling with :silent! 2609599410cbSBram Moolenaar lines =<< trim END 2610599410cbSBram Moolenaar def g:Broken() 2611599410cbSBram Moolenaar echo 'a' + [] 2612599410cbSBram Moolenaar enddef 2613599410cbSBram Moolenaar silent! defcompile 2614599410cbSBram Moolenaar END 2615599410cbSBram Moolenaar CheckScriptSuccess(lines) 2616599410cbSBram Moolenaar 2617599410cbSBram Moolenaar # Calling the function won't try compiling again 2618599410cbSBram Moolenaar assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken') 2619599410cbSBram Moolenaar delfunc g:Broken 2620701cc6caSBram Moolenaarenddef 2621701cc6caSBram Moolenaar 2622962c43bfSBram Moolenaardef Test_ignored_argument() 2623962c43bfSBram Moolenaar var lines =<< trim END 2624962c43bfSBram Moolenaar vim9script 2625962c43bfSBram Moolenaar def Ignore(_, _): string 2626962c43bfSBram Moolenaar return 'yes' 2627962c43bfSBram Moolenaar enddef 2628962c43bfSBram Moolenaar assert_equal('yes', Ignore(1, 2)) 2629962c43bfSBram Moolenaar 2630962c43bfSBram Moolenaar func Ok(_) 2631962c43bfSBram Moolenaar return a:_ 2632962c43bfSBram Moolenaar endfunc 2633962c43bfSBram Moolenaar assert_equal('ok', Ok('ok')) 2634962c43bfSBram Moolenaar 2635962c43bfSBram Moolenaar func Oktoo() 2636962c43bfSBram Moolenaar let _ = 'too' 2637962c43bfSBram Moolenaar return _ 2638962c43bfSBram Moolenaar endfunc 2639962c43bfSBram Moolenaar assert_equal('too', Oktoo()) 2640962c43bfSBram Moolenaar END 2641962c43bfSBram Moolenaar CheckScriptSuccess(lines) 2642962c43bfSBram Moolenaar 2643962c43bfSBram Moolenaar lines =<< trim END 2644962c43bfSBram Moolenaar def Ignore(_: string): string 2645962c43bfSBram Moolenaar return _ 2646962c43bfSBram Moolenaar enddef 2647962c43bfSBram Moolenaar defcompile 2648962c43bfSBram Moolenaar END 2649962c43bfSBram Moolenaar CheckScriptFailure(lines, 'E1181:', 1) 2650962c43bfSBram Moolenaar 2651962c43bfSBram Moolenaar lines =<< trim END 2652962c43bfSBram Moolenaar var _ = 1 2653962c43bfSBram Moolenaar END 2654962c43bfSBram Moolenaar CheckDefAndScriptFailure(lines, 'E1181:', 1) 2655962c43bfSBram Moolenaarenddef 2656962c43bfSBram Moolenaar 2657*bb8a7ce0SBram Moolenaardef Test_too_many_arguments() 2658*bb8a7ce0SBram Moolenaar var lines =<< trim END 2659*bb8a7ce0SBram Moolenaar echo [0, 1, 2]->map(() => 123) 2660*bb8a7ce0SBram Moolenaar END 2661*bb8a7ce0SBram Moolenaar CheckDefExecAndScriptFailure(lines, 'E1106: 2 arguments too many', 1) 2662*bb8a7ce0SBram Moolenaar 2663*bb8a7ce0SBram Moolenaar lines =<< trim END 2664*bb8a7ce0SBram Moolenaar echo [0, 1, 2]->map((_) => 123) 2665*bb8a7ce0SBram Moolenaar END 2666*bb8a7ce0SBram Moolenaar CheckDefExecAndScriptFailure(lines, 'E1106: One argument too many', 1) 2667*bb8a7ce0SBram Moolenaarenddef 2668077a4231SBram Moolenaar 2669f7779c63SBram Moolenaar 26705deeb3f1SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 2671