changeset 27068:6a4fc2e6e6eb v8.2.4063

patch 8.2.4063: Vim9: exported function in autoload script not found Commit: https://github.com/vim/vim/commit/b8822442d716df0230c79531132e530e95cc17e3 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jan 11 15:24:05 2022 +0000 patch 8.2.4063: Vim9: exported function in autoload script not found Problem: Vim9: exported function in autoload script not found. (Yegappan Lakshmanan) Solution: Use the autoload prefix to search for the function.
author Bram Moolenaar <Bram@vim.org>
date Tue, 11 Jan 2022 16:30:03 +0100
parents 89bc175b25a5
children 940d27b64e91
files src/testdir/test_vim9_import.vim src/userfunc.c src/version.c
diffstat 3 files changed, 56 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -1146,8 +1146,8 @@ def Test_vim9script_autoload()
        return 'test'
      enddef
 
-     export func GetSome()
-       return 'some'
+     export func GetMore()
+       return Gettest() .. 'more'
      endfunc
 
      export var name = 'name'
@@ -1163,7 +1163,7 @@ def Test_vim9script_autoload()
       assert_equal('test', prefixed.Gettest())
       assert_equal('yes', g:prefixed_loaded)
 
-      assert_equal('some', prefixed.GetSome())
+      assert_equal('testmore', prefixed.GetMore())
       assert_equal('name', prefixed.name)
       assert_equal('final', prefixed.fname)
       assert_equal('const', prefixed.cname)
@@ -1173,7 +1173,7 @@ def Test_vim9script_autoload()
   # can also get the items by autoload name
   lines =<< trim END
       call assert_equal('test', prefixed#Gettest())
-      call assert_equal('some', prefixed#GetSome())
+      call assert_equal('testmore', prefixed#GetMore())
       call assert_equal('name', prefixed#name)
       call assert_equal('final', prefixed#fname)
       call assert_equal('const', prefixed#cname)
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -1871,9 +1871,13 @@ fname_trans_sid(char_u *name, char_u *fn
     static ufunc_T *
 find_func_with_sid(char_u *name, int sid)
 {
-    hashitem_T	*hi;
-    char_u	buffer[200];
-
+    hashitem_T	    *hi;
+    char_u	    buffer[200];
+
+    if (!SCRIPT_ID_VALID(sid))
+	return NULL;	// not in a script
+
+    // A script-local function is stored as "<SNR>99_name".
     buffer[0] = K_SPECIAL;
     buffer[1] = KS_EXTRA;
     buffer[2] = (int)KE_SNR;
@@ -1882,6 +1886,46 @@ find_func_with_sid(char_u *name, int sid
     hi = hash_find(&func_hashtab, buffer);
     if (!HASHITEM_EMPTY(hi))
 	return HI2UF(hi);
+    return NULL;
+}
+
+/*
+ * Find a function "name" in script "sid" prefixing the autoload prefix.
+ */
+    static ufunc_T *
+find_func_with_prefix(char_u *name, int sid)
+{
+    hashitem_T	    *hi;
+    char_u	    buffer[200];
+    scriptitem_T    *si;
+
+    if (vim_strchr(name, AUTOLOAD_CHAR) != 0)
+	return NULL;	// already has the prefix
+    if (!SCRIPT_ID_VALID(sid))
+	return NULL;	// not in a script
+    si = SCRIPT_ITEM(sid);
+    if (si->sn_autoload_prefix != NULL)
+    {
+	size_t	len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1;
+	char_u	*auto_name;
+
+	// An exported function in an autoload script is stored as
+	// "dir#path#name".
+	if (len < sizeof(buffer))
+	    auto_name = buffer;
+	else
+	    auto_name = alloc(len);
+	if (auto_name != NULL)
+	{
+	    vim_snprintf((char *)auto_name, len, "%s%s",
+						 si->sn_autoload_prefix, name);
+	    hi = hash_find(&func_hashtab, auto_name);
+	    if (auto_name != buffer)
+		vim_free(auto_name);
+	    if (!HASHITEM_EMPTY(hi))
+		return HI2UF(hi);
+	}
+    }
 
     return NULL;
 }
@@ -1917,7 +1961,9 @@ find_func_even_dead(char_u *name, int is
     if (!HASHITEM_EMPTY(hi))
 	return HI2UF(hi);
 
-    return NULL;
+    // Find autoload function if this is an autoload script.
+    return find_func_with_prefix(name[0] == 's' && name[1] == ':'
+				       ? name + 2 : name, current_sctx.sc_sid);
 }
 
 /*
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4063,
+/**/
     4062,
 /**/
     4061,