changeset 24390:492f7b54f691 v8.2.2735

patch 8.2.2735: Vim9: function reference found with prefix, not without Commit: https://github.com/vim/vim/commit/fa5963880df1d11613594ab78c0a68f894d34aa3 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Apr 7 21:58:16 2021 +0200 patch 8.2.2735: Vim9: function reference found with prefix, not without Problem: Vim9: function reference found with prefix, not without. Solution: Also find function reference without prefix.
author Bram Moolenaar <Bram@vim.org>
date Wed, 07 Apr 2021 22:00:04 +0200
parents 9b13404bbb6f
children 7d85ad2835cd
files src/testdir/test_vim9_expr.vim src/version.c src/vim9compile.c
diffstat 3 files changed, 43 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -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'}
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2735,
+/**/
     2734,
 /**/
     2733,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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);
 	    }
 	}