]> granicus.if.org Git - vim/commitdiff
patch 8.2.4063: Vim9: exported function in autoload script not found v8.2.4063
authorBram Moolenaar <Bram@vim.org>
Tue, 11 Jan 2022 15:24:05 +0000 (15:24 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 11 Jan 2022 15:24:05 +0000 (15:24 +0000)
Problem:    Vim9: exported function in autoload script not found. (Yegappan
            Lakshmanan)
Solution:   Use the autoload prefix to search for the function.

src/testdir/test_vim9_import.vim
src/userfunc.c
src/version.c

index ddf5b82b66aed55135310e08e3bb639cd5e0ded2..46b826c949f46dcc79c984d6e353bd5992728268 100644 (file)
@@ -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)
index 48f5890e8b1c4c8acaeb51f72761329312b79050..4516a48aab8f088fee9a09de0adb2a89542afd15 100644 (file)
@@ -1871,9 +1871,13 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
     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_global, cctx_T *cctx UNUSED)
     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);
 }
 
 /*
index 36525af3dbf18146f8a953cea1b4734d8c67ee77..731a6543f1841af55ae348fdd94da7cba3e99cf1 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4063,
 /**/
     4062,
 /**/