]> granicus.if.org Git - vim/commitdiff
patch 8.2.2735: Vim9: function reference found with prefix, not without v8.2.2735
authorBram Moolenaar <Bram@vim.org>
Wed, 7 Apr 2021 19:58:16 +0000 (21:58 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 7 Apr 2021 19:58:16 +0000 (21:58 +0200)
Problem:    Vim9: function reference found with prefix, not without.
Solution:   Also find function reference without prefix.

src/testdir/test_vim9_expr.vim
src/version.c
src/vim9compile.c

index c86379eb1af384dc952753cf2c8c5c0b7d80e184..44ff105c6231b43b8e1d1ec120e141084f4f9843 100644 (file)
@@ -2102,6 +2102,29 @@ def Test_expr7_funcref()
       assert_equal(123, FuncRef())
   END
   CheckDefAndScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      func g:GlobalFunc()
+        return 'global'
+      endfunc
+      func s:ScriptFunc()
+        return 'script'
+      endfunc
+      def Test()
+        var Ref = g:GlobalFunc
+        assert_equal('global', Ref())
+        Ref = GlobalFunc
+        assert_equal('global', Ref())
+
+        Ref = s:ScriptFunc
+        assert_equal('script', Ref())
+        Ref = ScriptFunc
+        assert_equal('script', Ref())
+      enddef
+      Test()
+  END
+  CheckScriptSuccess(lines)
 enddef
 
 let g:test_space_dict = {'': 'empty', ' ': 'space'}
index 4eea2f18559ddfb64e0d5fe5d58cae7ce1aa42cb..f1534f128491036bff855cf9c0156c205d5215d5 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2735,
 /**/
     2734,
 /**/
index c4b5d3c1c0f88a85c7218a0dedf6507ede354534..00a8f56469a29610934b3e1f06cfeb317175fe1b 100644 (file)
@@ -2889,11 +2889,11 @@ compile_load(
 
     if (*(*arg + 1) == ':')
     {
-       // load namespaced variable
        if (end <= *arg + 2)
        {
            isntype_T  isn_type;
 
+           // load dictionary of namespace
            switch (**arg)
            {
                case 'g': isn_type = ISN_LOADGDICT; break;
@@ -2912,6 +2912,7 @@ compile_load(
        {
            isntype_T  isn_type = ISN_DROP;
 
+           // load namespaced variable
            name = vim_strnsave(*arg + 2, end - (*arg + 2));
            if (name == NULL)
                return FAIL;
@@ -2920,11 +2921,21 @@ compile_load(
            {
                case 'v': res = generate_LOADV(cctx, name, error);
                          break;
-               case 's': res = compile_load_scriptvar(cctx, name,
+               case 's': if (is_expr && ASCII_ISUPPER(*name)
+                                      && find_func(name, FALSE, cctx) != NULL)
+                             res = generate_funcref(cctx, name);
+                         else
+                             res = compile_load_scriptvar(cctx, name,
                                                            NULL, &end, error);
                          break;
                case 'g': if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
-                             isn_type = ISN_LOADG;
+                         {
+                             if (is_expr && ASCII_ISUPPER(*name)
+                                      && find_func(name, FALSE, cctx) != NULL)
+                                 res = generate_funcref(cctx, name);
+                             else
+                                 isn_type = ISN_LOADG;
+                         }
                          else
                          {
                              isn_type = ISN_LOADAUTO;
@@ -2945,7 +2956,7 @@ compile_load(
            {
                // Global, Buffer-local, Window-local and Tabpage-local
                // variables can be defined later, thus we don't check if it
-               // exists, give error at runtime.
+               // exists, give an error at runtime.
                res = generate_LOAD(cctx, isn_type, 0, name, &t_any);
            }
        }
@@ -2988,10 +2999,9 @@ compile_load(
                   res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
 
                // When evaluating an expression and the name starts with an
-               // uppercase letter or "x:" it can be a user defined function.
-               // TODO: this is just guessing
-               if (res == FAIL && is_expr
-                                  && (ASCII_ISUPPER(*name) || name[1] == ':'))
+               // uppercase letter it can be a user defined function.
+               // generate_funcref() will fail if the function can't be found.
+               if (res == FAIL && is_expr && ASCII_ISUPPER(*name))
                    res = generate_funcref(cctx, name);
            }
        }