]> granicus.if.org Git - vim/commitdiff
patch 8.2.3169: Vim9: cannot handle nested inline function v8.2.3169
authorBram Moolenaar <Bram@vim.org>
Thu, 15 Jul 2021 20:03:50 +0000 (22:03 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 15 Jul 2021 20:03:50 +0000 (22:03 +0200)
Problem:    Vim9: cannot handle nested inline function.
Solution:   Check for nested inline function. (closes #8575)

src/testdir/test_vim9_expr.vim
src/testdir/test_vim9_func.vim
src/userfunc.c
src/version.c

index ae48a89604e99b9f8fab484532f7930ddbdc1c8d..cd6ffa446363d254ef2ebe66f98296b27f845704 100644 (file)
@@ -2082,7 +2082,8 @@ def Test_expr7_lambda_block()
       var Func = (nr: number): int => {
               return nr
   END
-  CheckDefAndScriptFailure(lines, 'E1171', 1)  # line nr is function start
+  CheckDefFailure(lines, 'E1171', 0)  # line nr is function start
+  CheckScriptFailure(['vim9script'] + lines, 'E1171', 2)
 
   lines =<< trim END
       var Func = (nr: number): int => {
index 08e68d147c0a373b21be355d1f7f275ffce50c5f..c89c13e2dc8aa7dd9b7df84c9de42c4491730e79 100644 (file)
@@ -2255,6 +2255,16 @@ def Test_nested_inline_lambda()
       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>
index 4234681cd7b3947b1904110447b7ebf311422ac5..e21f15c1425373aecc54939313f9b91b28896859 100644 (file)
@@ -634,6 +634,7 @@ get_function_body(
                                                   || 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,7 +659,8 @@ get_function_body(
            ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL;
     }
 
-    nesting_def[nesting] = vim9_function;
+    nesting_def[0] = vim9_function;
+    nesting_inline[0] = eap->cmdidx == CMD_block;
     getline_options = vim9_function
                                ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT;
     for (;;)
@@ -705,10 +707,10 @@ get_function_body(
            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 if (eap->cmdidx == CMD_block)
-               emsg(_(e_missing_end_block));
            else
                emsg(_("E126: Missing :endfunction"));
            goto theend;
@@ -765,7 +767,8 @@ get_function_body(
        }
        else
        {
-           int c;
+           int     c;
+           char_u  *end;
 
            // skip ':' and blanks
            for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p)
@@ -773,7 +776,7 @@ get_function_body(
 
            // Check for "endfunction", "enddef" or "}".
            // When a ":" follows it must be a dict key; "enddef: value,"
-           if ((nesting == 0 && eap->cmdidx == CMD_block)
+           if (nesting_inline[nesting]
                    ? *p == '}'
                    : (checkforcmd(&p, nesting_def[nesting]
                                                ? "enddef" : "endfunction", 4)
@@ -857,6 +860,31 @@ get_function_body(
                    {
                        ++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;
                    }
                }
index b8c782eef29739f0da7a07e2ec139405f54ccde5..f436e549048e09a8e5a78534a3c23862b5dc7ba2 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3169,
 /**/
     3168,
 /**/