To: vim_dev@googlegroups.com Subject: Patch 8.2.3169 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3169 Problem: Vim9: cannot handle nested inline function. Solution: Check for nested inline function. (closes #8575) Files: src/userfunc.c, src/testdir/test_vim9_func.vim, src/testdir/test_vim9_expr.vim *** ../vim-8.2.3168/src/userfunc.c 2021-07-08 21:38:45.339232318 +0200 --- src/userfunc.c 2021-07-15 21:50:54.937285120 +0200 *************** *** 634,639 **** --- 634,640 ---- || 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,664 **** ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL; } ! nesting_def[nesting] = vim9_function; getline_options = vim9_function ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT; for (;;) --- 659,666 ---- ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL; } ! nesting_def[0] = vim9_function; ! nesting_inline[0] = eap->cmdidx == CMD_block; getline_options = vim9_function ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT; for (;;) *************** *** 705,714 **** SOURCING_LNUM = sourcing_lnum_top; if (skip_until != NULL) semsg(_(e_missing_heredoc_end_marker_str), skip_until); 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; --- 707,716 ---- 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 emsg(_("E126: Missing :endfunction")); goto theend; *************** *** 765,771 **** } else { ! int c; // skip ':' and blanks for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p) --- 767,774 ---- } else { ! int c; ! char_u *end; // skip ':' and blanks for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p) *************** *** 773,779 **** // Check for "endfunction", "enddef" or "}". // When a ":" follows it must be a dict key; "enddef: value," ! if ((nesting == 0 && eap->cmdidx == CMD_block) ? *p == '}' : (checkforcmd(&p, nesting_def[nesting] ? "enddef" : "endfunction", 4) --- 776,782 ---- // Check for "endfunction", "enddef" or "}". // When a ":" follows it must be a dict key; "enddef: value," ! if (nesting_inline[nesting] ? *p == '}' : (checkforcmd(&p, nesting_def[nesting] ? "enddef" : "endfunction", 4) *************** *** 857,862 **** --- 860,890 ---- { ++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; } } *** ../vim-8.2.3168/src/testdir/test_vim9_func.vim 2021-07-10 19:41:59.916341599 +0200 --- src/testdir/test_vim9_func.vim 2021-07-15 21:41:52.030576025 +0200 *************** *** 2255,2260 **** --- 2255,2270 ---- 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 *** ../vim-8.2.3168/src/testdir/test_vim9_expr.vim 2021-07-15 15:40:54.738804508 +0200 --- src/testdir/test_vim9_expr.vim 2021-07-15 22:01:39.996138475 +0200 *************** *** 2082,2088 **** var Func = (nr: number): int => { return nr END ! CheckDefAndScriptFailure(lines, 'E1171', 1) # line nr is function start lines =<< trim END var Func = (nr: number): int => { --- 2082,2089 ---- var Func = (nr: number): int => { return nr END ! CheckDefFailure(lines, 'E1171', 0) # line nr is function start ! CheckScriptFailure(['vim9script'] + lines, 'E1171', 2) lines =<< trim END var Func = (nr: number): int => { *** ../vim-8.2.3168/src/version.c 2021-07-15 19:23:14.313392491 +0200 --- src/version.c 2021-07-15 20:40:40.862940253 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3169, /**/ -- hundred-and-one symptoms of being an internet addict: 155. You forget to eat because you're too busy surfing the net. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///