comparison src/userfunc.c @ 25265:1d6ff96306fc v8.2.3169

patch 8.2.3169: Vim9: cannot handle nested inline function Commit: https://github.com/vim/vim/commit/5245beb37cb52991a745644c20d7ca1b0138ef2c Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jul 15 22:03:50 2021 +0200 patch 8.2.3169: Vim9: cannot handle nested inline function Problem: Vim9: cannot handle nested inline function. Solution: Check for nested inline function. (closes https://github.com/vim/vim/issues/8575)
author Bram Moolenaar <Bram@vim.org>
date Thu, 15 Jul 2021 22:15:03 +0200
parents 0a3b1c66d3f2
children c69ebc71bd85
comparison
equal deleted inserted replaced
25264:19bc0f4c9379 25265:1d6ff96306fc
632 char_u *line_arg = line_arg_in; 632 char_u *line_arg = line_arg_in;
633 int vim9_function = eap->cmdidx == CMD_def 633 int vim9_function = eap->cmdidx == CMD_def
634 || eap->cmdidx == CMD_block; 634 || eap->cmdidx == CMD_block;
635 #define MAX_FUNC_NESTING 50 635 #define MAX_FUNC_NESTING 50
636 char nesting_def[MAX_FUNC_NESTING]; 636 char nesting_def[MAX_FUNC_NESTING];
637 char nesting_inline[MAX_FUNC_NESTING];
637 int nesting = 0; 638 int nesting = 0;
638 getline_opt_T getline_options; 639 getline_opt_T getline_options;
639 int indent = 2; 640 int indent = 2;
640 char_u *skip_until = NULL; 641 char_u *skip_until = NULL;
641 int ret = FAIL; 642 int ret = FAIL;
656 goto theend; 657 goto theend;
657 while (sourcing_lnum_off-- > 0) 658 while (sourcing_lnum_off-- > 0)
658 ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL; 659 ((char_u **)(newlines->ga_data))[newlines->ga_len++] = NULL;
659 } 660 }
660 661
661 nesting_def[nesting] = vim9_function; 662 nesting_def[0] = vim9_function;
663 nesting_inline[0] = eap->cmdidx == CMD_block;
662 getline_options = vim9_function 664 getline_options = vim9_function
663 ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT; 665 ? GETLINE_CONCAT_CONTBAR : GETLINE_CONCAT_CONT;
664 for (;;) 666 for (;;)
665 { 667 {
666 char_u *theline; 668 char_u *theline;
703 { 705 {
704 // Use the start of the function for the line number. 706 // Use the start of the function for the line number.
705 SOURCING_LNUM = sourcing_lnum_top; 707 SOURCING_LNUM = sourcing_lnum_top;
706 if (skip_until != NULL) 708 if (skip_until != NULL)
707 semsg(_(e_missing_heredoc_end_marker_str), skip_until); 709 semsg(_(e_missing_heredoc_end_marker_str), skip_until);
710 else if (nesting_inline[nesting])
711 emsg(_(e_missing_end_block));
708 else if (eap->cmdidx == CMD_def) 712 else if (eap->cmdidx == CMD_def)
709 emsg(_(e_missing_enddef)); 713 emsg(_(e_missing_enddef));
710 else if (eap->cmdidx == CMD_block)
711 emsg(_(e_missing_end_block));
712 else 714 else
713 emsg(_("E126: Missing :endfunction")); 715 emsg(_("E126: Missing :endfunction"));
714 goto theend; 716 goto theend;
715 } 717 }
716 718
763 } 765 }
764 } 766 }
765 } 767 }
766 else 768 else
767 { 769 {
768 int c; 770 int c;
771 char_u *end;
769 772
770 // skip ':' and blanks 773 // skip ':' and blanks
771 for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p) 774 for (p = theline; VIM_ISWHITE(*p) || *p == ':'; ++p)
772 ; 775 ;
773 776
774 // Check for "endfunction", "enddef" or "}". 777 // Check for "endfunction", "enddef" or "}".
775 // When a ":" follows it must be a dict key; "enddef: value," 778 // When a ":" follows it must be a dict key; "enddef: value,"
776 if ((nesting == 0 && eap->cmdidx == CMD_block) 779 if (nesting_inline[nesting]
777 ? *p == '}' 780 ? *p == '}'
778 : (checkforcmd(&p, nesting_def[nesting] 781 : (checkforcmd(&p, nesting_def[nesting]
779 ? "enddef" : "endfunction", 4) 782 ? "enddef" : "endfunction", 4)
780 && *p != ':')) 783 && *p != ':'))
781 { 784 {
855 emsg(_(e_function_nesting_too_deep)); 858 emsg(_(e_function_nesting_too_deep));
856 else 859 else
857 { 860 {
858 ++nesting; 861 ++nesting;
859 nesting_def[nesting] = (c == 'd'); 862 nesting_def[nesting] = (c == 'd');
863 nesting_inline[nesting] = FALSE;
864 indent += 2;
865 }
866 }
867 }
868
869 // Check for nested inline function.
870 end = p + STRLEN(p) - 1;
871 while (end > p && VIM_ISWHITE(*end))
872 --end;
873 if (*end == '{')
874 {
875 --end;
876 while (end > p && VIM_ISWHITE(*end))
877 --end;
878 if (end > p - 2 && end[-1] == '=' && end[0] == '>')
879 {
880 // found trailing "=> {", start of an inline function
881 if (nesting == MAX_FUNC_NESTING - 1)
882 emsg(_(e_function_nesting_too_deep));
883 else
884 {
885 ++nesting;
886 nesting_def[nesting] = TRUE;
887 nesting_inline[nesting] = TRUE;
860 indent += 2; 888 indent += 2;
861 } 889 }
862 } 890 }
863 } 891 }
864 892