summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-07-15 22:03:50 +0200
committerBram Moolenaar <Bram@vim.org>2021-07-15 22:03:50 +0200
commit5245beb37cb52991a745644c20d7ca1b0138ef2c (patch)
tree4156f638b3e12e39f87fc4c86f9df921212ba5e4
parent378697ac58b8f9705286e36d1805a052e96fb86e (diff)
patch 8.2.3169: Vim9: cannot handle nested inline functionv8.2.3169
Problem: Vim9: cannot handle nested inline function. Solution: Check for nested inline function. (closes #8575)
-rw-r--r--src/testdir/test_vim9_expr.vim3
-rw-r--r--src/testdir/test_vim9_func.vim10
-rw-r--r--src/userfunc.c38
-rw-r--r--src/version.c2
4 files changed, 47 insertions, 6 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index ae48a89604..cd6ffa4463 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -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 => {
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 08e68d147c..c89c13e2dc 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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>
diff --git a/src/userfunc.c b/src/userfunc.c
index 4234681cd7..e21f15c142 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -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;
}
}
diff --git a/src/version.c b/src/version.c
index b8c782eef2..f436e54904 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3169,
+/**/
3168,
/**/
3167,