Patch 8.2.3169
Problem:    Vim9: cannot handle nested inline function.
Solution:   Check for nested inline function. (closes #8575)
Files:      src/userfunc.c, src/testdir/test_vim9_func.vim,
            src/testdir/test_vim9_expr.vim


*** ../vim-8.2.3168/src/userfunc.c      2021-07-08 21:38:45.339232318 +0200
--- src/userfunc.c      2021-07-15 21:50:54.937285120 +0200
***************
*** 634,639 ****
--- 634,640 ----
                                                   || eap->cmdidx == CMD_block;
  #define MAX_FUNC_NESTING 50
      char      nesting_def[MAX_FUNC_NESTING];
+     char      nesting_inline[MAX_FUNC_NESTING];
      int               nesting = 0;
      getline_opt_T getline_options;
      int               indent = 2;
***************
*** 658,664 ****
            ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL;
      }
  
!     nesting_def[nesting] = vim9_function;
      getline_options = vim9_function
                                ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT;
      for (;;)
--- 659,666 ----
            ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL;
      }
  
!     nesting_def[0] = vim9_function;
!     nesting_inline[0] = eap->cmdidx == CMD_block;
      getline_options = vim9_function
                                ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT;
      for (;;)
***************
*** 705,714 ****
            SOURCING_LNUM = sourcing_lnum_top;
            if (skip_until != NULL)
                semsg(_(e_missing_heredoc_end_marker_str), skip_until);
            else if (eap->cmdidx == CMD_def)
                emsg(_(e_missing_enddef));
-           else if (eap->cmdidx == CMD_block)
-               emsg(_(e_missing_end_block));
            else
                emsg(_("E126: Missing :endfunction"));
            goto theend;
--- 707,716 ----
            SOURCING_LNUM = sourcing_lnum_top;
            if (skip_until != NULL)
                semsg(_(e_missing_heredoc_end_marker_str), skip_until);
+           else if (nesting_inline[nesting])
+               emsg(_(e_missing_end_block));
            else if (eap->cmdidx == CMD_def)
                emsg(_(e_missing_enddef));
            else
                emsg(_("E126: Missing :endfunction"));
            goto theend;
***************
*** 765,771 ****
        }
        else
        {
!           int c;
  
            // skip ':' and blanks
            for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p)
--- 767,774 ----
        }
        else
        {
!           int     c;
!           char_u  *end;
  
            // skip ':' and blanks
            for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p)
***************
*** 773,779 ****
  
            // Check for "endfunction", "enddef" or "}".
            // When a ":" follows it must be a dict key; "enddef: value,"
!           if ((nesting == 0 && eap->cmdidx == CMD_block)
                    ? *p == '}'
                    : (checkforcmd(&p, nesting_def[nesting]
                                                ? "enddef" : "endfunction", 4)
--- 776,782 ----
  
            // Check for "endfunction", "enddef" or "}".
            // When a ":" follows it must be a dict key; "enddef: value,"
!           if (nesting_inline[nesting]
                    ? *p == '}'
                    : (checkforcmd(&p, nesting_def[nesting]
                                                ? "enddef" : "endfunction", 4)
***************
*** 857,862 ****
--- 860,890 ----
                    {
                        ++nesting;
                        nesting_def[nesting] = (c == 'd');
+                       nesting_inline[nesting] = FALSE;
+                       indent += 2;
+                   }
+               }
+           }
+ 
+           // Check for nested inline function.
+           end = p + STRLEN(p) - 1;
+           while (end > p && VIM_ISWHITE(*end))
+               --end;
+           if (*end == '{')
+           {
+               --end;
+               while (end > p && VIM_ISWHITE(*end))
+                   --end;
+               if (end > p - 2 && end[-1] == '=' && end[0] == '>')
+               {
+                   // found trailing "=> {", start of an inline function
+                   if (nesting == MAX_FUNC_NESTING - 1)
+                       emsg(_(e_function_nesting_too_deep));
+                   else
+                   {
+                       ++nesting;
+                       nesting_def[nesting] = TRUE;
+                       nesting_inline[nesting] = TRUE;
                        indent += 2;
                    }
                }
*** ../vim-8.2.3168/src/testdir/test_vim9_func.vim      2021-07-10 
19:41:59.916341599 +0200
--- src/testdir/test_vim9_func.vim      2021-07-15 21:41:52.030576025 +0200
***************
*** 2255,2260 ****
--- 2255,2270 ----
        assert_equal('--there', F('unused')('there')('--'))
    END
    CheckScriptSuccess(lines)
+ 
+   lines =<< trim END
+       vim9script
+       echo range(4)->mapnew((_, v) => {
+         return range(v) ->mapnew((_, s) => {
+           return string(s)
+           })
+         })
+   END
+   CheckScriptSuccess(lines)
  enddef
  
  def Shadowed(): list<number>
*** ../vim-8.2.3168/src/testdir/test_vim9_expr.vim      2021-07-15 
15:40:54.738804508 +0200
--- src/testdir/test_vim9_expr.vim      2021-07-15 22:01:39.996138475 +0200
***************
*** 2082,2088 ****
        var Func = (nr: number): int => {
                return nr
    END
!   CheckDefAndScriptFailure(lines, 'E1171', 1)  # line nr is function start
  
    lines =<< trim END
        var Func = (nr: number): int => {
--- 2082,2089 ----
        var Func = (nr: number): int => {
                return nr
    END
!   CheckDefFailure(lines, 'E1171', 0)  # line nr is function start
!   CheckScriptFailure(['vim9script'] + lines, 'E1171', 2)
  
    lines =<< trim END
        var Func = (nr: number): int => {
*** ../vim-8.2.3168/src/version.c       2021-07-15 19:23:14.313392491 +0200
--- src/version.c       2021-07-15 20:40:40.862940253 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3169,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
155. You forget to eat because you're too busy surfing the net.

 /// 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/202107152004.16FK4V651982915%40masaka.moolenaar.net.

Raspunde prin e-mail lui