Patch 8.2.4124
Problem:    Vim9: method in compiled function may not see script item.
Solution:   Make sure not to skip to the next line. (closes #9496)
Files:      src/vim9expr.c, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.4123/src/vim9expr.c      2022-01-16 20:59:32.429613796 +0000
--- src/vim9expr.c      2022-01-17 20:44:48.803480942 +0000
***************
*** 1732,1752 ****
                }
                else
                {
                    *paren = NUL;
!                   if (compile_expr8(arg, cctx, ppconst) == FAIL
!                                                   || *skipwhite(*arg) != NUL)
                    {
-                       *paren = '(';
                        semsg(_(e_invalid_expression_str), pstart);
                        return FAIL;
                    }
-                   *paren = '(';
                }
  
-               // Remember the next instruction index, where the instructions
-               // for arguments are being written.
-               expr_isn_end = cctx->ctx_instr.ga_len;
- 
                // Compile the arguments.
                if (**arg != '(')
                {
--- 1732,1754 ----
                }
                else
                {
+                   int fail;
+                   int save_len = cctx->ctx_ufunc->uf_lines.ga_len;
+ 
                    *paren = NUL;
!                   // do not look in the next line
!                   cctx->ctx_ufunc->uf_lines.ga_len = 1;
!                   fail = compile_expr8(arg, cctx, ppconst) == FAIL
!                                                   || *skipwhite(*arg) != NUL;
!                   *paren = '(';
!                   cctx->ctx_ufunc->uf_lines.ga_len = save_len;
!                   if (fail)
                    {
                        semsg(_(e_invalid_expression_str), pstart);
                        return FAIL;
                    }
                }
  
                // Compile the arguments.
                if (**arg != '(')
                {
***************
*** 1756,1761 ****
--- 1758,1768 ----
                        semsg(_(e_missing_parenthesis_str), *arg);
                    return FAIL;
                }
+ 
+               // Remember the next instruction index, where the instructions
+               // for arguments are being written.
+               expr_isn_end = cctx->ctx_instr.ga_len;
+ 
                *arg = skipwhite(*arg + 1);
                if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL)
                    return FAIL;
*** ../vim-8.2.4123/src/testdir/test_vim9_expr.vim      2022-01-16 
20:59:32.429613796 +0000
--- src/testdir/test_vim9_expr.vim      2022-01-17 20:47:18.475181420 +0000
***************
*** 1717,1723 ****
  let $TESTVAR = 'testvar'
  
  " type casts
! def Test_expr7t()
    var lines =<< trim END
        var ls: list<string> = ['a', <string>g:string_empty]
        var ln: list<number> = [<number>g:anint, <number>g:thefour]
--- 1717,1723 ----
  let $TESTVAR = 'testvar'
  
  " type casts
! def Test_expr7()
    var lines =<< trim END
        var ls: list<string> = ['a', <string>g:string_empty]
        var ln: list<number> = [<number>g:anint, <number>g:thefour]
***************
*** 1743,1749 ****
  enddef
  
  " test low level expression
! def Test_expr7_number()
    # number constant
    var lines =<< trim END
        assert_equal(0, 0)
--- 1743,1749 ----
  enddef
  
  " test low level expression
! def Test_expr8_number()
    # number constant
    var lines =<< trim END
        assert_equal(0, 0)
***************
*** 1756,1762 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_float()
    # float constant
    if !has('float')
      MissingFeature 'float'
--- 1756,1762 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_float()
    # float constant
    if !has('float')
      MissingFeature 'float'
***************
*** 1771,1777 ****
    endif
  enddef
  
! def Test_expr7_blob()
    # blob constant
    var lines =<< trim END
        assert_equal(g:blob_empty, 0z)
--- 1771,1777 ----
    endif
  enddef
  
! def Test_expr8_blob()
    # blob constant
    var lines =<< trim END
        assert_equal(g:blob_empty, 0z)
***************
*** 1803,1809 ****
    CheckDefAndScriptFailure(["var x = 0z123"], 'E973:', 1)
  enddef
  
! def Test_expr7_string()
    # string constant
    var lines =<< trim END
        assert_equal(g:string_empty, '')
--- 1803,1809 ----
    CheckDefAndScriptFailure(["var x = 0z123"], 'E973:', 1)
  enddef
  
! def Test_expr8_string()
    # string constant
    var lines =<< trim END
        assert_equal(g:string_empty, '')
***************
*** 1820,1826 ****
    CheckDefAndScriptFailure(["var x = 'abc"], 'E115:', 1)
  enddef
  
! def Test_expr7_vimvar()
    v:errors = []
    var errs: list<string> = v:errors
    CheckDefFailure(['var errs: list<number> = v:errors'], 'E1012:')
--- 1820,1826 ----
    CheckDefAndScriptFailure(["var x = 'abc"], 'E115:', 1)
  enddef
  
! def Test_expr8_vimvar()
    v:errors = []
    var errs: list<string> = v:errors
    CheckDefFailure(['var errs: list<number> = v:errors'], 'E1012:')
***************
*** 1845,1851 ****
    bwipe!
  enddef
  
! def Test_expr7_special()
    # special constant
    var lines =<< trim END
        assert_equal(g:special_true, true)
--- 1845,1851 ----
    bwipe!
  enddef
  
! def Test_expr8_special()
    # special constant
    var lines =<< trim END
        assert_equal(g:special_true, true)
***************
*** 1882,1888 ****
    CheckDefAndScriptFailure(['v:none = 22'], 'E46:', 1)
  enddef
  
! def Test_expr7_list()
    # list
    var lines =<< trim END
        assert_equal(g:list_empty, [])
--- 1882,1888 ----
    CheckDefAndScriptFailure(['v:none = 22'], 'E46:', 1)
  enddef
  
! def Test_expr8_list()
    # list
    var lines =<< trim END
        assert_equal(g:list_empty, [])
***************
*** 1955,1961 ****
    CheckDefAndScriptFailure(lines + ['echo numbers[a :b]'], 'E1004:', 4)
  enddef
  
! def Test_expr7_list_vim9script()
    var lines =<< trim END
        var l = [
                11,
--- 1955,1961 ----
    CheckDefAndScriptFailure(lines + ['echo numbers[a :b]'], 'E1004:', 4)
  enddef
  
! def Test_expr8_list_vim9script()
    var lines =<< trim END
        var l = [
                11,
***************
*** 2043,2049 ****
              x == 2
  enddef
  
! def Test_expr7_lambda()
    var lines =<< trim END
        var La = () => 'result'
        # comment
--- 2043,2049 ----
              x == 2
  enddef
  
! def Test_expr8_lambda()
    var lines =<< trim END
        var La = () => 'result'
        # comment
***************
*** 2129,2135 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_lambda_block()
    var lines =<< trim END
        var Func = (s: string): string => {
                        return 'hello ' .. s
--- 2129,2135 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_lambda_block()
    var lines =<< trim END
        var Func = (s: string): string => {
                        return 'hello ' .. s
***************
*** 2209,2215 ****
              x == 2
  enddef
  
! def Test_expr7_new_lambda()
    var lines =<< trim END
        var La = () => 'result'
        assert_equal('result', La())
--- 2209,2215 ----
              x == 2
  enddef
  
! def Test_expr8_new_lambda()
    var lines =<< trim END
        var La = () => 'result'
        assert_equal('result', La())
***************
*** 2294,2300 ****
    CheckDefAndScriptFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
  enddef
  
! def Test_expr7_lambda_vim9script()
    var lines =<< trim END
        var v = 10->((a) =>
            a
--- 2294,2300 ----
    CheckDefAndScriptFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
  enddef
  
! def Test_expr8_lambda_vim9script()
    var lines =<< trim END
        var v = 10->((a) =>
            a
***************
*** 2313,2319 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_funcref()
    var lines =<< trim END
        def RetNumber(): number
          return 123
--- 2313,2319 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_funcref()
    var lines =<< trim END
        def RetNumber(): number
          return 123
***************
*** 2350,2356 ****
  let g:test_space_dict = {'': 'empty', ' ': 'space'}
  let g:test_hash_dict = #{one: 1, two: 2}
  
! def Test_expr7_dict()
    # dictionary
    var lines =<< trim END
        assert_equal(g:dict_empty, {})
--- 2350,2356 ----
  let g:test_space_dict = {'': 'empty', ' ': 'space'}
  let g:test_hash_dict = #{one: 1, two: 2}
  
! def Test_expr8_dict()
    # dictionary
    var lines =<< trim END
        assert_equal(g:dict_empty, {})
***************
*** 2461,2467 ****
    CheckDefExecAndScriptFailure(['{}[getftype("file")]'], 'E716: Key not 
present in Dictionary: ""', 1)
  enddef
  
! def Test_expr7_dict_vim9script()
    var lines =<< trim END
        var d = {
                ['one']:
--- 2461,2467 ----
    CheckDefExecAndScriptFailure(['{}[getftype("file")]'], 'E716: Key not 
present in Dictionary: ""', 1)
  enddef
  
! def Test_expr8_dict_vim9script()
    var lines =<< trim END
        var d = {
                ['one']:
***************
*** 2592,2598 ****
    CheckScriptSuccess(lines)
  enddef
  
! def Test_expr7_dict_in_block()
    var lines =<< trim END
        vim9script
        command MyCommand {
--- 2592,2598 ----
    CheckScriptSuccess(lines)
  enddef
  
! def Test_expr8_dict_in_block()
    var lines =<< trim END
        vim9script
        command MyCommand {
***************
*** 2615,2621 ****
    delcommand YourCommand
  enddef
  
! def Test_expr7_call_2bool()
    var lines =<< trim END
        vim9script
  
--- 2615,2621 ----
    delcommand YourCommand
  enddef
  
! def Test_expr8_call_2bool()
    var lines =<< trim END
        vim9script
  
***************
*** 2663,2669 ****
    CheckDefExecAndScriptFailure(["var d: dict<number>", "d = g:list_empty"], 
'E1012: Type mismatch; expected dict<number> but got list<unknown>', 2)
  enddef
  
! def Test_expr7_any_index_slice()
    var lines =<< trim END
      # getting the one member should clear the list only after getting the item
      assert_equal('bbb', ['aaa', 'bbb', 'ccc'][1])
--- 2663,2669 ----
    CheckDefExecAndScriptFailure(["var d: dict<number>", "d = g:list_empty"], 
'E1012: Type mismatch; expected dict<number> but got list<unknown>', 2)
  enddef
  
! def Test_expr8_any_index_slice()
    var lines =<< trim END
      # getting the one member should clear the list only after getting the item
      assert_equal('bbb', ['aaa', 'bbb', 'ccc'][1])
***************
*** 2817,2823 ****
    b:someVar = &fdm
  enddef
  
! def Test_expr7_option()
    var lines =<< trim END
        # option
        set ts=11
--- 2817,2823 ----
    b:someVar = &fdm
  enddef
  
! def Test_expr8_option()
    var lines =<< trim END
        # option
        set ts=11
***************
*** 2844,2850 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_environment()
    var lines =<< trim END
        # environment variable
        assert_equal('testvar', $TESTVAR)
--- 2844,2850 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_environment()
    var lines =<< trim END
        # environment variable
        assert_equal('testvar', $TESTVAR)
***************
*** 2856,2862 ****
    CheckDefAndScriptFailure(["$"], ['E1002:', 'E15:'], 1)
  enddef
  
! def Test_expr7_register()
    var lines =<< trim END
        @a = 'register a'
        assert_equal('register a', @a)
--- 2856,2862 ----
    CheckDefAndScriptFailure(["$"], ['E1002:', 'E15:'], 1)
  enddef
  
! def Test_expr8_register()
    var lines =<< trim END
        @a = 'register a'
        assert_equal('register a', @a)
***************
*** 2882,2888 ****
  enddef
  
  " This is slow when run under valgrind.
! def Test_expr7_namespace()
    var lines =<< trim END
        g:some_var = 'some'
        assert_equal('some', get(g:, 'some_var'))
--- 2882,2888 ----
  enddef
  
  " This is slow when run under valgrind.
! def Test_expr8_namespace()
    var lines =<< trim END
        g:some_var = 'some'
        assert_equal('some', get(g:, 'some_var'))
***************
*** 2911,2917 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_namespace_loop_def()
    var lines =<< trim END
        # check using g: in a for loop more than DO_NOT_FREE_CNT times
        var exists = 0
--- 2911,2917 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_namespace_loop_def()
    var lines =<< trim END
        # check using g: in a for loop more than DO_NOT_FREE_CNT times
        var exists = 0
***************
*** 2930,2937 ****
  enddef
  
  " NOTE: this is known to be slow.  To skip use:
! "   :let $TEST_SKIP_PAT = 'Test_expr7_namespace_loop_script'
! def Test_expr7_namespace_loop_script()
    var lines =<< trim END
        vim9script
        # check using g: in a for loop more than DO_NOT_FREE_CNT times
--- 2930,2937 ----
  enddef
  
  " NOTE: this is known to be slow.  To skip use:
! "   :let $TEST_SKIP_PAT = 'Test_expr8_namespace_loop_script'
! def Test_expr8_namespace_loop_script()
    var lines =<< trim END
        vim9script
        # check using g: in a for loop more than DO_NOT_FREE_CNT times
***************
*** 2950,2956 ****
    CheckScriptSuccess(lines)
  enddef
  
! def Test_expr7_parens()
    # (expr)
    var lines =<< trim END
        assert_equal(4, (6 * 4) / 6)
--- 2950,2956 ----
    CheckScriptSuccess(lines)
  enddef
  
! def Test_expr8_parens()
    # (expr)
    var lines =<< trim END
        assert_equal(4, (6 * 4) / 6)
***************
*** 2982,2988 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_negate_add()
    var lines =<< trim END
        assert_equal(-99, -99)
        assert_equal(-99, - 99)
--- 2982,2988 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_negate_add()
    var lines =<< trim END
        assert_equal(-99, -99)
        assert_equal(-99, - 99)
***************
*** 3031,3037 ****
    legacy return #{key: 'ok'}.key
  enddef
  
! def Test_expr7_legacy_script()
    var lines =<< trim END
        let s:legacy = 'legacy'
        def GetLocal(): string
--- 3031,3037 ----
    legacy return #{key: 'ok'}.key
  enddef
  
! def Test_expr8_legacy_script()
    var lines =<< trim END
        let s:legacy = 'legacy'
        def GetLocal(): string
***************
*** 3065,3071 ****
    return arg
  enddef
  
! def Test_expr7_call()
    var lines =<< trim END
        assert_equal('yes', 'yes'->Echo())
        assert_equal(true, !range(5)->empty())
--- 3065,3071 ----
    return arg
  enddef
  
! def Test_expr8_call()
    var lines =<< trim END
        assert_equal('yes', 'yes'->Echo())
        assert_equal(true, !range(5)->empty())
***************
*** 3098,3104 ****
    delete('Xruntime', 'rf')
  enddef
  
! def Test_expr7_method_call()
    var lines =<< trim END
        new
        setline(1, ['first', 'last'])
--- 3098,3104 ----
    delete('Xruntime', 'rf')
  enddef
  
! def Test_expr8_method_call()
    var lines =<< trim END
        new
        setline(1, ['first', 'last'])
***************
*** 3175,3181 ****
    CheckDefExecFailure(lines, 'E1013:')
  enddef
  
! def Test_expr7_method_call_linebreak()
    # this was giving an error when skipping over the expression
    var lines =<< trim END
        vim9script
--- 3175,3181 ----
    CheckDefExecFailure(lines, 'E1013:')
  enddef
  
! def Test_expr8_method_call_linebreak()
    # this was giving an error when skipping over the expression
    var lines =<< trim END
        vim9script
***************
*** 3191,3198 ****
    CheckScriptSuccess(lines)
  enddef
  
  
! def Test_expr7_not()
    var lines =<< trim END
        assert_equal(true, !'')
        assert_equal(true, ![])
--- 3191,3224 ----
    CheckScriptSuccess(lines)
  enddef
  
+ def Test_expr8_method_call_import()
+   var lines =<< trim END
+       vim9script
+       export def Square(items: list<number>): list<number>
+           return map(items, (_, i) => i * i)
+       enddef
+   END
+   call writefile(lines, 'Xsquare.vim')
+ 
+   lines =<< trim END
+       vim9script
+       import './Xsquare.vim'
+ 
+       def Test(): list<number>
+         return range(5)
+             ->Xsquare.Square()
+             ->map((_, i) => i * 10)
+       enddef
+ 
+       assert_equal([0, 10, 40, 90, 160], Test())
+   END
+   CheckScriptSuccess(lines)
+ 
+   delete('Xsquare.vim')
+ enddef
+ 
  
! def Test_expr8_not()
    var lines =<< trim END
        assert_equal(true, !'')
        assert_equal(true, ![])
***************
*** 3244,3250 ****
  
  let g:anumber = 42
  
! def Test_expr7_negate()
    var lines =<< trim END
        var nr = 1
        assert_equal(-1, -nr)
--- 3270,3276 ----
  
  let g:anumber = 42
  
! def Test_expr8_negate()
    var lines =<< trim END
        var nr = 1
        assert_equal(-1, -nr)
***************
*** 3253,3259 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! func Test_expr7_fails()
    call CheckDefFailure(["var x = (12"], "E1097:", 3)
    call CheckScriptFailure(['vim9script', "var x = (12"], 'E110:', 2)
  
--- 3279,3285 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! func Test_expr8_fails()
    call CheckDefFailure(["var x = (12"], "E1097:", 3)
    call CheckScriptFailure(['vim9script', "var x = (12"], 'E110:', 2)
  
***************
*** 3313,3319 ****
    return a:one .. a:two
  endfunc
  
! def Test_expr7_trailing()
    var lines =<< trim END
        # user function call
        assert_equal(123, g:CallMe(123))
--- 3339,3345 ----
    return a:one .. a:two
  endfunc
  
! def Test_expr8_trailing()
    var lines =<< trim END
        # user function call
        assert_equal(123, g:CallMe(123))
***************
*** 3349,3355 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_string_subscript()
    var lines =<< trim END
      var text = 'abcdef'
      assert_equal('f', text[-1])
--- 3375,3381 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_string_subscript()
    var lines =<< trim END
      var text = 'abcdef'
      assert_equal('f', text[-1])
***************
*** 3448,3454 ****
    CheckDefAndScriptFailure(lines, ['E1012: Type mismatch; expected number but 
got string', 'E1030: Using a String as a Number: "2"'], 1)
  enddef
  
! def Test_expr7_list_subscript()
    var lines =<< trim END
        var list = [0, 1, 2, 3, 4]
        assert_equal(0, list[0])
--- 3474,3480 ----
    CheckDefAndScriptFailure(lines, ['E1012: Type mismatch; expected number but 
got string', 'E1030: Using a String as a Number: "2"'], 1)
  enddef
  
! def Test_expr8_list_subscript()
    var lines =<< trim END
        var list = [0, 1, 2, 3, 4]
        assert_equal(0, list[0])
***************
*** 3491,3497 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_dict_subscript()
    var lines =<< trim END
        var l = [{lnum: 2}, {lnum: 1}]
        var res = l[0].lnum > l[1].lnum
--- 3517,3523 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_dict_subscript()
    var lines =<< trim END
        var l = [{lnum: 2}, {lnum: 1}]
        var res = l[0].lnum > l[1].lnum
***************
*** 3512,3518 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_blob_subscript()
    var lines =<< trim END
        var b = 0z112233
        assert_equal(0x11, b[0])
--- 3538,3544 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_blob_subscript()
    var lines =<< trim END
        var b = 0z112233
        assert_equal(0x11, b[0])
***************
*** 3524,3530 ****
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr7_subscript_linebreak()
    var lines =<< trim END
        var range = range(
                      3)
--- 3550,3556 ----
    CheckDefAndScriptSuccess(lines)
  enddef
  
! def Test_expr8_subscript_linebreak()
    var lines =<< trim END
        var range = range(
                      3)
***************
*** 3567,3573 ****
    CheckDefAndScriptFailure(lines, ['E1127:', 'E116:'], 2)
  enddef
  
! func Test_expr7_trailing_fails()
    call CheckDefAndScriptFailure(['var l = [2]', 'l->((ll) => add(ll, 8))'], 
'E107:', 2)
    call CheckDefAndScriptFailure(['var l = [2]', 'l->((ll) => add(ll, 8)) 
()'], 'E274:', 2)
  endfunc
--- 3593,3599 ----
    CheckDefAndScriptFailure(lines, ['E1127:', 'E116:'], 2)
  enddef
  
! func Test_expr8_trailing_fails()
    call CheckDefAndScriptFailure(['var l = [2]', 'l->((ll) => add(ll, 8))'], 
'E107:', 2)
    call CheckDefAndScriptFailure(['var l = [2]', 'l->((ll) => add(ll, 8)) 
()'], 'E274:', 2)
  endfunc
*** ../vim-8.2.4123/src/version.c       2022-01-17 20:09:02.860881495 +0000
--- src/version.c       2022-01-17 20:29:37.573463180 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4124,
  /**/

-- 
There are 2 kinds of people in my world: those who know Unix, Perl, Vim, GNU,
Linux, etc, and those who know COBOL.  It gets very difficult for me at
parties, not knowing which group to socialise with :-)
                                                Sitaram Chamarty

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220117205115.53E311C044E%40moolenaar.net.

Raspunde prin e-mail lui