diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 2 | ||||
-rw-r--r-- | src/evalvars.c | 51 | ||||
-rw-r--r-- | src/ex_docmd.c | 1 | ||||
-rw-r--r-- | src/proto/vim9script.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_cmd.vim | 17 | ||||
-rw-r--r-- | src/userfunc.c | 2 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9script.c | 8 |
8 files changed, 62 insertions, 23 deletions
diff --git a/src/eval.c b/src/eval.c index 2cde64216..b30577fec 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1065,7 +1065,7 @@ get_lval( && lp->ll_tv == &v->di_tv && ht != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(lp->ll_tv, 0); + svar_T *sv = find_typval_in_script(lp->ll_tv, 0, TRUE); // Vim9 script local variable: get the type if (sv != NULL) diff --git a/src/evalvars.c b/src/evalvars.c index dd70427d3..c1ec5b0ba 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1951,23 +1951,42 @@ do_lock_var( lp->ll_name); ret = FAIL; } - else if ((di->di_flags & DI_FLAGS_FIX) - && di->di_tv.v_type != VAR_DICT - && di->di_tv.v_type != VAR_LIST) - { - // For historic reasons this error is not given for a list or - // dict. E.g., the b: dict could be locked/unlocked. - semsg(_(e_cannot_lock_or_unlock_variable_str), lp->ll_name); - ret = FAIL; - } else { - if (lock) - di->di_flags |= DI_FLAGS_LOCK; + if ((di->di_flags & DI_FLAGS_FIX) + && di->di_tv.v_type != VAR_DICT + && di->di_tv.v_type != VAR_LIST) + { + // For historic reasons this error is not given for a list + // or dict. E.g., the b: dict could be locked/unlocked. + semsg(_(e_cannot_lock_or_unlock_variable_str), lp->ll_name); + ret = FAIL; + } else - di->di_flags &= ~DI_FLAGS_LOCK; - if (deep != 0) - item_lock(&di->di_tv, deep, lock, FALSE); + { + if (in_vim9script()) + { + svar_T *sv = find_typval_in_script(&di->di_tv, + 0, FALSE); + + if (sv != NULL && sv->sv_const != 0) + { + semsg(_(e_cannot_change_readonly_variable_str), + lp->ll_name); + ret = FAIL; + } + } + + if (ret == OK) + { + if (lock) + di->di_flags |= DI_FLAGS_LOCK; + else + di->di_flags &= ~DI_FLAGS_LOCK; + if (deep != 0) + item_lock(&di->di_tv, deep, lock, FALSE); + } + } } } *name_end = cc; @@ -2812,7 +2831,7 @@ eval_variable( if (ht != NULL && ht == get_script_local_ht() && tv != &SCRIPT_SV(current_sctx.sc_sid)->sv_var.di_tv) { - svar_T *sv = find_typval_in_script(tv, 0); + svar_T *sv = find_typval_in_script(tv, 0, TRUE); if (sv != NULL) type = sv->sv_type; @@ -3557,7 +3576,7 @@ set_var_const( if (var_in_vim9script && (flags & ASSIGN_FOR_LOOP) == 0) { where_T where = WHERE_INIT; - svar_T *sv = find_typval_in_script(&di->di_tv, sid); + svar_T *sv = find_typval_in_script(&di->di_tv, sid, TRUE); if (sv != NULL) { diff --git a/src/ex_docmd.c b/src/ex_docmd.c index c12f151c3..2d5752445 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -303,7 +303,6 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name); # define ex_throw ex_ni # define ex_try ex_ni # define ex_unlet ex_ni -# define ex_unlockvar ex_ni # define ex_while ex_ni # define ex_import ex_ni # define ex_export ex_ni diff --git a/src/proto/vim9script.pro b/src/proto/vim9script.pro index bc1e23275..04c07fc32 100644 --- a/src/proto/vim9script.pro +++ b/src/proto/vim9script.pro @@ -16,7 +16,7 @@ int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, cctx_T char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg); void update_vim9_script_var(int create, dictitem_T *di, char_u *name, int flags, typval_T *tv, type_T **type, int do_member); void hide_script_var(scriptitem_T *si, int idx, int func_defined); -svar_T *find_typval_in_script(typval_T *dest, scid_T sid); +svar_T *find_typval_in_script(typval_T *dest, scid_T sid, int must_find); int check_script_var_type(svar_T *sv, typval_T *value, char_u *name, where_T where); int check_reserved_name(char_u *name); /* vim: set ft=c : */ diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index 8dea71d5f..49ca29b67 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -1650,6 +1650,23 @@ def Test_lockvar() LockIt() END v9.CheckScriptFailure(lines, 'E1246', 1) + + lines =<< trim END + vim9script + const name = 'john' + unlockvar name + END + v9.CheckScriptFailure(lines, 'E46', 3) + + lines =<< trim END + vim9script + const name = 'john' + def UnLockIt() + unlockvar name + enddef + UnLockIt() + END + v9.CheckScriptFailure(lines, 'E46', 1) enddef def Test_substitute_expr() diff --git a/src/userfunc.c b/src/userfunc.c index 052923e94..c80a49051 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1697,7 +1697,7 @@ deref_func_name( { if (!did_type && type != NULL && ht == get_script_local_ht()) { - svar_T *sv = find_typval_in_script(tv, 0); + svar_T *sv = find_typval_in_script(tv, 0, TRUE); if (sv != NULL) *type = sv->sv_type; diff --git a/src/version.c b/src/version.c index 79a3bad67..8b7450c66 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4682, +/**/ 4681, /**/ 4680, diff --git a/src/vim9script.c b/src/vim9script.c index cd9ff92cd..adb01e8b9 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -956,7 +956,7 @@ update_vim9_script_var( } else { - sv = find_typval_in_script(&di->di_tv, 0); + sv = find_typval_in_script(&di->di_tv, 0, TRUE); } if (sv != NULL) { @@ -1053,10 +1053,11 @@ hide_script_var(scriptitem_T *si, int idx, int func_defined) /* * Find the script-local variable that links to "dest". * If "sid" is zero use the current script. + * if "must_find" is TRUE and "dest" cannot be found report an internal error. * Returns NULL if not found and give an internal error. */ svar_T * -find_typval_in_script(typval_T *dest, scid_T sid) +find_typval_in_script(typval_T *dest, scid_T sid, int must_find) { scriptitem_T *si = SCRIPT_ITEM(sid == 0 ? current_sctx.sc_sid : sid); int idx; @@ -1076,7 +1077,8 @@ find_typval_in_script(typval_T *dest, scid_T sid) if (sv->sv_name != NULL && sv->sv_tv == dest) return sv; } - iemsg("find_typval_in_script(): not found"); + if (must_find) + iemsg("find_typval_in_script(): not found"); return NULL; } |