Patch 8.2.1373
Problem:    Vim9: no error for assigning to non-existing script var.
Solution:   Check that in Vim9 script the variable was defined. (closes #6630)
Files:      src/vim9compile.c, src/userfunc.c, src/structs.h,
            src/testdir/test_vim9_script.vim


*** ../vim-8.2.1372/src/vim9compile.c   2020-08-05 10:53:15.087273357 +0200
--- src/vim9compile.c   2020-08-05 14:08:25.707856210 +0200
***************
*** 148,153 ****
--- 148,154 ----
  static char e_used_as_arg[] = N_("E1006: %s is used as an argument");
  static char e_cannot_use_void[] = N_("E1031: Cannot use void value");
  static char e_namespace[] = N_("E1075: Namespace not supported: %s");
+ static char e_unknown_var[] = N_("E1089: unknown variable: %s");
  
  static void delete_def_function_contents(dfunc_T *dfunc);
  static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx);
***************
*** 5335,5341 ****
            else
            {
                int         idx;
-               imported_T  *import = NULL;
  
                for (idx = 0; reserved[idx] != NULL; ++idx)
                    if (STRCMP(reserved[idx], name) == 0)
--- 5336,5341 ----
***************
*** 5374,5422 ****
                        goto theend;
                    }
                }
!               else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)
!                       || lookup_script(var_start, varlen) == OK
!                       || (import = find_imported(var_start, varlen, cctx))
!                                                                      != NULL)
                {
!                   char_u      *rawname = name + (name[1] == ':' ? 2 : 0);
  
!                   if (is_decl)
                    {
!                       if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0))
!                           semsg(_("E1101: Cannot declare a script variable in 
a function: %s"),
                                                                         name);
!                       else
!                           semsg(_("E1054: Variable already declared in the 
script: %s"),
                                                                         name);
!                       goto theend;
!                   }
!                   dest = dest_script;
  
!                   // existing script-local variables should have a type
!                   scriptvar_sid = current_sctx.sc_sid;
!                   if (import != NULL)
!                       scriptvar_sid = import->imp_sid;
!                   scriptvar_idx = get_script_item_idx(scriptvar_sid,
                                                                rawname, TRUE);
!                   if (scriptvar_idx >= 0)
!                   {
!                       scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
!                       svar_T       *sv = ((svar_T *)si->sn_var_vals.ga_data)
                                                               + scriptvar_idx;
!                       type = sv->sv_type;
                    }
!               }
!               else if (name[1] == ':' && name[2] != NUL)
!               {
!                   semsg(_("E1082: Cannot use a namespaced variable: %s"),
                                                                         name);
!                   goto theend;
!               }
!               else if (!is_decl)
!               {
!                   semsg(_("E1089: unknown variable: %s"), name);
!                   goto theend;
                }
            }
  
--- 5374,5440 ----
                        goto theend;
                    }
                }
!               else
                {
!                   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;
!                   imported_T  *import =
!                                       find_imported(var_start, varlen, cctx);
  
!                   if (script_namespace || script_var || import != NULL)
                    {
!                       char_u  *rawname = name + (name[1] == ':' ? 2 : 0);
! 
!                       if (is_decl)
!                       {
!                           if (script_namespace)
!                               semsg(_("E1101: Cannot declare a script 
variable in a function: %s"),
                                                                         name);
!                           else
!                               semsg(_("E1054: Variable already declared in 
the script: %s"),
                                                                         name);
!                           goto theend;
!                       }
!                       else if (cctx->ctx_ufunc->uf_script_ctx_version
!                                                       == SCRIPT_VERSION_VIM9
!                               && script_namespace
!                                             && !script_var && import == NULL)
!                       {
!                           semsg(_(e_unknown_var), name);
!                           goto theend;
!                       }
! 
!                       dest = dest_script;
  
!                       // existing script-local variables should have a type
!                       scriptvar_sid = current_sctx.sc_sid;
!                       if (import != NULL)
!                           scriptvar_sid = import->imp_sid;
!                       scriptvar_idx = get_script_item_idx(scriptvar_sid,
                                                                rawname, TRUE);
!                       if (scriptvar_idx >= 0)
!                       {
!                           scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
!                           svar_T           *sv =
!                                           ((svar_T *)si->sn_var_vals.ga_data)
                                                               + scriptvar_idx;
!                           type = sv->sv_type;
!                       }
                    }
!                   else if (name[1] == ':' && name[2] != NUL)
!                   {
!                       semsg(_("E1082: Cannot use a namespaced variable: %s"),
                                                                         name);
!                       goto theend;
!                   }
!                   else if (!is_decl)
!                   {
!                       semsg(_(e_unknown_var), name);
!                       goto theend;
!                   }
                }
            }
  
*** ../vim-8.2.1372/src/userfunc.c      2020-08-01 22:16:39.724599474 +0200
--- src/userfunc.c      2020-08-05 14:04:52.328403976 +0200
***************
*** 3508,3513 ****
--- 3508,3514 ----
      fp->uf_calls = 0;
      fp->uf_cleared = FALSE;
      fp->uf_script_ctx = current_sctx;
+     fp->uf_script_ctx_version = current_sctx.sc_version;
      fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
      if (is_export)
      {
*** ../vim-8.2.1372/src/structs.h       2020-07-31 22:04:59.772336176 +0200
--- src/structs.h       2020-08-05 14:06:16.484191588 +0200
***************
*** 1594,1600 ****
      int               uf_tml_execed;  // line being timed was executed
  # endif
      sctx_T    uf_script_ctx;  // SCTX where function was defined,
!                               // used for s: variables
      int               uf_refcount;    // reference count, see 
func_name_refcount()
  
      funccall_T        *uf_scoped;     // l: local variables for closure
--- 1594,1602 ----
      int               uf_tml_execed;  // line being timed was executed
  # endif
      sctx_T    uf_script_ctx;  // SCTX where function was defined,
!                               // used for s: variables; sc_version changed
!                               // for :function
!     int               uf_script_ctx_version;  // original sc_version of SCTX
      int               uf_refcount;    // reference count, see 
func_name_refcount()
  
      funccall_T        *uf_scoped;     // l: local variables for closure
*** ../vim-8.2.1372/src/testdir/test_vim9_script.vim    2020-08-02 
20:40:40.089339804 +0200
--- src/testdir/test_vim9_script.vim    2020-08-05 14:32:06.679904410 +0200
***************
*** 112,117 ****
--- 112,126 ----
    call CheckDefFailure(['let s:var = 123'], 'E1101:')
    call CheckDefFailure(['let s:var: number'], 'E1101:')
  
+   lines =<< trim END
+     vim9script
+     def SomeFunc()
+       s:var = 123
+     enddef
+     defcompile
+   END
+   call CheckScriptFailure(lines, 'E1089:')
+ 
    g:inc_counter += 1
    assert_equal(2, g:inc_counter)
  
*** ../vim-8.2.1372/src/version.c       2020-08-05 12:44:37.369298977 +0200
--- src/version.c       2020-08-05 13:21:13.563851524 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     1373,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
126. You brag to all of your friends about your date Saturday night...but
     you don't tell them it was only in a chat room.

 /// 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/202008051234.075CYeAB3289180%40masaka.moolenaar.net.

Raspunde prin e-mail lui