changeset 25525:8880eb140a00 v8.2.3299

patch 8.2.3299: Vim9: exists() does not handle much at compile time Commit: https://github.com/vim/vim/commit/5671f3f076573fa9133bc210d6580067698d9a1b Author: Bram Moolenaar <Bram@vim.org> Date: Thu Aug 5 22:48:11 2021 +0200 patch 8.2.3299: Vim9: exists() does not handle much at compile time Problem: Vim9: exists() does not handle much at compile time. Solution: Handle variable names. (closes https://github.com/vim/vim/issues/8688)
author Bram Moolenaar <Bram@vim.org>
date Thu, 05 Aug 2021 23:00:04 +0200
parents 359c6acd9ad1
children f9ebb5b05597
files src/evalfunc.c src/testdir/test_vim9_builtin.vim src/version.c src/vim9compile.c
diffstat 4 files changed, 34 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3552,7 +3552,14 @@ f_exists(typval_T *argvars, typval_T *re
     }
     else if (*p == '*')			// internal or user defined function
     {
+	int save_version = current_sctx.sc_version;
+
+	// Vim9 script assumes a function is script-local, but here we want to
+	// find any matching function.
+	if (current_sctx.sc_version == SCRIPT_VERSION_VIM9)
+	    current_sctx.sc_version = SCRIPT_VERSION_MAX;
 	n = function_exists(p + 1, FALSE);
+	current_sctx.sc_version = save_version;
     }
     else if (*p == '?')			// internal function only
     {
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -787,6 +787,8 @@ def Test_exepath()
   CheckDefExecFailure(['echo exepath("")'], 'E1175:')
 enddef
 
+command DoSomeCommand let g:didSomeCommand = 4
+
 def Test_exists()
   CheckDefAndScriptFailure2(['exists(10)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
   call assert_equal(1, exists('&tabstop'))
@@ -809,6 +811,26 @@ def Test_exists()
   else
     assert_report('tabstop option not existing?')
   endif
+
+  if exists(':DoSomeCommand') >= 2
+    DoSomeCommand
+  endif
+  assert_equal(4, g:didSomeCommand)
+  if exists(':NoSuchCommand') >= 2
+    NoSuchCommand
+  endif
+
+  var found = false
+  if exists('*CheckScriptSuccess')
+    found = true
+  endif
+  assert_true(found)
+  if exists('*NoSuchFunction')
+    NoSuchFunction()
+  endif
+  if exists('*no_such_function')
+    no_such_function()
+  endif
 enddef
 
 def Test_expand()
@@ -2948,7 +2970,7 @@ def Test_setreg()
   assert_fails('setreg("ab", 0)', 'E1162:')
   CheckDefAndScriptFailure2(['setreg(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
   CheckDefAndScriptFailure2(['setreg("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
-enddef 
+enddef
 
 def Test_settabvar()
   CheckDefAndScriptFailure2(['settabvar("a", "b", 1)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3299,
+/**/
     3298,
 /**/
     3297,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -3417,8 +3417,8 @@ compile_call(
 	s = skipwhite(s);
 	if (*s == ')' && argvars[0].v_type == VAR_STRING
 	       && ((is_has && !dynamic_feature(argvars[0].vval.v_string))
-		    || (!is_has && (*argvars[0].vval.v_string == '+'
-			    || *argvars[0].vval.v_string == '&'))))
+		    || (!is_has && vim_strchr((char_u *)"+&:*",
+						  *argvars[0].vval.v_string))))
 	{
 	    typval_T	*tv = &ppconst->pp_tv[ppconst->pp_used];