# HG changeset patch # User Bram Moolenaar # Date 1639773003 -3600 # Node ID bdf11d8e3df3096b9d2153f2f15c85b8d97a7059 # Parent f9400763802637e7076b53d8485971865399cbb3 patch 8.2.3841: Vim9: outdated TODO items, disabled tests that work Commit: https://github.com/vim/vim/commit/71b768509250b12696e8cc90e5902029f1b5433d Author: Bram Moolenaar Date: Fri Dec 17 20:15:38 2021 +0000 patch 8.2.3841: Vim9: outdated TODO items, disabled tests that work Problem: Vim9: outdated TODO items, disabled tests that work. Solution: Remove TODO items, run tests that work now. Check that a dict item isn't locked. diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -105,6 +105,8 @@ EXTERN char e_corrupted_regexp_program[] EXTERN char e_readonly_option_is_set_add_bang_to_override[] INIT(= N_("E45: 'readonly' option is set (add ! to override)")); #ifdef FEAT_EVAL +EXTERN char e_cannot_change_readonly_variable[] + INIT(= N_("E46: Cannot change read-only variable")); EXTERN char e_cannot_change_readonly_variable_str[] INIT(= N_("E46: Cannot change read-only variable \"%s\"")); #endif @@ -290,6 +292,22 @@ EXTERN char e_list_value_does_not_have_e INIT(= N_("E711: List value does not have enough items")); EXTERN char e_cannot_slice_dictionary[] INIT(= N_("E719: Cannot slice a Dictionary")); +EXTERN char e_value_is_locked[] + INIT(= N_("E741: Value is locked")); +EXTERN char e_value_is_locked_str[] + INIT(= N_("E741: Value is locked: %s")); +EXTERN char e_cannot_change_value[] + INIT(= N_("E742: Cannot change value")); +EXTERN char e_cannot_change_value_of_str[] + INIT(= N_("E742: Cannot change value of %s")); +EXTERN char e_cannot_set_variable_in_sandbox[] + INIT(= N_("E794: Cannot set variable in the sandbox")); +EXTERN char e_cannot_set_variable_in_sandbox_str[] + INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\"")); +EXTERN char e_cannot_delete_variable[] + INIT(= N_("E795: Cannot delete variable")); +EXTERN char e_cannot_delete_variable_str[] + INIT(= N_("E795: Cannot delete variable %s")); #endif EXTERN char e_conflicts_with_value_of_listchars[] INIT(= N_("E834: Conflicts with value of 'listchars'")); diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -2314,7 +2314,7 @@ set_vim_var_tv(int idx, typval_T *tv) } if (sandbox && (vimvars[idx].vv_flags & VV_RO_SBX)) { - semsg(_(e_readonlysbx), vimvars[idx].vv_name); + semsg(_(e_cannot_set_variable_in_sandbox_str), vimvars[idx].vv_name); return FAIL; } clear_tv(&vimvars[idx].vv_di.di_tv); @@ -3610,13 +3610,20 @@ var_check_ro(int flags, char_u *name, in { if (flags & DI_FLAGS_RO) { - semsg(_(e_cannot_change_readonly_variable_str), + if (name == NULL) + emsg(_(e_cannot_change_readonly_variable)); + else + semsg(_(e_cannot_change_readonly_variable_str), use_gettext ? (char_u *)_(name) : name); return TRUE; } if ((flags & DI_FLAGS_RO_SBX) && sandbox) { - semsg(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name); + if (name == NULL) + emsg(_(e_cannot_set_variable_in_sandbox)); + else + semsg(_(e_cannot_set_variable_in_sandbox_str), + use_gettext ? (char_u *)_(name) : name); return TRUE; } return FALSE; @@ -3647,7 +3654,10 @@ var_check_fixed(int flags, char_u *name, { if (flags & DI_FLAGS_FIX) { - semsg(_("E795: Cannot delete variable %s"), + if (name == NULL) + emsg(_(e_cannot_delete_variable)); + else + semsg(_(e_cannot_delete_variable_str), use_gettext ? (char_u *)_(name) : name); return TRUE; } @@ -3696,18 +3706,20 @@ value_check_lock(int lock, char_u *name, { if (lock & VAR_LOCKED) { - semsg(_("E741: Value is locked: %s"), - name == NULL ? (char_u *)_("Unknown") - : use_gettext ? (char_u *)_(name) - : name); + if (name == NULL) + emsg(_(e_value_is_locked)); + else + semsg(_(e_value_is_locked_str), + use_gettext ? (char_u *)_(name) : name); return TRUE; } if (lock & VAR_FIXED) { - semsg(_("E742: Cannot change value of %s"), - name == NULL ? (char_u *)_("Unknown") - : use_gettext ? (char_u *)_(name) - : name); + if (name == NULL) + emsg(_(e_cannot_change_value)); + else + semsg(_(e_cannot_change_value_of_str), + use_gettext ? (char_u *)_(name) : name); return TRUE; } return FALSE; diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -1680,7 +1680,6 @@ EXTERN char e_loclist[] INIT(= N_("E776 EXTERN char e_letwrong[] INIT(= N_("E734: Wrong variable type for %s=")); EXTERN char e_illvar[] INIT(= N_("E461: Illegal variable name: %s")); EXTERN char e_cannot_mod[] INIT(= N_("E995: Cannot modify existing variable")); -EXTERN char e_readonlysbx[] INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\"")); EXTERN char e_stringreq[] INIT(= N_("E928: String required")); EXTERN char e_numberreq[] INIT(= N_("E889: Number required")); EXTERN char e_boolreq[] INIT(= N_("E839: Bool required")); diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -743,10 +743,7 @@ func Test_dict_item_lock_unlet() unlet d.a call assert_equal({'b': 100}, d) END - " TODO: make this work in a :def function - "call CheckLegacyAndVim9Success(lines) - call CheckTransLegacySuccess(lines) - call CheckTransVim9Success(lines) + call CheckLegacyAndVim9Success(lines) endfunc " filter() after lock on dict item @@ -757,10 +754,7 @@ func Test_dict_lock_filter() call filter(d, 'v:key != "a"') call assert_equal({'b': 100}, d) END - " TODO: make this work in a :def function - "call CheckLegacyAndVim9Success(lines) - call CheckTransLegacySuccess(lines) - call CheckTransVim9Success(lines) + call CheckLegacyAndVim9Success(lines) endfunc " map() after lock on dict @@ -774,6 +768,17 @@ func Test_dict_lock_map() " This won't work in a :def function call CheckTransLegacySuccess(lines) call CheckTransVim9Success(lines) + + " For a :def function use a global dict. + let lines =<< trim END + let g:thedict = {'a': 77, 'b': 88} + lockvar 1 g:thedict + def Delkey() + unlet g:thedict.a + enddef + call Delkey() + END + call CheckScriptFailure(lines, 'E741:') endfunc " No extend() after lock on dict item diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -2017,6 +2017,22 @@ def Test_unlet() 'defcompile', ], 'E1081:') + CheckScriptFailure([ + 'vim9script', + 'def Delcount(dict: dict)', + ' unlet dict.count', + 'enddef', + 'Delcount(v:)', + ], 'E742:') + + CheckScriptFailure([ + 'vim9script', + 'def DelChangedtick(dict: dict)', + ' unlet dict.changedtick', + 'enddef', + 'DelChangedtick(b:)', + ], 'E795:') + writefile(['vim9script', 'export var svar = 1234'], 'XunletExport.vim') var lines =<< trim END vim9script diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3841, +/**/ 3840, /**/ 3839, diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -915,7 +915,6 @@ call_ufunc( // The function has been compiled, can call it quickly. For a function // that was defined later: we can call it directly next time. - // TODO: what if the function was deleted and then defined again? if (iptr != NULL) { delete_instr(iptr); @@ -933,7 +932,6 @@ call_ufunc( funcexe.fe_selfdict = selfdict != NULL ? selfdict : dict_stack_get_dict(); // Call the user function. Result goes in last position on the stack. - // TODO: add selfdict if there is one error = call_user_func_check(ufunc, argcount, argvars, STACK_TV_BOT(-1), &funcexe, funcexe.fe_selfdict); @@ -2862,21 +2860,29 @@ exec_instructions(ectx_T *ectx) char_u *key = tv_idx->vval.v_string; dictitem_T *di = NULL; - if (key == NULL) - key = (char_u *)""; - if (d != NULL) - di = dict_find(d, key, (int)STRLEN(key)); - if (di == NULL) - { - // NULL dict is equivalent to empty dict - SOURCING_LNUM = iptr->isn_lnum; - semsg(_(e_dictkey), key); + if (d != NULL && value_check_lock( + d->dv_lock, NULL, FALSE)) status = FAIL; - } else { - // TODO: check for dict or item locked - dictitem_remove(d, di); + SOURCING_LNUM = iptr->isn_lnum; + if (key == NULL) + key = (char_u *)""; + if (d != NULL) + di = dict_find(d, key, (int)STRLEN(key)); + if (di == NULL) + { + // NULL dict is equivalent to empty dict + semsg(_(e_dictkey), key); + status = FAIL; + } + else if (var_check_fixed(di->di_flags, + NULL, FALSE) + || var_check_ro(di->di_flags, + NULL, FALSE)) + status = FAIL; + else + dictitem_remove(d, di); } } }