diff src/userfunc.c @ 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 58cfcd3ed15b
children ceff6a546748
line wrap: on
line diff
--- 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);
 }
 
 /*