changeset 21983:3fe594c72d8c v8.2.1541

patch 8.2.1541: Vim9: cannot find function reference for s:Func Commit: https://github.com/vim/vim/commit/95006e3dca099d3dc73d70d9872660308106e86c Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 29 17:47:08 2020 +0200 patch 8.2.1541: Vim9: cannot find function reference for s:Func Problem: Vim9: cannot find function reference for s:Func. Solution: Recognize <SNR> prefix. (closes https://github.com/vim/vim/issues/6805)
author Bram Moolenaar <Bram@vim.org>
date Sat, 29 Aug 2020 18:00:04 +0200
parents 8ffa48563456
children 23eca0b1283d
files src/testdir/test_vim9_script.vim src/userfunc.c src/version.c src/vim9execute.c
diffstat 4 files changed, 32 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1652,6 +1652,10 @@ def Test_vim9script_reload_import()
   delete('Ximport.vim')
 enddef
 
+def s:RetSome(): string
+  return 'some'
+enddef
+
 " Not exported function that is referenced needs to be accessed by the
 " script-local name.
 def Test_vim9script_funcref()
@@ -1683,6 +1687,9 @@ def Test_vim9script_funcref()
   unlet g:result
   delete('Xsort.vim')
   delete('Xscript.vim')
+
+  let Funcref = function('s:RetSome')
+  assert_equal('some', Funcref())
 enddef
 
 " Check that when searching for "FilterFunc" it finds the import in the
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -808,11 +808,12 @@ find_func_even_dead(char_u *name, int is
 
     if (!is_global)
     {
-	int	vim9script = in_vim9script();
 	char_u	*after_script = NULL;
 	long	sid = 0;
-
-	if (vim9script)
+	int	find_script_local = in_vim9script()
+				     && eval_isnamec1(*name) && name[1] != ':';
+
+	if (find_script_local)
 	{
 	    // Find script-local function before global one.
 	    func = find_func_with_sid(name, current_sctx.sc_sid);
@@ -833,7 +834,7 @@ find_func_even_dead(char_u *name, int is
 	    else
 		after_script = NULL;
 	}
-	if (vim9script || after_script != NULL)
+	if (find_script_local || after_script != NULL)
 	{
 	    // Find imported function before global one.
 	    if (after_script != NULL && sid != current_sctx.sc_sid)
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1541,
+/**/
     1540,
 /**/
     1539,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -614,6 +614,7 @@ call_partial(typval_T *tv, int argcount_
     int		argcount = argcount_arg;
     char_u	*name = NULL;
     int		called_emsg_before = called_emsg;
+    int		res;
 
     if (tv->v_type == VAR_PARTIAL)
     {
@@ -650,7 +651,23 @@ call_partial(typval_T *tv, int argcount_
     }
     else if (tv->v_type == VAR_FUNC)
 	name = tv->vval.v_string;
-    if (name == NULL || call_by_name(name, argcount, ectx, NULL) == FAIL)
+    if (name != NULL)
+    {
+	char_u	fname_buf[FLEN_FIXED + 1];
+	char_u	*tofree = NULL;
+	int	error = FCERR_NONE;
+	char_u	*fname;
+
+	// May need to translate <SNR>123_ to K_SNR.
+	fname = fname_trans_sid(name, fname_buf, &tofree, &error);
+	if (error != FCERR_NONE)
+	    res = FAIL;
+	else
+	    res = call_by_name(fname, argcount, ectx, NULL);
+	vim_free(tofree);
+    }
+
+    if (name == NULL || res == FAIL)
     {
 	if (called_emsg == called_emsg_before)
 	    semsg(_(e_unknownfunc),