]> granicus.if.org Git - vim/commitdiff
patch 8.2.4131: Vim9: calling function in autoload import does not work v8.2.4131
authorBram Moolenaar <Bram@vim.org>
Tue, 18 Jan 2022 12:58:28 +0000 (12:58 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 18 Jan 2022 12:58:28 +0000 (12:58 +0000)
Problem:    Vim9: calling function in autoload import does not work in a :def
            function.
Solution:   When a variable is not found and a PCALL follows use a funcref.
            (closes #9550)

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

index 1378261f7adf5a6d5143bc8103d1e437bf0c6370..13530151a2a7e3568f0f361882123769aff73ece 100644 (file)
@@ -1264,6 +1264,10 @@ def Test_vim9script_autoload_call()
   var lines =<< trim END
      vim9script autoload
 
+     export def RetArg(arg: string): string
+       return arg
+     enddef
+
      export def Getother()
        g:result = 'other'
      enddef
@@ -1273,6 +1277,13 @@ def Test_vim9script_autoload_call()
   lines =<< trim END
       vim9script
       import autoload 'another.vim'
+
+      # compile this before 'another.vim' is loaded
+      def CallAnother()
+        assert_equal('foo', 'foo'->another.RetArg())
+      enddef
+      CallAnother()
+
       call another.Getother()
       assert_equal('other', g:result)
   END
index f7e3053b84b07e08f36b04d3119a88718b044dfa..64a607796722ed901737680636ee25ceeb92128e 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4131,
 /**/
     4130,
 /**/
index c947d6a0ce110a5f1cb1b803cef114af09834b80..0037f51af8546fc37b6894a97565b2061eae33b4 100644 (file)
@@ -2200,10 +2200,12 @@ exec_instructions(ectx_T *ectx)
            case ISN_LOADW:
            case ISN_LOADT:
                {
-                   dictitem_T *di = NULL;
-                   hashtab_T *ht = NULL;
-                   char namespace;
+                   dictitem_T  *di = NULL;
+                   hashtab_T   *ht = NULL;
+                   char        namespace;
 
+                   if (GA_GROW_FAILS(&ectx->ec_stack, 1))
+                       goto theend;
                    switch (iptr->isn_type)
                    {
                        case ISN_LOADG:
@@ -2227,14 +2229,38 @@ exec_instructions(ectx_T *ectx)
                    }
                    di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE);
 
-                   if (di == NULL && ht == get_globvar_ht())
+                   if (di == NULL && ht == get_globvar_ht()
+                                           && vim_strchr(iptr->isn_arg.string,
+                                                       AUTOLOAD_CHAR) != NULL)
                    {
-                       // may need to load autoload script
+                       // Global variable has an autoload name, may still need
+                       // to load the script.
                        if (script_autoload(iptr->isn_arg.string, FALSE))
                            di = find_var_in_ht(ht, 0,
                                                   iptr->isn_arg.string, TRUE);
                        if (did_emsg)
                            goto on_error;
+                       if (di == NULL)
+                       {
+                           isn_T   *next = &ectx->ec_instr[ectx->ec_iidx];
+
+                           // When compiling "script.Func()" when "script" is
+                           // an autoload import then this results in
+                           // "LOADG script#Func" because we don't know if it
+                           // is a funcref variable or a function name.  In
+                           // that case a PCALL follows, push the function
+                           // name instead.
+                           if (next->isn_type == ISN_PCALL)
+                           {
+                               tv = STACK_TV_BOT(0);
+                               tv->v_type = VAR_FUNC;
+                               tv->v_lock = 0;
+                               tv->vval.v_string =
+                                            vim_strsave(iptr->isn_arg.string);
+                               ++ectx->ec_stack.ga_len;
+                               break;
+                           }
+                       }
                    }
 
                    if (di == NULL)
@@ -2246,8 +2272,6 @@ exec_instructions(ectx_T *ectx)
                    }
                    else
                    {
-                       if (GA_GROW_FAILS(&ectx->ec_stack, 1))
-                           goto theend;
                        copy_tv(&di->di_tv, STACK_TV_BOT(0));
                        ++ectx->ec_stack.ga_len;
                    }