Skip to content

Commit

Permalink
patch 8.2.4407: Vim9: some code not covered by tests
Browse files Browse the repository at this point in the history
Problem:    Vim9: some code not covered by tests.
Solution:   Add more tests.  Avoid giving two errors.  Remove dead code.
  • Loading branch information
brammool committed Feb 17, 2022
1 parent 2438430 commit e08be09
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 99 deletions.
53 changes: 53 additions & 0 deletions src/testdir/test_vim9_assign.vim
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,13 @@ def Test_assign_index()
d3.one.two.three = 123
assert_equal({one: {two: {three: 123}}}, d3)

# blob
var bl: blob = 0z11223344
bl[0] = 0x77
assert_equal(0z77223344, bl)
bl[-2] = 0x66
assert_equal(0z77226644, bl)

# should not read the next line when generating "a.b"
var a = {}
a.b = {}
Expand Down Expand Up @@ -591,6 +598,18 @@ def Test_assign_index()
dl.one = {}
END
v9.CheckDefFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<unknown>', 2)

lines =<< trim END
g:l = [1, 2]
g:l['x'] = 3
END
v9.CheckDefExecAndScriptFailure(lines, ['E39:', 'E1030:'], 2)

lines =<< trim END
var bl: blob = test_null_blob()
bl[1] = 8
END
v9.CheckDefExecAndScriptFailure(lines, ['E1184:', 'E979:'], 2)
enddef

def Test_init_in_for_loop()
Expand Down Expand Up @@ -1201,6 +1220,21 @@ def Test_assignment_default()
assert_equal(5678, nr)
enddef

def Test_script_var_default()
var lines =<< trim END
vim9script
var l: list<number>
var bl: blob
var d: dict<number>
def Echo()
assert_equal([], l)
assert_equal(0z, bl)
assert_equal({}, d)
enddef
END
v9.CheckScriptSuccess(lines)
enddef

let s:scriptvar = 'init'

def Test_assignment_var_list()
Expand Down Expand Up @@ -2082,6 +2116,25 @@ def Test_unlet()
'var ll = [1, 2]',
'unlet ll[0: 1]',
], 'E1004:', 2)

v9.CheckDefExecFailure([
'g:ll = [1, 2]',
'g:idx = "x"',
'unlet g:ll[g:idx]',
], 'E1029: Expected number but got string', 3)

v9.CheckDefExecFailure([
'g:ll = [1, 2, 3]',
'g:idx = "x"',
'unlet g:ll[g:idx : 2]',
], 'E1029: Expected number but got string', 3)

v9.CheckDefExecFailure([
'g:ll = [1, 2, 3]',
'g:idx = "x"',
'unlet g:ll[0 : g:idx]',
], 'E1029: Expected number but got string', 3)

# command recognized as assignment when skipping, should not give an error
v9.CheckScriptSuccess([
'vim9script',
Expand Down
11 changes: 11 additions & 0 deletions src/testdir/test_vim9_cmd.vim
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,17 @@ def Test_lockvar()
assert_equal({a: 7, b: 5}, d)

var lines =<< trim END
vim9script
g:bl = 0z1122
lockvar g:bl
def Tryit()
g:bl[1] = 99
enddef
Tryit()
END
v9.CheckScriptFailure(lines, 'E741:', 1)

lines =<< trim END
vim9script
var theList = [1, 2, 3]
def SetList()
Expand Down
8 changes: 8 additions & 0 deletions src/testdir/test_vim9_func.vim
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,14 @@ def Test_nested_def_list()
v9.CheckScriptFailure(lines, 'E476:', 1)
enddef

def Test_global_function_not_found()
var lines =<< trim END
g:Ref = 123
call g:Ref()
END
v9.CheckDefExecAndScriptFailure(lines, ['E117:', 'E1085:'], 2)
enddef

def Test_global_local_function()
var lines =<< trim END
vim9script
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4407,
/**/
4406,
/**/
Expand Down
194 changes: 95 additions & 99 deletions src/vim9execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1750,122 +1750,118 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
status = FAIL;
}
}
else if (dest_type != tv_dest->v_type)
{
// just in case, should be OK
semsg(_(e_expected_str_but_got_str),
vartype_name(dest_type),
vartype_name(tv_dest->v_type));
status = FAIL;
}

if (status == OK && dest_type == VAR_LIST)
if (status == OK)
{
long lidx = (long)tv_idx->vval.v_number;
list_T *list = tv_dest->vval.v_list;

if (list == NULL)
if (dest_type == VAR_LIST)
{
emsg(_(e_list_not_set));
return FAIL;
}
if (lidx < 0 && list->lv_len + lidx >= 0)
// negative index is relative to the end
lidx = list->lv_len + lidx;
if (lidx < 0 || lidx > list->lv_len)
{
semsg(_(e_list_index_out_of_range_nr), lidx);
return FAIL;
}
if (lidx < list->lv_len)
{
listitem_T *li = list_find(list, lidx);
long lidx = (long)tv_idx->vval.v_number;
list_T *list = tv_dest->vval.v_list;

if (error_if_locked(li->li_tv.v_lock,
e_cannot_change_locked_list_item))
if (list == NULL)
{
emsg(_(e_list_not_set));
return FAIL;
// overwrite existing list item
clear_tv(&li->li_tv);
li->li_tv = *tv;
}
else
{
if (error_if_locked(list->lv_lock, e_cannot_change_locked_list))
}
if (lidx < 0 && list->lv_len + lidx >= 0)
// negative index is relative to the end
lidx = list->lv_len + lidx;
if (lidx < 0 || lidx > list->lv_len)
{
semsg(_(e_list_index_out_of_range_nr), lidx);
return FAIL;
// append to list, only fails when out of memory
if (list_append_tv(list, tv) == FAIL)
return NOTDONE;
clear_tv(tv);
}
}
else if (status == OK && dest_type == VAR_DICT)
{
char_u *key = tv_idx->vval.v_string;
dict_T *dict = tv_dest->vval.v_dict;
dictitem_T *di;
}
if (lidx < list->lv_len)
{
listitem_T *li = list_find(list, lidx);

SOURCING_LNUM = iptr->isn_lnum;
if (dict == NULL)
{
emsg(_(e_dictionary_not_set));
return FAIL;
if (error_if_locked(li->li_tv.v_lock,
e_cannot_change_locked_list_item))
return FAIL;
// overwrite existing list item
clear_tv(&li->li_tv);
li->li_tv = *tv;
}
else
{
if (error_if_locked(list->lv_lock, e_cannot_change_locked_list))
return FAIL;
// append to list, only fails when out of memory
if (list_append_tv(list, tv) == FAIL)
return NOTDONE;
clear_tv(tv);
}
}
if (key == NULL)
key = (char_u *)"";
di = dict_find(dict, key, -1);
if (di != NULL)
else if (dest_type == VAR_DICT)
{
if (error_if_locked(di->di_tv.v_lock, e_cannot_change_dict_item))
char_u *key = tv_idx->vval.v_string;
dict_T *dict = tv_dest->vval.v_dict;
dictitem_T *di;

SOURCING_LNUM = iptr->isn_lnum;
if (dict == NULL)
{
emsg(_(e_dictionary_not_set));
return FAIL;
// overwrite existing value
clear_tv(&di->di_tv);
di->di_tv = *tv;
}
if (key == NULL)
key = (char_u *)"";
di = dict_find(dict, key, -1);
if (di != NULL)
{
if (error_if_locked(di->di_tv.v_lock,
e_cannot_change_dict_item))
return FAIL;
// overwrite existing value
clear_tv(&di->di_tv);
di->di_tv = *tv;
}
else
{
if (error_if_locked(dict->dv_lock, e_cannot_change_dict))
return FAIL;
// add to dict, only fails when out of memory
if (dict_add_tv(dict, (char *)key, tv) == FAIL)
return NOTDONE;
clear_tv(tv);
}
}
else
else if (dest_type == VAR_BLOB)
{
if (error_if_locked(dict->dv_lock, e_cannot_change_dict))
long lidx = (long)tv_idx->vval.v_number;
blob_T *blob = tv_dest->vval.v_blob;
varnumber_T nr;
int error = FALSE;
int len;

if (blob == NULL)
{
emsg(_(e_blob_not_set));
return FAIL;
// add to dict, only fails when out of memory
if (dict_add_tv(dict, (char *)key, tv) == FAIL)
return NOTDONE;
clear_tv(tv);
}
}
else if (status == OK && dest_type == VAR_BLOB)
{
long lidx = (long)tv_idx->vval.v_number;
blob_T *blob = tv_dest->vval.v_blob;
varnumber_T nr;
int error = FALSE;
int len;
}
len = blob_len(blob);
if (lidx < 0 && len + lidx >= 0)
// negative index is relative to the end
lidx = len + lidx;

if (blob == NULL)
{
emsg(_(e_blob_not_set));
return FAIL;
// Can add one byte at the end.
if (lidx < 0 || lidx > len)
{
semsg(_(e_blob_index_out_of_range_nr), lidx);
return FAIL;
}
if (value_check_lock(blob->bv_lock, (char_u *)"blob", FALSE))
return FAIL;
nr = tv_get_number_chk(tv, &error);
if (error)
return FAIL;
blob_set_append(blob, lidx, nr);
}
len = blob_len(blob);
if (lidx < 0 && len + lidx >= 0)
// negative index is relative to the end
lidx = len + lidx;

// Can add one byte at the end.
if (lidx < 0 || lidx > len)
else
{
semsg(_(e_blob_index_out_of_range_nr), lidx);
return FAIL;
status = FAIL;
semsg(_(e_cannot_index_str), vartype_name(dest_type));
}
if (value_check_lock(blob->bv_lock, (char_u *)"blob", FALSE))
return FAIL;
nr = tv_get_number_chk(tv, &error);
if (error)
return FAIL;
blob_set_append(blob, lidx, nr);
}
else
{
status = FAIL;
semsg(_(e_cannot_index_str), vartype_name(dest_type));
}

clear_tv(tv_idx);
Expand Down

0 comments on commit e08be09

Please sign in to comment.