mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.3997: Vim9: not enough testing for extend() and map()
Problem: Vim9: not enough testing for extend() and map(). Solution: Add more test cases. Fix uncovered problems. Remove unused type fields.
This commit is contained in:
parent
078a46161e
commit
10d6f18b2f
@ -109,8 +109,6 @@ dict_free_contents(dict_T *d)
|
|||||||
hashtab_free_contents(&d->dv_hashtab);
|
hashtab_free_contents(&d->dv_hashtab);
|
||||||
free_type(d->dv_type);
|
free_type(d->dv_type);
|
||||||
d->dv_type = NULL;
|
d->dv_type = NULL;
|
||||||
free_type(d->dv_decl_type);
|
|
||||||
d->dv_decl_type = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -271,7 +271,6 @@ list_free_list(list_T *l)
|
|||||||
l->lv_used_next->lv_used_prev = l->lv_used_prev;
|
l->lv_used_next->lv_used_prev = l->lv_used_prev;
|
||||||
|
|
||||||
free_type(l->lv_type);
|
free_type(l->lv_type);
|
||||||
free_type(l->lv_decl_type);
|
|
||||||
vim_free(l);
|
vim_free(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1026,8 +1025,6 @@ flatten_common(typval_T *argvars, typval_T *rettv, int make_copy)
|
|||||||
// The type will change.
|
// The type will change.
|
||||||
free_type(l->lv_type);
|
free_type(l->lv_type);
|
||||||
l->lv_type = NULL;
|
l->lv_type = NULL;
|
||||||
free_type(l->lv_decl_type);
|
|
||||||
l->lv_decl_type = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1223,7 +1220,6 @@ list_copy(list_T *orig, int deep, int copyID)
|
|||||||
if (copy != NULL)
|
if (copy != NULL)
|
||||||
{
|
{
|
||||||
copy->lv_type = alloc_type(orig->lv_type);
|
copy->lv_type = alloc_type(orig->lv_type);
|
||||||
copy->lv_decl_type = alloc_type(orig->lv_decl_type);
|
|
||||||
if (copyID != 0)
|
if (copyID != 0)
|
||||||
{
|
{
|
||||||
// Do this before adding the items, because one of the items may
|
// Do this before adding the items, because one of the items may
|
||||||
|
@ -1513,7 +1513,6 @@ struct listvar_S
|
|||||||
} mat;
|
} mat;
|
||||||
} lv_u;
|
} lv_u;
|
||||||
type_T *lv_type; // current type, allocated by alloc_type()
|
type_T *lv_type; // current type, allocated by alloc_type()
|
||||||
type_T *lv_decl_type; // declared type, allocated by alloc_type()
|
|
||||||
list_T *lv_copylist; // copied list used by deepcopy()
|
list_T *lv_copylist; // copied list used by deepcopy()
|
||||||
list_T *lv_used_next; // next list in used lists list
|
list_T *lv_used_next; // next list in used lists list
|
||||||
list_T *lv_used_prev; // previous list in used lists list
|
list_T *lv_used_prev; // previous list in used lists list
|
||||||
@ -1578,7 +1577,6 @@ struct dictvar_S
|
|||||||
int dv_copyID; // ID used by deepcopy()
|
int dv_copyID; // ID used by deepcopy()
|
||||||
hashtab_T dv_hashtab; // hashtab that refers to the items
|
hashtab_T dv_hashtab; // hashtab that refers to the items
|
||||||
type_T *dv_type; // current type, allocated by alloc_type()
|
type_T *dv_type; // current type, allocated by alloc_type()
|
||||||
type_T *dv_decl_type; // declared type, allocated by alloc_type()
|
|
||||||
dict_T *dv_copydict; // copied dict used by deepcopy()
|
dict_T *dv_copydict; // copied dict used by deepcopy()
|
||||||
dict_T *dv_used_next; // next dict in used dicts list
|
dict_T *dv_used_next; // next dict in used dicts list
|
||||||
dict_T *dv_used_prev; // previous dict in used dicts list
|
dict_T *dv_used_prev; // previous dict in used dicts list
|
||||||
|
@ -979,6 +979,10 @@ def Test_extend_arg_types()
|
|||||||
var res: list<dict<any>>
|
var res: list<dict<any>>
|
||||||
extend(res, mapnew([1, 2], (_, v) => ({})))
|
extend(res, mapnew([1, 2], (_, v) => ({})))
|
||||||
assert_equal([{}, {}], res)
|
assert_equal([{}, {}], res)
|
||||||
|
|
||||||
|
var dany: dict<any> = {a: 0}
|
||||||
|
dany->extend({b: 'x'})
|
||||||
|
assert_equal({a: 0, b: 'x'}, dany)
|
||||||
END
|
END
|
||||||
CheckDefAndScriptSuccess(lines)
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
@ -2151,9 +2155,29 @@ def Test_map()
|
|||||||
CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
|
CheckDefAndScriptFailure(['map(1, "1")'], ['E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1251: List, Dictionary, Blob or String required for argument 1'])
|
||||||
|
|
||||||
# type of dict remains dict<any> even when type of values changes
|
# type of dict remains dict<any> even when type of values changes
|
||||||
|
# same for list
|
||||||
|
var lines =<< trim END
|
||||||
var d: dict<any> = {a: 0}
|
var d: dict<any> = {a: 0}
|
||||||
d->map((k, v) => true)
|
d->map((k, v) => true)
|
||||||
d->map((k, v) => 'x')
|
d->map((k, v) => 'x')
|
||||||
|
assert_equal({a: 'x'}, d)
|
||||||
|
|
||||||
|
d = {a: 0}
|
||||||
|
g:gd = d
|
||||||
|
map(g:gd, (k, v) => true)
|
||||||
|
assert_equal({a: true}, g:gd)
|
||||||
|
|
||||||
|
var l: list<any> = [0]
|
||||||
|
l->map((k, v) => true)
|
||||||
|
l->map((k, v) => 'x')
|
||||||
|
assert_equal(['x'], l)
|
||||||
|
|
||||||
|
l = [1]
|
||||||
|
g:gl = l
|
||||||
|
map(g:gl, (k, v) => true)
|
||||||
|
assert_equal([true], g:gl)
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_map_failure()
|
def Test_map_failure()
|
||||||
@ -2175,6 +2199,13 @@ def Test_map_failure()
|
|||||||
CheckScriptFailure(lines, 'E1013:')
|
CheckScriptFailure(lines, 'E1013:')
|
||||||
au! BufReadPost
|
au! BufReadPost
|
||||||
delete('Xtmpfile')
|
delete('Xtmpfile')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var d: dict<number> = {a: 1}
|
||||||
|
g:gd = d
|
||||||
|
map(g:gd, (k, v) => true)
|
||||||
|
END
|
||||||
|
CheckDefExecAndScriptFailure(lines, 'E1012: Type mismatch; expected number but got bool')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_map_function_arg()
|
def Test_map_function_arg()
|
||||||
|
@ -455,6 +455,7 @@ def Test_disassemble_list_assign()
|
|||||||
'\d\+ CHECKTYPE string stack\[-1\] arg 2\_s*' ..
|
'\d\+ CHECKTYPE string stack\[-1\] arg 2\_s*' ..
|
||||||
'\d\+ STORE $1\_s*' ..
|
'\d\+ STORE $1\_s*' ..
|
||||||
'\d\+ SLICE 2\_s*' ..
|
'\d\+ SLICE 2\_s*' ..
|
||||||
|
'\d\+ SETTYPE list<any>\_s*' ..
|
||||||
'\d\+ STORE $2\_s*' ..
|
'\d\+ STORE $2\_s*' ..
|
||||||
'\d\+ RETURN void',
|
'\d\+ RETURN void',
|
||||||
res)
|
res)
|
||||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3997,
|
||||||
/**/
|
/**/
|
||||||
3996,
|
3996,
|
||||||
/**/
|
/**/
|
||||||
|
@ -2279,14 +2279,12 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
// ":const var": lock the value, but not referenced variables
|
// ":const var": lock the value, but not referenced variables
|
||||||
generate_LOCKCONST(cctx);
|
generate_LOCKCONST(cctx);
|
||||||
|
|
||||||
if (is_decl
|
if ((lhs.lhs_type->tt_type == VAR_DICT
|
||||||
&& (lhs.lhs_type->tt_type == VAR_DICT
|
|
||||||
|| lhs.lhs_type->tt_type == VAR_LIST)
|
|| lhs.lhs_type->tt_type == VAR_LIST)
|
||||||
&& lhs.lhs_type->tt_member != NULL
|
&& lhs.lhs_type->tt_member != NULL
|
||||||
&& lhs.lhs_type->tt_member != &t_unknown)
|
&& lhs.lhs_type->tt_member != &t_unknown)
|
||||||
// Set the type in the list or dict, so that it can be checked,
|
// Set the type in the list or dict, so that it can be checked,
|
||||||
// also in legacy script. Not for "list<any> = val", then the
|
// also in legacy script.
|
||||||
// type of "val" is used.
|
|
||||||
generate_SETTYPE(cctx, lhs.lhs_type);
|
generate_SETTYPE(cctx, lhs.lhs_type);
|
||||||
|
|
||||||
if (!skip_store && generate_store_lhs(cctx, &lhs,
|
if (!skip_store && generate_store_lhs(cctx, &lhs,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user