Patch 8.2.2194
Problem:    Vim9: cannot use :const or :final at the script level.
Solution:   Support using :const and :final. (closes #7526)
Files:      src/vim.h, src/evalvars.c, src/testdir/test_vim9_assign.vim,
            src/testdir/test_vim9_func.vim


*** ../vim-8.2.2193/src/vim.h   2020-12-19 22:10:09.861835442 +0100
--- src/vim.h   2020-12-22 20:45:12.063111668 +0100
***************
*** 2144,2150 ****
  // Flags for assignment functions.
  #define ASSIGN_FINAL  1   // ":final"
  #define ASSIGN_CONST  2   // ":const"
! #define ASSIGN_NO_DECL        4   // "name = expr" without ":let" or ":const"
  
  #include "ex_cmds.h"      // Ex command defines
  #include "spell.h"        // spell checking stuff
--- 2144,2150 ----
  // Flags for assignment functions.
  #define ASSIGN_FINAL  1   // ":final"
  #define ASSIGN_CONST  2   // ":const"
! #define ASSIGN_NO_DECL        4   // "name = expr" without 
":let"/":const"/":final"
  
  #include "ex_cmds.h"      // Ex command defines
  #include "spell.h"        // spell checking stuff
*** ../vim-8.2.2193/src/evalvars.c      2020-12-22 20:35:37.465034288 +0100
--- src/evalvars.c      2020-12-22 20:56:11.597584514 +0100
***************
*** 738,751 ****
      int               first = TRUE;
      int               concat;
      int               has_assign;
!     int               flags = eap->cmdidx == CMD_const ? ASSIGN_CONST : 0;
      int               vim9script = in_vim9script();
  
      if (eap->cmdidx == CMD_final && !vim9script)
      {
!           // In legacy Vim script ":final" is short for ":finally".
!           ex_finally(eap);
!           return;
      }
      if (eap->cmdidx == CMD_let && vim9script)
      {
--- 738,751 ----
      int               first = TRUE;
      int               concat;
      int               has_assign;
!     int               flags = 0;
      int               vim9script = in_vim9script();
  
      if (eap->cmdidx == CMD_final && !vim9script)
      {
!       // In legacy Vim script ":final" is short for ":finally".
!       ex_finally(eap);
!       return;
      }
      if (eap->cmdidx == CMD_let && vim9script)
      {
***************
*** 756,762 ****
        // In legacy Vim script ":const" works like ":final".
        eap->cmdidx = CMD_final;
  
!     // detect Vim9 assignment without ":let" or ":const"
      if (eap->arg == eap->cmd)
        flags |= ASSIGN_NO_DECL;
  
--- 756,767 ----
        // In legacy Vim script ":const" works like ":final".
        eap->cmdidx = CMD_final;
  
!     if (eap->cmdidx == CMD_const)
!       flags |= ASSIGN_CONST;
!     else if (eap->cmdidx == CMD_final)
!       flags |= ASSIGN_FINAL;
! 
!     // Vim9 assignment without ":let", ":const" or ":final"
      if (eap->arg == eap->cmd)
        flags |= ASSIGN_NO_DECL;
  
***************
*** 909,915 ****
      int               copy,           // copy values from "tv", don't move
      int               semicolon,      // from skip_var_list()
      int               var_count,      // from skip_var_list()
!     int               flags,          // ASSIGN_CONST, ASSIGN_NO_DECL
      char_u    *op)
  {
      char_u    *arg = arg_start;
--- 914,920 ----
      int               copy,           // copy values from "tv", don't move
      int               semicolon,      // from skip_var_list()
      int               var_count,      // from skip_var_list()
!     int               flags,          // ASSIGN_FINAL, ASSIGN_CONST, 
ASSIGN_NO_DECL
      char_u    *op)
  {
      char_u    *arg = arg_start;
***************
*** 1264,1270 ****
      char_u    *arg,           // points to variable name
      typval_T  *tv,            // value to assign to variable
      int               copy,           // copy value from "tv"
!     int               flags,          // ASSIGN_CONST, ASSIGN_NO_DECL
      char_u    *endchars,      // valid chars after variable name  or NULL
      char_u    *op)            // "+", "-", "."  or NULL
  {
--- 1269,1275 ----
      char_u    *arg,           // points to variable name
      typval_T  *tv,            // value to assign to variable
      int               copy,           // copy value from "tv"
!     int               flags,          // ASSIGN_CONST, ASSIGN_FINAL, 
ASSIGN_NO_DECL
      char_u    *endchars,      // valid chars after variable name  or NULL
      char_u    *op)            // "+", "-", "."  or NULL
  {
***************
*** 1277,1282 ****
--- 1282,1288 ----
      char_u    *tofree = NULL;
  
      if (in_vim9script() && (flags & ASSIGN_NO_DECL) == 0
+                       && (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
                                  && vim_strchr((char_u *)"$@&", *arg) != NULL)
      {
        vim9_declare_error(arg);
***************
*** 1286,1292 ****
      // ":let $VAR = expr": Set environment variable.
      if (*arg == '$')
      {
!       if (flags & ASSIGN_CONST)
        {
            emsg(_("E996: Cannot lock an environment variable"));
            return NULL;
--- 1292,1298 ----
      // ":let $VAR = expr": Set environment variable.
      if (*arg == '$')
      {
!       if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
        {
            emsg(_("E996: Cannot lock an environment variable"));
            return NULL;
***************
*** 1338,1344 ****
      // ":let &g:option = expr": Set global option value.
      else if (*arg == '&')
      {
!       if (flags & ASSIGN_CONST)
        {
            emsg(_(e_const_option));
            return NULL;
--- 1344,1350 ----
      // ":let &g:option = expr": Set global option value.
      else if (*arg == '&')
      {
!       if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
        {
            emsg(_(e_const_option));
            return NULL;
***************
*** 1422,1428 ****
      // ":let @r = expr": Set register contents.
      else if (*arg == '@')
      {
!       if (flags & ASSIGN_CONST)
        {
            emsg(_("E996: Cannot lock a register"));
            return NULL;
--- 1428,1434 ----
      // ":let @r = expr": Set register contents.
      else if (*arg == '@')
      {
!       if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
        {
            emsg(_("E996: Cannot lock a register"));
            return NULL;
***************
*** 3056,3062 ****
      type_T    *type,
      typval_T  *tv_arg,
      int               copy,       // make copy of value in "tv"
!     int               flags)      // ASSIGN_CONST, ASSIGN_NO_DECL
  {
      typval_T  *tv = tv_arg;
      typval_T  bool_tv;
--- 3062,3068 ----
      type_T    *type,
      typval_T  *tv_arg,
      int               copy,       // make copy of value in "tv"
!     int               flags)      // ASSIGN_CONST, ASSIGN_FINAL, 
ASSIGN_NO_DECL
  {
      typval_T  *tv = tv_arg;
      typval_T  bool_tv;
***************
*** 3077,3082 ****
--- 3083,3089 ----
      if (vim9script
            && !is_script_local
            && (flags & ASSIGN_NO_DECL) == 0
+           && (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
            && name[1] == ':')
      {
        vim9_declare_error(name);
***************
*** 3106,3112 ****
      {
        if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
        {
!           if (flags & ASSIGN_CONST)
            {
                emsg(_(e_cannot_mod));
                goto failed;
--- 3113,3119 ----
      {
        if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
        {
!           if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
            {
                emsg(_(e_cannot_mod));
                goto failed;
***************
*** 3206,3212 ****
            goto failed;
        }
        di->di_flags = DI_FLAGS_ALLOC;
!       if (flags & ASSIGN_CONST)
            di->di_flags |= DI_FLAGS_LOCK;
  
        // A Vim9 script-local variable is also added to sn_all_vars and
--- 3213,3219 ----
            goto failed;
        }
        di->di_flags = DI_FLAGS_ALLOC;
!       if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
            di->di_flags |= DI_FLAGS_LOCK;
  
        // A Vim9 script-local variable is also added to sn_all_vars and
*** ../vim-8.2.2193/src/testdir/test_vim9_assign.vim    2020-12-21 
17:30:46.941668485 +0100
--- src/testdir/test_vim9_assign.vim    2020-12-22 21:16:18.974238954 +0100
***************
*** 1127,1132 ****
--- 1127,1156 ----
  
      const FOO: number = 123
      assert_equal(123, FOO)
+     const FOOS = 'foos'
+     assert_equal('foos', FOOS)
+     final FLIST = [1]
+     assert_equal([1], FLIST)
+     FLIST[0] = 11
+     assert_equal([11], FLIST)
+ 
+     const g:FOO: number = 321
+     assert_equal(321, g:FOO)
+     const g:FOOS = 'gfoos'
+     assert_equal('gfoos', g:FOOS)
+     final g:FLIST = [2]
+     assert_equal([2], g:FLIST)
+     g:FLIST[0] = 22
+     assert_equal([22], g:FLIST)
+ 
+     const w:FOO: number = 46
+     assert_equal(46, w:FOO)
+     const w:FOOS = 'wfoos'
+     assert_equal('wfoos', w:FOOS)
+     final w:FLIST = [3]
+     assert_equal([3], w:FLIST)
+     w:FLIST[0] = 33
+     assert_equal([33], w:FLIST)
  
      var s:other: number
      other = 1234
***************
*** 1150,1155 ****
--- 1174,1185 ----
    unlet g:var_test
    unlet g:var_prefixed
    unlet g:other_var
+   unlet g:FOO
+   unlet g:FOOS
+   unlet g:FLIST
+   unlet w:FOO
+   unlet w:FOOS
+   unlet w:FLIST
  enddef
  
  def Test_var_declaration_fails()
***************
*** 1161,1166 ****
--- 1191,1212 ----
  
    lines =<< trim END
      vim9script
+     const g:constvar = 'string'
+     g:constvar = 'xx'
+   END
+   CheckScriptFailure(lines, 'E741:')
+   unlet g:constvar
+ 
+   lines =<< trim END
+     vim9script
+     final w:finalvar = [9]
+     w:finalvar = [8]
+   END
+   CheckScriptFailure(lines, 'E1122:')
+   unlet w:finalvar
+ 
+   lines =<< trim END
+     vim9script
      const var: string
    END
    CheckScriptFailure(lines, 'E1021:')
*** ../vim-8.2.2193/src/testdir/test_vim9_func.vim      2020-12-22 
20:35:37.469034276 +0100
--- src/testdir/test_vim9_func.vim      2020-12-22 21:18:41.145814495 +0100
***************
*** 1032,1038 ****
        call Change()
        unlet g:Aconst
    END
!   CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
  enddef
  
  " Test that inside :function a Python function can be defined, :def is not
--- 1032,1038 ----
        call Change()
        unlet g:Aconst
    END
!   CheckScriptFailure(lines, 'E1122: Variable is locked: Aconst', 2)
  enddef
  
  " Test that inside :function a Python function can be defined, :def is not
*** ../vim-8.2.2193/src/version.c       2020-12-22 20:35:37.469034276 +0100
--- src/version.c       2020-12-22 20:56:37.317524097 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2194,
  /**/

-- 
Everybody wants to go to heaven, but nobody wants to die.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202012222020.0BMKKAIQ2668172%40masaka.moolenaar.net.

Raspunde prin e-mail lui