Patch 8.2.2264
Problem:    Vim9: no error for mismatched :endfunc or :enddef.
Solution:   Check for the mismatch. (issue #7582)
Files:      src/errors.h, src/userfunc.c, src/testdir/test_vim9_func.vim


*** ../vim-8.2.2263/src/errors.h        2020-12-28 18:25:56.800886000 +0100
--- src/errors.h        2021-01-01 18:26:09.223465396 +0100
***************
*** 335,337 ****
--- 335,341 ----
        INIT(= N_("E1149: Script variable is invalid after reload in function 
%s"));
  EXTERN char e_script_variable_type_changed[]
        INIT(= N_("E1150: Script variable type changed"));
+ EXTERN char e_mismatched_endfunction[]
+       INIT(= N_("E1151: Mismatched endfunction"));
+ EXTERN char e_mismatched_enddef[]
+       INIT(= N_("E1152: Mismatched enddef"));
*** ../vim-8.2.2263/src/userfunc.c      2020-12-31 18:28:13.706927452 +0100
--- src/userfunc.c      2021-01-01 18:39:28.940843840 +0100
***************
*** 3404,3438 ****
  
            // Check for "endfunction" or "enddef".
            if (checkforcmd(&p, nesting_def[nesting]
!                            ? "enddef" : "endfunction", 4) && nesting-- == 0)
            {
!               char_u *nextcmd = NULL;
! 
!               if (*p == '|')
!                   nextcmd = p + 1;
!               else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
!                   nextcmd = line_arg;
!               else if (*p != NUL && *p != '"' && p_verbose > 0)
!                   give_warning2(eap->cmdidx == CMD_def
!                       ? (char_u *)_("W1001: Text found after :enddef: %s")
!                       : (char_u *)_("W22: Text found after :endfunction: %s"),
!                        p, TRUE);
!               if (nextcmd != NULL)
                {
!                   // Another command follows. If the line came from "eap" we
!                   // can simply point into it, otherwise we need to change
!                   // "eap->cmdlinep".
!                   eap->nextcmd = nextcmd;
!                   if (line_to_free != NULL)
                    {
!                       vim_free(*eap->cmdlinep);
!                       *eap->cmdlinep = line_to_free;
!                       line_to_free = NULL;
                    }
                }
-               break;
            }
  
            // Increase indent inside "if", "while", "for" and "try", decrease
            // at "end".
            if (indent > 2 && (*p == '}' || STRNCMP(p, "end", 3) == 0))
--- 3404,3454 ----
  
            // Check for "endfunction" or "enddef".
            if (checkforcmd(&p, nesting_def[nesting]
!                                               ? "enddef" : "endfunction", 4))
            {
!               if (nesting-- == 0)
                {
!                   char_u *nextcmd = NULL;
! 
!                   if (*p == '|')
!                       nextcmd = p + 1;
!                   else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
!                       nextcmd = line_arg;
!                   else if (*p != NUL && *p != '"' && p_verbose > 0)
!                       give_warning2(eap->cmdidx == CMD_def
!                           ? (char_u *)_("W1001: Text found after :enddef: %s")
!                           : (char_u *)_("W22: Text found after :endfunction: 
%s"),
!                            p, TRUE);
!                   if (nextcmd != NULL)
                    {
!                       // Another command follows. If the line came from "eap"
!                       // we can simply point into it, otherwise we need to
!                       // change "eap->cmdlinep".
!                       eap->nextcmd = nextcmd;
!                       if (line_to_free != NULL)
!                       {
!                           vim_free(*eap->cmdlinep);
!                           *eap->cmdlinep = line_to_free;
!                           line_to_free = NULL;
!                       }
                    }
+                   break;
                }
            }
  
+           // Check for mismatched "endfunc" or "enddef".
+           // We don't check for "def" inside "func" thus we also can't check
+           // for "enddef".
+           // We continue to find the end of the function, although we might
+           // not find it.
+           else if (nesting_def[nesting])
+           {
+               if (checkforcmd(&p, "endfunction", 4))
+                   emsg(_(e_mismatched_endfunction));
+           }
+           else if (eap->cmdidx == CMD_def && checkforcmd(&p, "enddef", 4))
+               emsg(_(e_mismatched_enddef));
+ 
            // Increase indent inside "if", "while", "for" and "try", decrease
            // at "end".
            if (indent > 2 && (*p == '}' || STRNCMP(p, "end", 3) == 0))
*** ../vim-8.2.2263/src/testdir/test_vim9_func.vim      2020-12-31 
21:28:43.423217932 +0100
--- src/testdir/test_vim9_func.vim      2021-01-01 18:41:26.040698939 +0100
***************
*** 79,84 ****
--- 79,103 ----
    set maxfuncdepth&
  enddef
  
+ def Test_endfunc_enddef()
+   var lines =<< trim END
+     def Test()
+       echo 'test'
+       endfunc
+     enddef
+   END
+   CheckScriptFailure(lines, 'E1151:', 3)
+ 
+   lines =<< trim END
+     def Test()
+       func Nested()
+         echo 'test'
+       enddef
+     enddef
+   END
+   CheckScriptFailure(lines, 'E1152:', 4)
+ enddef
+ 
  def ReturnString(): string
    return 'string'
  enddef
*** ../vim-8.2.2263/src/version.c       2021-01-01 16:10:42.474679574 +0100
--- src/version.c       2021-01-01 18:27:09.515270162 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2264,
  /**/

-- 
If bankers can count, how come they have eight windows and
only four tellers?

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202101011744.101Hie5J1588169%40masaka.moolenaar.net.

Raspunde prin e-mail lui