0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.3924: Vim9: no error if something follows :enddef

Problem:    Vim9: no error if something follows :enddef in a nested function.
Solution:   Give an error.  Move common code to a function.
This commit is contained in:
Bram Moolenaar
2021-12-28 17:55:26 +00:00
parent 4bf1006cae
commit 7473a84cf9
5 changed files with 56 additions and 22 deletions

View File

@@ -717,8 +717,8 @@ EXTERN char e_missing_end_block[]
INIT(= N_("E1171: Missing } after inline function")); INIT(= N_("E1171: Missing } after inline function"));
EXTERN char e_cannot_use_default_values_in_lambda[] EXTERN char e_cannot_use_default_values_in_lambda[]
INIT(= N_("E1172: Cannot use default values in a lambda")); INIT(= N_("E1172: Cannot use default values in a lambda"));
EXTERN char e_text_found_after_enddef_str[] EXTERN char e_text_found_after_str_str[]
INIT(= N_("E1173: Text found after enddef: %s")); INIT(= N_("E1173: Text found after %s: %s"));
EXTERN char e_string_required_for_argument_nr[] EXTERN char e_string_required_for_argument_nr[]
INIT(= N_("E1174: String required for argument %d")); INIT(= N_("E1174: String required for argument %d"));
EXTERN char e_non_empty_string_required_for_argument_nr[] EXTERN char e_non_empty_string_required_for_argument_nr[]

View File

@@ -1686,7 +1686,7 @@ def Test_nested_function_with_nextcmd()
# Compile all functions # Compile all functions
defcompile defcompile
END END
CheckScriptFailure(lines, 'E476: Invalid command: AAAAA') CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
enddef enddef
def Test_nested_function_with_args_split() def Test_nested_function_with_args_split()
@@ -1703,8 +1703,17 @@ def Test_nested_function_with_args_split()
# Compile all functions # Compile all functions
defcompile defcompile
END END
# FIXME: this should fail on the BBBB CheckScriptFailure(lines, 'E1173: Text found after enddef: BBBB')
CheckScriptSuccess(lines)
lines =<< trim END
vim9script
def FirstFunction()
func SecondFunction()
endfunc|BBBB
enddef
defcompile
END
CheckScriptFailure(lines, 'E1173: Text found after endfunction: BBBB')
enddef enddef
def Test_return_type_wrong() def Test_return_type_wrong()

View File

@@ -165,6 +165,35 @@ one_function_arg(
return p; 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. * Get function arguments.
* "argp" should point to just after the "(", possibly to white space. * "argp" should point to just after the "(", possibly to white space.
@@ -212,16 +241,11 @@ get_function_args(
while (eap != NULL && eap->getline != NULL while (eap != NULL && eap->getline != NULL
&& (*p == NUL || (VIM_ISWHITE(*whitep) && *p == '#'))) && (*p == NUL || (VIM_ISWHITE(*whitep) && *p == '#')))
{ {
char_u *theline;
// End of the line, get the next one. // 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) if (theline == NULL)
break; break;
vim_free(*line_to_free);
if (*eap->cmdlinep == *line_to_free)
*eap->cmdlinep = theline;
*line_to_free = theline;
whitep = (char_u *)" "; whitep = (char_u *)" ";
p = skipwhite(theline); p = skipwhite(theline);
} }
@@ -720,15 +744,8 @@ get_function_body(
} }
else else
{ {
if (eap->getline == NULL) theline = get_function_line(eap, line_to_free, indent,
theline = getcmdline(':', 0L, indent, getline_options);
else
theline = eap->getline(':', eap->cookie, indent,
getline_options); getline_options);
if (*eap->cmdlinep == *line_to_free)
*eap->cmdlinep = theline;
vim_free(*line_to_free);
*line_to_free = theline;
} }
if (KeyTyped) if (KeyTyped)
lines_left = Rows - 1; lines_left = Rows - 1;
@@ -827,7 +844,7 @@ get_function_body(
SOURCING_LNUM = sourcing_lnum_top SOURCING_LNUM = sourcing_lnum_top
+ newlines->ga_len + 1; + newlines->ga_len + 1;
if (eap->cmdidx == CMD_def) if (eap->cmdidx == CMD_def)
semsg(_(e_text_found_after_enddef_str), p); semsg(_(e_text_found_after_str_str), "enddef", p);
else else
give_warning2((char_u *) give_warning2((char_u *)
_("W22: Text found after :endfunction: %s"), _("W22: Text found after :endfunction: %s"),

View File

@@ -749,6 +749,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3924,
/**/ /**/
3923, 3923,
/**/ /**/

View 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); ufunc = define_function(eap, lambda_name, line_to_free);
if (ufunc == NULL) if (ufunc == NULL)
{ {
r = eap->skip ? OK : FAIL; r = eap->skip ? OK : FAIL;
goto theend; 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 // copy over the block scope IDs before compiling
if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0) if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0)