changeset 26624:bdf11d8e3df3 v8.2.3841

patch 8.2.3841: Vim9: outdated TODO items, disabled tests that work Commit: https://github.com/vim/vim/commit/71b768509250b12696e8cc90e5902029f1b5433d Author: Bram Moolenaar <Bram@vim.org> 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.
author Bram Moolenaar <Bram@vim.org>
date Fri, 17 Dec 2021 21:30:03 +0100
parents f94007638026
children 05e524ae9236
files src/errors.h src/evalvars.c src/globals.h src/testdir/test_listdict.vim src/testdir/test_vim9_assign.vim src/version.c src/vim9execute.c
diffstat 7 files changed, 93 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- 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'"));
--- 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;
--- 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"));
--- 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
--- 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<any>)',
+   '  unlet dict.count',
+   'enddef',
+   'Delcount(v:)',
+   ], 'E742:')
+
+  CheckScriptFailure([
+   'vim9script',
+   'def DelChangedtick(dict: dict<any>)',
+   '  unlet dict.changedtick',
+   'enddef',
+   'DelChangedtick(b:)',
+   ], 'E795:')
+
   writefile(['vim9script', 'export var svar = 1234'], 'XunletExport.vim')
   var lines =<< trim END
     vim9script
--- 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,
--- 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);
 			    }
 			}
 		    }