Patch 8.2.4989
Problem:    Cannot specify a function name for :defcompile.
Solution:   Implement a function name argument for :defcompile.
Files:      runtime/doc/vim9.txt, src/userfunc.c, src/proto/userfunc.pro,
            src/vim9execute.c, src/ex_cmds.h, src/testdir/test_vim9_cmd.vim,
            src/testdir/test_vim9_disassemble.vim


*** ../vim-8.2.4988/runtime/doc/vim9.txt        2022-04-14 12:58:19.604895030 
+0100
--- runtime/doc/vim9.txt        2022-05-21 15:19:15.069829376 +0100
***************
*** 1167,1177 ****
                                                *:defc* *:defcompile*
  :defc[ompile]         Compile functions defined in the current script that
                        were not compiled yet.
!                       This will report errors found during the compilation.
  
                                                *:disa* *:disassemble*
  :disa[ssemble] {func} Show the instructions generated for {func}.
!                       This is for debugging and testing.
                        Note that for command line completion of {func} you
                        can prepend "s:" to find script-local functions.
  
--- 1210,1227 ----
                                                *:defc* *:defcompile*
  :defc[ompile]         Compile functions defined in the current script that
                        were not compiled yet.
!                       This will report any errors found during compilation.
! 
! :defc[ompile] {func}
! :defc[ompile] debug {func}
! :defc[ompile] profile {func}
!                       Compile function {func}, if needed.  Use "debug" and
!                       "profile" to specify the compilation mode.
!                       This will report any errors found during compilation.
  
                                                *:disa* *:disassemble*
  :disa[ssemble] {func} Show the instructions generated for {func}.
!                       This is for debugging and testing. *E1061*
                        Note that for command line completion of {func} you
                        can prepend "s:" to find script-local functions.
  
*** ../vim-8.2.4988/src/userfunc.c      2022-05-13 13:50:32.815012765 +0100
--- src/userfunc.c      2022-05-21 15:07:41.701381219 +0100
***************
*** 4997,5032 ****
  }
  
  /*
   * :defcompile - compile all :def functions in the current script that need to
!  * be compiled.  Except dead functions.  Doesn't do profiling.
   */
      void
! ex_defcompile(exarg_T *eap UNUSED)
  {
-     long      todo = (long)func_hashtab.ht_used;
-     int               changed = func_hashtab.ht_changed;
-     hashitem_T        *hi;
      ufunc_T   *ufunc;
  
!     for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
      {
!       if (!HASHITEM_EMPTY(hi))
        {
!           --todo;
!           ufunc = HI2UF(hi);
!           if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
!                   && ufunc->uf_def_status == UF_TO_BE_COMPILED
!                   && (ufunc->uf_flags & FC_DEAD) == 0)
!           {
!               (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL);
  
!               if (func_hashtab.ht_changed != changed)
                {
!                   // a function has been added or removed, need to start over
!                   todo = (long)func_hashtab.ht_used;
!                   changed = func_hashtab.ht_changed;
!                   hi = func_hashtab.ht_array;
!                   --hi;
                }
            }
        }
--- 4997,5111 ----
  }
  
  /*
+  * Find a function by name, including "<lambda>123".
+  * Check for "profile" and "debug" arguments and set"compile_type".
+  * Return NULL if not found.
+  */
+     ufunc_T *
+ find_func_by_name(char_u *name, compiletype_T *compile_type)
+ {
+     char_u    *arg = name;
+     char_u    *fname;
+     ufunc_T   *ufunc;
+     int               is_global = FALSE;
+ 
+     *compile_type = CT_NONE;
+     if (STRNCMP(arg, "profile", 7) == 0 && VIM_ISWHITE(arg[7]))
+     {
+       *compile_type = CT_PROFILE;
+       arg = skipwhite(arg + 7);
+     }
+     else if (STRNCMP(arg, "debug", 5) == 0 && VIM_ISWHITE(arg[5]))
+     {
+       *compile_type = CT_DEBUG;
+       arg = skipwhite(arg + 5);
+     }
+ 
+     if (STRNCMP(arg, "<lambda>", 8) == 0)
+     {
+       arg += 8;
+       (void)getdigits(&arg);
+       fname = vim_strnsave(name, arg - name);
+     }
+     else
+       fname = trans_function_name(&arg, &is_global, FALSE,
+                     TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD, NULL, NULL, NULL);
+     if (fname == NULL)
+     {
+       semsg(_(e_invalid_argument_str), name);
+       return NULL;
+     }
+     if (!ends_excmd2(name, arg))
+     {
+       emsg(ex_errmsg(e_trailing_characters_str, arg));
+       return NULL;
+     }
+ 
+     ufunc = find_func(fname, is_global);
+     if (ufunc == NULL)
+     {
+       char_u *p = untrans_function_name(fname);
+ 
+       if (p != NULL)
+           // Try again without making it script-local.
+           ufunc = find_func(p, FALSE);
+     }
+     vim_free(fname);
+     if (ufunc == NULL)
+       semsg(_(e_cannot_find_function_str), name);
+     return ufunc;
+ }
+ 
+ /*
   * :defcompile - compile all :def functions in the current script that need to
!  * be compiled or the one specified by the argument.
!  * Skips dead functions.  Doesn't do profiling.
   */
      void
! ex_defcompile(exarg_T *eap)
  {
      ufunc_T   *ufunc;
  
!     if (*eap->arg != NUL)
      {
!       compiletype_T compile_type;
! 
!       ufunc = find_func_by_name(eap->arg, &compile_type);
!       if (ufunc != NULL)
        {
!           if (func_needs_compiling(ufunc, compile_type))
!               (void)compile_def_function(ufunc, FALSE, compile_type, NULL);
!           else
!               smsg(_("Function %s does not need compiling"), eap->arg);
!       }
!     }
!     else
!     {
!       long    todo = (long)func_hashtab.ht_used;
!       int             changed = func_hashtab.ht_changed;
!       hashitem_T      *hi;
  
!       for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
!       {
!           if (!HASHITEM_EMPTY(hi))
!           {
!               --todo;
!               ufunc = HI2UF(hi);
!               if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
!                       && ufunc->uf_def_status == UF_TO_BE_COMPILED
!                       && (ufunc->uf_flags & FC_DEAD) == 0)
                {
!                   (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL);
! 
!                   if (func_hashtab.ht_changed != changed)
!                   {
!                       // a function has been added or removed, need to start
!                       // over
!                       todo = (long)func_hashtab.ht_used;
!                       changed = func_hashtab.ht_changed;
!                       hi = func_hashtab.ht_array;
!                       --hi;
!                   }
                }
            }
        }
*** ../vim-8.2.4988/src/proto/userfunc.pro      2022-03-31 20:02:52.422045605 
+0100
--- src/proto/userfunc.pro      2022-05-21 14:25:55.757001488 +0100
***************
*** 45,50 ****
--- 45,51 ----
  void list_functions(regmatch_T *regmatch);
  ufunc_T *define_function(exarg_T *eap, char_u *name_arg, garray_T 
*lines_to_free);
  void ex_function(exarg_T *eap);
+ ufunc_T *find_func_by_name(char_u *name, compiletype_T *compile_type);
  void ex_defcompile(exarg_T *eap);
  int eval_fname_script(char_u *p);
  int translated_function_exists(char_u *name, int is_global);
*** ../vim-8.2.4988/src/vim9execute.c   2022-05-18 11:00:44.295519512 +0100
--- src/vim9execute.c   2022-05-21 14:24:16.605069858 +0100
***************
*** 6277,6331 ****
  ex_disassemble(exarg_T *eap)
  {
      char_u    *arg = eap->arg;
-     char_u    *fname;
      ufunc_T   *ufunc;
      dfunc_T   *dfunc;
      isn_T     *instr;
      int               instr_count;
!     int               is_global = FALSE;
!     compiletype_T compile_type = CT_NONE;
  
!     if (STRNCMP(arg, "profile", 7) == 0 && VIM_ISWHITE(arg[7]))
!     {
!       compile_type = CT_PROFILE;
!       arg = skipwhite(arg + 7);
!     }
!     else if (STRNCMP(arg, "debug", 5) == 0 && VIM_ISWHITE(arg[5]))
!     {
!       compile_type = CT_DEBUG;
!       arg = skipwhite(arg + 5);
!     }
! 
!     if (STRNCMP(arg, "<lambda>", 8) == 0)
!     {
!       arg += 8;
!       (void)getdigits(&arg);
!       fname = vim_strnsave(eap->arg, arg - eap->arg);
!     }
!     else
!       fname = trans_function_name(&arg, &is_global, FALSE,
!                     TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD, NULL, NULL, NULL);
!     if (fname == NULL)
!     {
!       semsg(_(e_invalid_argument_str), eap->arg);
!       return;
!     }
! 
!     ufunc = find_func(fname, is_global);
!     if (ufunc == NULL)
!     {
!       char_u *p = untrans_function_name(fname);
! 
!       if (p != NULL)
!           // Try again without making it script-local.
!           ufunc = find_func(p, FALSE);
!     }
!     vim_free(fname);
      if (ufunc == NULL)
-     {
-       semsg(_(e_cannot_find_function_str), eap->arg);
        return;
-     }
      if (func_needs_compiling(ufunc, compile_type)
            && compile_def_function(ufunc, FALSE, compile_type, NULL) == FAIL)
        return;
--- 6277,6291 ----
  ex_disassemble(exarg_T *eap)
  {
      char_u    *arg = eap->arg;
      ufunc_T   *ufunc;
      dfunc_T   *dfunc;
      isn_T     *instr;
      int               instr_count;
!     compiletype_T compile_type;
  
!     ufunc = find_func_by_name(arg, &compile_type);
      if (ufunc == NULL)
        return;
      if (func_needs_compiling(ufunc, compile_type)
            && compile_def_function(ufunc, FALSE, compile_type, NULL) == FAIL)
        return;
*** ../vim-8.2.4988/src/ex_cmds.h       2022-03-24 11:22:07.215294108 +0000
--- src/ex_cmds.h       2022-05-21 15:13:35.921471148 +0100
***************
*** 465,471 ****
        EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_defcompile, "defcompile",   ex_defcompile,
!       EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR,
        ADDR_NONE),
  EXCMD(CMD_delcommand, "delcommand",   ex_delcommand,
        EX_NEEDARG|EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
--- 465,471 ----
        EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
        ADDR_NONE),
  EXCMD(CMD_defcompile, "defcompile",   ex_defcompile,
!       EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_TRLBAR|EX_EXTRA,
        ADDR_NONE),
  EXCMD(CMD_delcommand, "delcommand",   ex_delcommand,
        EX_NEEDARG|EX_WORD1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
*** ../vim-8.2.4988/src/testdir/test_vim9_cmd.vim       2022-05-17 
12:45:11.789423526 +0100
--- src/testdir/test_vim9_cmd.vim       2022-05-21 15:15:44.369638126 +0100
***************
*** 83,88 ****
--- 83,98 ----
    v9.CheckScriptSuccess(lines)
  enddef
  
+ def Test_defcompile_fails()
+   assert_fails('defcompile NotExists', 'E1061:')
+   assert_fails('defcompile debug debug Test_defcompile_fails', 'E488:')
+   assert_fails('defcompile profile profile Test_defcompile_fails', 'E488:')
+ enddef
+ 
+ defcompile Test_defcompile_fails
+ defcompile debug Test_defcompile_fails
+ defcompile profile Test_defcompile_fails
+ 
  def Test_cmdmod_execute()
    # "legacy" applies not only to the "exe" argument but also to the commands
    var lines =<< trim END
*** ../vim-8.2.4988/src/testdir/test_vim9_disassemble.vim       2022-05-17 
16:12:35.712086412 +0100
--- src/testdir/test_vim9_disassemble.vim       2022-05-21 15:09:29.405340070 
+0100
***************
*** 43,48 ****
--- 43,51 ----
    assert_fails('disass [', 'E475:')
    assert_fails('disass 234', 'E129:')
    assert_fails('disass <XX>foo', 'E129:')
+   assert_fails('disass Test_disassemble_load burp', 'E488:')
+   assert_fails('disass debug debug Test_disassemble_load', 'E488:')
+   assert_fails('disass profile profile Test_disassemble_load', 'E488:')
  
    var res = execute('disass s:ScriptFuncLoad')
    assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
*** ../vim-8.2.4988/src/version.c       2022-05-21 11:20:38.102070988 +0100
--- src/version.c       2022-05-21 14:20:10.761214621 +0100
***************
*** 748,749 ****
--- 748,751 ----
  {   /* Add new patch number below this line */
+ /**/
+     4989,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
243. You unsuccessfully try to download a pizza from www.dominos.com.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20220521143932.333BE1C0473%40moolenaar.net.

Raspunde prin e-mail lui