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 -- Br...@Moolenaar.net --
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 ///