summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-28 17:55:26 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-28 17:55:26 +0000
commit7473a84cf935f64ddd4ea7fe7eee0f9c51c50b60 (patch)
tree19fbc65c6b7484971559c5be81745a780cf1143a
parent4bf1006cae7e87259ccd5219128c3dba75774441 (diff)
patch 8.2.3924: Vim9: no error if something follows :enddefv8.2.3924
Problem: Vim9: no error if something follows :enddef in a nested function. Solution: Give an error. Move common code to a function.
-rw-r--r--src/errors.h4
-rw-r--r--src/testdir/test_vim9_func.vim15
-rw-r--r--src/userfunc.c49
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c8
5 files changed, 56 insertions, 22 deletions
diff --git a/src/errors.h b/src/errors.h
index 5ca74cc1d0..692574b1d0 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -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[]
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 88c0af8e0d..7a5f0f1a40 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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()
diff --git a/src/userfunc.c b/src/userfunc.c
index a7cbac3c86..b87cdedb68 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -166,6 +166,35 @@ one_function_arg(
}
/*
+ * 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.
* "argp" is advanced just after "endchar".
@@ -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"),
diff --git a/src/version.c b/src/version.c
index 5d22d98e8d..90bd422941 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3924,
+/**/
3923,
/**/
3922,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index b23145ebcd..8882bfe107 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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)