patch 8.2.4447: Vim9: can still use s:var in a compiled function v8.2.4447
authorBram Moolenaar <Bram@vim.org>
Tue, 22 Feb 2022 20:43:36 +0000 (20:43 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 22 Feb 2022 20:43:36 +0000 (20:43 +0000)
Problem:    Vim9: can still use s:var in a compiled function.
Solution:   Disallow using s:var for Vim9 script. (closes #9824)

runtime/doc/vim9.txt
src/testdir/test_vim9_assign.vim
src/version.c
src/vim9compile.c
src/vim9expr.c

index 987495a326d2c9ab9b888423792cc9e50f469421..a5bcb3f443bfe219b633a3677d115e24946fd39c 100644 (file)
@@ -1,4 +1,4 @@
-*vim9.txt*     For Vim version 8.2.  Last change: 2022 Feb 18
+*vim9.txt*     For Vim version 8.2.  Last change: 2022 Feb 22
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -245,9 +245,11 @@ that the name interferes with builtin functions.
                                                        *vim9-s-namespace*
 The use of the "s:" prefix is not supported at the Vim9 script level.  All
 functions and variables without a prefix are script-local.
-In :def functions the use of "s:" is optional.  This is because in legacy
-script the "s:" might be needed.  Disallowing the use of "s:" only in a :def
-function in Vim9 script would be a bit confusing.
+
+In :def functions the use of "s:" depends on the script: Script-local
+variables and functions in a legacy script do use "s:", while in a Vim9 script
+they do not use "s:".  This matches what you see in the rest of the file.
+
 In legacy functions the use of "s:" for script items is required, as before.
 
 In all cases the function must be defined before used.  That is when it is
@@ -1467,7 +1469,7 @@ strings: >
        # typename(mylist) == "list<string>", no error
 
 There is a subtle difference between using a list constant directly and
-through a variable declaraiton.  Because of type inference, when using a list
+through a variable declaration.  Because of type inference, when using a list
 constant to initialize a variable, this also sets the declared type: >
        var mylist = [1, 2, 3]
        # typename(mylist) == "list<number>"
index 82521c8888fd1b622ce772e274bf770ede2c33c7..44247add1f409ebea56e51ab31bd8fbdf88cd2b1 100644 (file)
@@ -220,7 +220,7 @@ def Test_assignment()
     enddef
     defcompile
   END
-  v9.CheckScriptFailure(lines, 'E1089:')
+  v9.CheckScriptFailure(lines, 'E1268:')
 
   g:inc_counter += 1
   assert_equal(2, g:inc_counter)
@@ -2460,6 +2460,49 @@ def Run_Test_declare_command_line()
   g:StopVimInTerminal(buf)
 enddef
 
+def Test_using_s_var_in_function()
+  var lines =<< trim END
+      vim9script
+      var scriptlevel = 123
+      def SomeFunc()
+        echo s:scriptlevel
+      enddef
+      SomeFunc()
+  END
+  v9.CheckScriptFailure(lines, 'E1268:')
+
+  # OK in legacy script
+  lines =<< trim END
+      let s:scriptlevel = 123
+      def s:SomeFunc()
+        echo s:scriptlevel
+      enddef
+      call s:SomeFunc()
+  END
+  v9.CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      vim9script
+      var scriptlevel = 123
+      def SomeFunc()
+        s:scriptlevel = 456
+      enddef
+      SomeFunc()
+  END
+  v9.CheckScriptFailure(lines, 'E1268:')
+
+  # OK in legacy script
+  lines =<< trim END
+      let s:scriptlevel = 123
+      def s:SomeFunc()
+        s:scriptlevel = 456
+      enddef
+      call s:SomeFunc()
+      call assert_equal(456, s:scriptlevel)
+  END
+  v9.CheckScriptSuccess(lines)
+enddef
+
 
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 253cbe809d6636014f6187eb3f9ca893fc170edc..97a8f6e48c5b40181925c10234f32a6511b41677 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4447,
 /**/
     4446,
 /**/
index 803f19c0800d000340a25855b80536412f3c90d2..6eb6e160e26ce66647a48694883f042166a0ca6a 100644 (file)
@@ -1331,6 +1331,12 @@ compile_lhs(
                    char_u      *rawname = lhs->lhs_name
                                           + (lhs->lhs_name[1] == ':' ? 2 : 0);
 
+                   if (script_namespace && current_script_is_vim9())
+                   {
+                       semsg(_(e_cannot_use_s_colon_in_vim9_script_str),
+                                                                   var_start);
+                       return FAIL;
+                   }
                    if (is_decl)
                    {
                        if (script_namespace)
index 46d14dc05e100a809e4a95c8adf5abdcb2febead..1485bd93cf37c89e8c4e414a2fd78d2f464d194c 100644 (file)
@@ -422,8 +422,15 @@ compile_load(
            {
                case 'v': res = generate_LOADV(cctx, name, error);
                          break;
-               case 's': if (is_expr && ASCII_ISUPPER(*name)
-                                      && find_func(name, FALSE) != NULL)
+               case 's': if (current_script_is_vim9())
+                         {
+                             semsg(_(e_cannot_use_s_colon_in_vim9_script_str),
+                                                                        *arg);
+                             vim_free(name);
+                             return FAIL;
+                         }
+                         if (is_expr && ASCII_ISUPPER(*name)
+                                            && find_func(name, FALSE) != NULL)
                              res = generate_funcref(cctx, name, FALSE);
                          else
                              res = compile_load_scriptvar(cctx, name,