]> granicus.if.org Git - vim/commitdiff
patch 8.2.3299: Vim9: exists() does not handle much at compile time v8.2.3299
authorBram Moolenaar <Bram@vim.org>
Thu, 5 Aug 2021 20:48:11 +0000 (22:48 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 5 Aug 2021 20:48:11 +0000 (22:48 +0200)
Problem:    Vim9: exists() does not handle much at compile time.
Solution:   Handle variable names. (closes #8688)

src/evalfunc.c
src/testdir/test_vim9_builtin.vim
src/version.c
src/vim9compile.c

index 6db930ef220a436eeacb0ef61556fe62f7019d1b..af46d150a23c192bd322748363781f5b02f90adc 100644 (file)
@@ -3552,7 +3552,14 @@ f_exists(typval_T *argvars, typval_T *rettv)
     }
     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
     {
index 19baada10b4586d3df37ec4419322490f63040d2..4fb1df342d983ab0d8e74e58a1f2e45356f2f5b8 100644 (file)
@@ -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')
index 942f114f0ac36eb7937388d2778b98368e0a6de6..6518b3be661dfb69f9c7c1033bcb32d601fe8314 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3299,
 /**/
     3298,
 /**/
index d96724b12c639ba0f616189b09c2f637e10f79e0..23f0a746e199fa06471cf568d9a800907d418a7d 100644 (file)
@@ -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];