]> granicus.if.org Git - vim/commitdiff
patch 8.2.1510: using "var" in :def function may refer to legacy script var v8.2.1510
authorBram Moolenaar <Bram@vim.org>
Sat, 22 Aug 2020 17:02:02 +0000 (19:02 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 22 Aug 2020 17:02:02 +0000 (19:02 +0200)
Problem:    Using "var" in a :def function may refer to a legacy Vim script
            variable.
Solution:   Require using "s:" to refer to a legacy Vim script variable.
            (closes #6771)

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

index 35a8bf765b12cffb7b6fd2977adb30cd431bf2b2..412e4a6dc9fd96f8e7c910adac95dde66a922b8a 100644 (file)
@@ -829,30 +829,30 @@ endfunc
 let s:funcResult = 0
 
 def FuncNoArgNoRet()
-  funcResult = 11
+  s:funcResult = 11
 enddef
 
 def FuncNoArgRetNumber(): number
-  funcResult = 22
+  s:funcResult = 22
   return 1234
 enddef
 
 def FuncNoArgRetString(): string
-  funcResult = 45
+  s:funcResult = 45
   return 'text'
 enddef
 
 def FuncOneArgNoRet(arg: number)
-  funcResult = arg
+  s:funcResult = arg
 enddef
 
 def FuncOneArgRetNumber(arg: number): number
-  funcResult = arg
+  s:funcResult = arg
   return arg
 enddef
 
 def FuncTwoArgNoRet(one: bool, two: number)
-  funcResult = two
+  s:funcResult = two
 enddef
 
 def FuncOneArgRetString(arg: string): string
@@ -865,31 +865,31 @@ enddef
 
 def Test_func_type()
   let Ref1: func()
-  funcResult = 0
+  s:funcResult = 0
   Ref1 = FuncNoArgNoRet
   Ref1()
-  assert_equal(11, funcResult)
+  assert_equal(11, s:funcResult)
 
   let Ref2: func
-  funcResult = 0
+  s:funcResult = 0
   Ref2 = FuncNoArgNoRet
   Ref2()
-  assert_equal(11, funcResult)
+  assert_equal(11, s:funcResult)
 
-  funcResult = 0
+  s:funcResult = 0
   Ref2 = FuncOneArgNoRet
   Ref2(12)
-  assert_equal(12, funcResult)
+  assert_equal(12, s:funcResult)
 
-  funcResult = 0
+  s:funcResult = 0
   Ref2 = FuncNoArgRetNumber
   assert_equal(1234, Ref2())
-  assert_equal(22, funcResult)
+  assert_equal(22, s:funcResult)
 
-  funcResult = 0
+  s:funcResult = 0
   Ref2 = FuncOneArgRetNumber
   assert_equal(13, Ref2(13))
-  assert_equal(13, funcResult)
+  assert_equal(13, s:funcResult)
 enddef
 
 def Test_repeat_return_type()
index 1cdd69a005228a1ce7cb271f68ec5acdf4eeda47..60726ab942816d038c910e3a31208024a57e746b 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1510,
 /**/
     1509,
 /**/
index a552c8512339a4c6ee9687935753238c8b4df3c7..e4b7d44adbfbe1831ba301d1d68c9aa576e9bf2d 100644 (file)
@@ -260,15 +260,20 @@ lookup_arg(
 
 /*
  * Lookup a variable in the current script.
+ * If "vim9script" is TRUE the script must be Vim9 script.  Used for "var"
+ * without "s:".
  * Returns OK or FAIL.
  */
     static int
-lookup_script(char_u *name, size_t len)
+lookup_script(char_u *name, size_t len, int vim9script)
 {
     int                    cc;
     hashtab_T      *ht = &SCRIPT_VARS(current_sctx.sc_sid);
     dictitem_T     *di;
 
+    if (vim9script && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
+                                                       != SCRIPT_VERSION_VIM9)
+       return FAIL;
     cc = name[len];
     name[len] = NUL;
     di = find_var_in_ht(ht, 0, name, TRUE);
@@ -287,7 +292,7 @@ check_defined(char_u *p, size_t len, cctx_T *cctx)
     int c = p[len];
 
     p[len] = NUL;
-    if (lookup_script(p, len) == OK
+    if (lookup_script(p, len, FALSE) == OK
            || (cctx != NULL
                && (lookup_local(p, len, cctx) != NULL
                    || lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK))
@@ -2145,15 +2150,14 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
            else
            {
                // "var" can be script-local even without using "s:" if it
-               // already exists.
-               if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
-                                                   == SCRIPT_VERSION_VIM9
-                           || lookup_script(*arg, len) == OK)
-                  res = compile_load_scriptvar(cctx, name, *arg, &end,
-                                                                   FALSE);
+               // already exists in a Vim9 script or when it's imported.
+               if (lookup_script(*arg, len, TRUE) == OK
+                       || find_imported(name, 0, cctx) != NULL)
+                  res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
 
                // When the name starts with an uppercase letter or "x:" it
                // can be a user defined function.
+               // TODO: this is just guessing
                if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':'))
                    res = generate_funcref(cctx, name);
            }
@@ -4697,8 +4701,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                    int script_namespace = varlen > 1
                                           && STRNCMP(var_start, "s:", 2) == 0;
                    int script_var = (script_namespace
-                               ? lookup_script(var_start + 2, varlen - 2)
-                               : lookup_script(var_start, varlen)) == OK;
+                             ? lookup_script(var_start + 2, varlen - 2, FALSE)
+                             : lookup_script(var_start, varlen, TRUE)) == OK;
                    imported_T  *import =
                                        find_imported(var_start, varlen, cctx);
 
@@ -6637,7 +6641,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
                            || lookup_local(ea.cmd, len, &cctx) != NULL
                            || lookup_arg(ea.cmd, len, NULL, NULL,
                                                             NULL, &cctx) == OK
-                           || lookup_script(ea.cmd, len) == OK
+                           || lookup_script(ea.cmd, len, FALSE) == OK
                            || find_imported(ea.cmd, len, &cctx) != NULL)
                    {
                        line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);