Patch 8.2.4429
Problem:    Using script-local function from the wrong script when using a
            partial. (Yegappan Lakshmanan)
Solution:   Include the script ID in the partial name.
Files:      src/userfunc.c, src/proto/userfunc.pro, src/evalfunc.c,
            src/vim9type.c, src/testdir/test_vim9_import.vim


*** ../vim-8.2.4428/src/userfunc.c      2022-02-18 18:34:41.280976317 +0000
--- src/userfunc.c      2022-02-21 12:53:12.930220824 +0000
***************
*** 1958,1974 ****
  
      if ((flags & FFED_IS_GLOBAL) == 0)
      {
!       int     find_script_local = in_vim9script() && eval_isnamec1(*name)
!                                          && (name[1] != ':' || *name == 's');
! 
!       if (find_script_local)
        {
-           // Find script-local function before global one.
            func = find_func_with_sid(name[0] == 's' && name[1] == ':'
                                       ? name + 2 : name, current_sctx.sc_sid);
            if (func != NULL)
                return func;
        }
      }
  
      if ((flags & FFED_NO_GLOBAL) == 0)
--- 1958,1986 ----
  
      if ((flags & FFED_IS_GLOBAL) == 0)
      {
!       // Find script-local function before global one.
!       if (in_vim9script() && eval_isnamec1(*name)
!                                          && (name[1] != ':' || *name == 's'))
        {
            func = find_func_with_sid(name[0] == 's' && name[1] == ':'
                                       ? name + 2 : name, current_sctx.sc_sid);
            if (func != NULL)
                return func;
        }
+       if (in_vim9script() && STRNCMP(name, "<SNR>", 5) == 0)
+       {
+           char_u  *p = name + 5;
+           long    sid;
+ 
+           // printable "<SNR>123_Name" form
+           sid = getdigits(&p);
+           if (*p == '_')
+           {
+               func = find_func_with_sid(p + 1, (int)sid);
+               if (func != NULL)
+                   return func;
+           }
+       }
      }
  
      if ((flags & FFED_NO_GLOBAL) == 0)
***************
*** 4068,4073 ****
--- 4080,4102 ----
  }
  
  /*
+  * Return script-local "fname" with the 3-byte sequence replaced by
+  * printable <SNR> in allocated memory.
+  */
+     char_u *
+ alloc_printable_func_name(char_u *fname)
+ {
+     char_u *n = alloc(STRLEN(fname + 3) + 6);
+ 
+     if (n != NULL)
+     {
+       STRCPY(n, "<SNR>");
+       STRCPY(n + 5, fname + 3);
+     }
+     return n;
+ }
+ 
+ /*
   * Call trans_function_name(), except that a lambda is returned as-is.
   * Returns the name in allocated memory.
   */
*** ../vim-8.2.4428/src/proto/userfunc.pro      2022-02-12 19:52:22.024702251 
+0000
--- src/proto/userfunc.pro      2022-02-21 12:17:19.437118360 +0000
***************
*** 38,43 ****
--- 38,44 ----
  char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, 
funcdict_T *fdp, partial_T **partial, type_T **type);
  char_u *untrans_function_name(char_u *name);
  char_u *get_scriptlocal_funcname(char_u *funcname);
+ char_u *alloc_printable_func_name(char_u *fname);
  char_u *save_function_name(char_u **name, int *is_global, int skip, int 
flags, funcdict_T *fudi);
  void list_functions(regmatch_T *regmatch);
  ufunc_T *define_function(exarg_T *eap, char_u *name_arg, garray_T 
*lines_to_free);
*** ../vim-8.2.4428/src/evalfunc.c      2022-02-20 18:26:43.107537899 +0000
--- src/evalfunc.c      2022-02-21 12:27:35.243609763 +0000
***************
*** 570,576 ****
                        || context->arg_types[0].type_curr->tt_type == VAR_BLOB
                        || context->arg_types[0].type_curr->tt_type == VAR_LIST)
                    args[0] = &t_number;
!               else if (context->arg_types[0].type_curr->tt_type == VAR_DICT)
                    args[0] = &t_string;
                if (args[0] != NULL)
                    args[1] = expected_ret;
--- 570,576 ----
                        || context->arg_types[0].type_curr->tt_type == VAR_BLOB
                        || context->arg_types[0].type_curr->tt_type == VAR_LIST)
                    args[0] = &t_number;
!               else if (context->arg_types[0].type_decl->tt_type == VAR_DICT)
                    args[0] = &t_string;
                if (args[0] != NULL)
                    args[1] = expected_ret;
***************
*** 4366,4371 ****
--- 4366,4373 ----
            // would also work, but some plugins depend on the name being
            // printable text.
            name = get_scriptlocal_funcname(s);
+       else if (trans_name != NULL && *trans_name == K_SPECIAL)
+           name = alloc_printable_func_name(trans_name);
        else
            name = vim_strsave(s);
  
*** ../vim-8.2.4428/src/vim9type.c      2022-02-06 15:49:32.377256545 +0000
--- src/vim9type.c      2022-02-21 12:18:59.556879233 +0000
***************
*** 457,463 ****
                    {
                        type->tt_argcount -= tv->vval.v_partial->pt_argc;
                        type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
!                       if (type->tt_argcount == 0)
                            type->tt_args = NULL;
                        else
                        {
--- 457,463 ----
                    {
                        type->tt_argcount -= tv->vval.v_partial->pt_argc;
                        type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
!                       if (type->tt_argcount <= 0)
                            type->tt_args = NULL;
                        else
                        {
*** ../vim-8.2.4428/src/testdir/test_vim9_import.vim    2022-02-16 
21:48:20.966418934 +0000
--- src/testdir/test_vim9_import.vim    2022-02-21 12:24:50.516020383 +0000
***************
*** 423,428 ****
--- 423,468 ----
    delete('Xlib.vim')
  enddef
  
+ def Test_import_duplicate_function()
+   # Function Hover() exists in both scripts, partial should refer to the right
+   # one.
+   var lines =<< trim END
+       vim9script
+ 
+       def Hover(d: dict<any>): string
+         return 'found it'
+       enddef
+ 
+       export def NewLspServer(): dict<any>
+         var d: dict<any> = {}
+         d->extend({hover: function('Hover', [d])})
+         return d
+       enddef
+ 
+       NewLspServer()
+   END
+   writefile(lines, 'Xserver.vim')
+ 
+   lines =<< trim END
+       vim9script
+ 
+       import './Xserver.vim' as server
+ 
+       export def Hover()
+       enddef
+ 
+       def AddServer()
+         var d: dict<any> = server.NewLspServer()
+         assert_equal('found it', d.hover())
+       enddef
+       AddServer()
+   END
+   v9.CheckScriptSuccess(lines)
+ 
+   delete('Xserver.vim')
+ enddef
+ 
+ 
  def Test_import_fails()
    writefile([], 'Xfoo.vim')
    var lines =<< trim END
*** ../vim-8.2.4428/src/version.c       2022-02-20 20:48:53.226071796 +0000
--- src/version.c       2022-02-21 12:25:21.143944334 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4429,
  /**/

-- 
>From "know your smileys":
 :^[/   mean-smiley-with-cigarette

 /// 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/20220221131438.338681C0FE0%40moolenaar.net.

Raspunde prin e-mail lui