]> granicus.if.org Git - vim/commitdiff
patch 8.2.4446: Vim9: cannot refer to a global function like a local one v8.2.4446
authorBram Moolenaar <Bram@vim.org>
Tue, 22 Feb 2022 19:39:13 +0000 (19:39 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 22 Feb 2022 19:39:13 +0000 (19:39 +0000)
Problem:    Vim9: cannot refer to a global function like a local one.
Solution:   When g:name is not a variable but a function, use a function
            reference. (closes #9826)

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

index b91e9f2dcec3610aae84128418d9832159467af8..2c183fd3c859795f0eccc12e46f8f32e3f21f9c5 100644 (file)
@@ -427,6 +427,21 @@ def Test_call_call()
   call('reverse', [l])
   l->assert_equal([1, 2, 3])
 
+  var lines =<< trim END
+      vim9script
+      def Outer()
+        def g:Inner()
+          g:done = 'Inner'
+        enddef
+        call(g:Inner, [])
+      enddef
+      Outer()
+      assert_equal('Inner', g:done)
+      unlet g:done
+  END
+  v9.CheckScriptSuccess(lines)
+  delfunc g:Inner
+
   v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1')
   v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1')
   v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
index cb6e8e3e8715b67c5dc73c8f19bfd93576b02674..253cbe809d6636014f6187eb3f9ca893fc170edc 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4446,
 /**/
     4445,
 /**/
index 3c23ad41103fa21ab5930a14c6d0f059cce65d3d..beca9e723d9e5a3e6a17949b2c0fb2c1ebc9ba08 100644 (file)
@@ -2333,16 +2333,33 @@ load_namespace_var(ectx_T *ectx, isntype_T isn_type, isn_T *iptr)
 
     if (di == NULL)
     {
+       if (isn_type == ISN_LOADG)
+       {
+           ufunc_T *ufunc = find_func(iptr->isn_arg.string, TRUE);
+
+           // g:Something could be a function
+           if (ufunc != NULL)
+           {
+               typval_T    *tv = STACK_TV_BOT(0);
+
+               ++ectx->ec_stack.ga_len;
+               tv->v_type = VAR_FUNC;
+               tv->vval.v_string = alloc(STRLEN(iptr->isn_arg.string) + 3);
+               if (tv->vval.v_string == NULL)
+                   return FAIL;
+               STRCPY(tv->vval.v_string, "g:");
+               STRCPY(tv->vval.v_string + 2, iptr->isn_arg.string);
+               return OK;
+           }
+       }
        SOURCING_LNUM = iptr->isn_lnum;
-       if (vim_strchr(iptr->isn_arg.string,
-                                       AUTOLOAD_CHAR) != NULL)
+       if (vim_strchr(iptr->isn_arg.string, AUTOLOAD_CHAR) != NULL)
            // no check if the item exists in the script but
            // isn't exported, it is too complicated
-           semsg(_(e_item_not_found_in_script_str),
-                                        iptr->isn_arg.string);
+           semsg(_(e_item_not_found_in_script_str), iptr->isn_arg.string);
        else
            semsg(_(e_undefined_variable_char_str),
-                            namespace, iptr->isn_arg.string);
+                                             namespace, iptr->isn_arg.string);
        return FAIL;
     }
     else