]> granicus.if.org Git - vim/commitdiff
patch 8.2.3924: Vim9: no error if something follows :enddef v8.2.3924
authorBram Moolenaar <Bram@vim.org>
Tue, 28 Dec 2021 17:55:26 +0000 (17:55 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 28 Dec 2021 17:55:26 +0000 (17:55 +0000)
Problem:    Vim9: no error if something follows :enddef in a nested function.
Solution:   Give an error.  Move common code to a function.

src/errors.h
src/testdir/test_vim9_func.vim
src/userfunc.c
src/version.c
src/vim9compile.c

index 5ca74cc1d09225ec3158a5464f023860d96919f7..692574b1d0ca43b8fe12553bd1f1b18b96394040 100644 (file)
@@ -717,8 +717,8 @@ EXTERN char e_missing_end_block[]
        INIT(= N_("E1171: Missing } after inline function"));
 EXTERN char e_cannot_use_default_values_in_lambda[]
        INIT(= N_("E1172: Cannot use default values in a lambda"));
-EXTERN char e_text_found_after_enddef_str[]
-       INIT(= N_("E1173: Text found after enddef: %s"));
+EXTERN char e_text_found_after_str_str[]
+       INIT(= N_("E1173: Text found after %s: %s"));
 EXTERN char e_string_required_for_argument_nr[]
        INIT(= N_("E1174: String required for argument %d"));
 EXTERN char e_non_empty_string_required_for_argument_nr[]
index 88c0af8e0da5a8dfd74bfb2c2138b86e67bb7dbf..7a5f0f1a4012da267db4abd07a43d7f4c42672a1 100644 (file)
@@ -1686,7 +1686,7 @@ def Test_nested_function_with_nextcmd()
       # Compile all functions
       defcompile
   END
-  CheckScriptFailure(lines, 'E476: Invalid command: AAAAA')
+  CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
 enddef
 
 def Test_nested_function_with_args_split()
@@ -1703,8 +1703,17 @@ def Test_nested_function_with_args_split()
       # Compile all functions
       defcompile
   END
-  # FIXME: this should fail on the BBBB
-  CheckScriptSuccess(lines)
+  CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
+
+  lines =<< trim END
+      vim9script
+      def FirstFunction()
+        func SecondFunction()
+        endfunc|BBBB
+      enddef
+      defcompile
+  END
+  CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
 enddef
 
 def Test_return_type_wrong()
index a7cbac3c8675b335f8e8387fe94cd41b304655cf..b87cdedb68ce87cb3e0421b7cec1566e9ad5406d 100644 (file)
@@ -165,6 +165,35 @@ one_function_arg(
     return p;
 }
 
+/*
+ * Handle line continuation in function arguments or body.
+ * Get a next line, store it in "eap" if appropriate and use "line_to_free" to
+ * handle freeing the line later.
+ */
+    static char_u *
+get_function_line(
+       exarg_T         *eap,
+       char_u          **line_to_free,
+       getline_opt_T   getline_options,
+       int             indent)
+{
+    char_u *theline;
+
+    if (eap->getline == NULL)
+       theline = getcmdline(':', 0L, indent, getline_options);
+    else
+       theline = eap->getline(':', eap->cookie, indent, getline_options);
+    if (theline != NULL)
+    {
+       if (*eap->cmdlinep == *line_to_free)
+           *eap->cmdlinep = theline;
+       vim_free(*line_to_free);
+       *line_to_free = theline;
+    }
+
+    return theline;
+}
+
 /*
  * Get function arguments.
  * "argp" should point to just after the "(", possibly to white space.
@@ -212,16 +241,11 @@ get_function_args(
        while (eap != NULL && eap->getline != NULL
                         && (*p == NUL || (VIM_ISWHITE(*whitep) && *p == '#')))
        {
-           char_u *theline;
-
            // End of the line, get the next one.
-           theline = eap->getline(':', eap->cookie, 0, TRUE);
+           char_u *theline = get_function_line(eap, line_to_free, 0, TRUE);
+
            if (theline == NULL)
                break;
-           vim_free(*line_to_free);
-           if (*eap->cmdlinep == *line_to_free)
-               *eap->cmdlinep = theline;
-           *line_to_free = theline;
            whitep = (char_u *)" ";
            p = skipwhite(theline);
        }
@@ -720,15 +744,8 @@ get_function_body(
        }
        else
        {
-           if (eap->getline == NULL)
-               theline = getcmdline(':', 0L, indent, getline_options);
-           else
-               theline = eap->getline(':', eap->cookie, indent,
+           theline = get_function_line(eap, line_to_free, indent,
                                                              getline_options);
-           if (*eap->cmdlinep == *line_to_free)
-               *eap->cmdlinep = theline;
-           vim_free(*line_to_free);
-           *line_to_free = theline;
        }
        if (KeyTyped)
            lines_left = Rows - 1;
@@ -827,7 +844,7 @@ get_function_body(
                        SOURCING_LNUM = sourcing_lnum_top
                                                        + newlines->ga_len + 1;
                        if (eap->cmdidx == CMD_def)
-                           semsg(_(e_text_found_after_enddef_str), p);
+                           semsg(_(e_text_found_after_str_str), "enddef", p);
                        else
                            give_warning2((char_u *)
                                   _("W22: Text found after :endfunction: %s"),
index 5d22d98e8dadf58cafacc6aeaae106962925bd17..90bd4229419892a9228ba3b4ac6b0a6ad27d9fac 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3924,
 /**/
     3923,
 /**/
index b23145ebcdffb1041561658d31bdfa0d506260ae..8882bfe107b8d9471510134521e6f6e1b299221f 100644 (file)
@@ -879,12 +879,18 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, char_u **line_to_free)
     }
 
     ufunc = define_function(eap, lambda_name, line_to_free);
-
     if (ufunc == NULL)
     {
        r = eap->skip ? OK : FAIL;
        goto theend;
     }
+    if (eap->nextcmd != NULL)
+    {
+       semsg(_(e_text_found_after_str_str),
+             eap->cmdidx == CMD_def ? "enddef" : "endfunction", eap->nextcmd);
+       r = FAIL;
+       goto theend;
+    }
 
     // copy over the block scope IDs before compiling
     if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0)