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