forked from aniani/vim
patch 8.2.3890: Vim9: type check for using v: variables is basic
Problem: Vim9: type check for using v: variables is basic. Solution: Specify a more precise type.
This commit is contained in:
235
src/evalvars.c
235
src/evalvars.c
@@ -45,118 +45,119 @@ static struct vimvar
|
|||||||
{
|
{
|
||||||
char *vv_name; // name of variable, without v:
|
char *vv_name; // name of variable, without v:
|
||||||
dictitem16_T vv_di; // value and name for key (max 16 chars!)
|
dictitem16_T vv_di; // value and name for key (max 16 chars!)
|
||||||
|
type_T *vv_type; // type or NULL
|
||||||
char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX
|
char vv_flags; // VV_COMPAT, VV_RO, VV_RO_SBX
|
||||||
} vimvars[VV_LEN] =
|
} vimvars[VV_LEN] =
|
||||||
{
|
{
|
||||||
// The order here must match the VV_ defines in vim.h!
|
// The order here must match the VV_ defines in vim.h!
|
||||||
// Initializing a union does not work, leave tv.vval empty to get zero's.
|
// Initializing a union does not work, leave tv.vval empty to get zero's.
|
||||||
{VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO},
|
{VV_NAME("count", VAR_NUMBER), NULL, VV_COMPAT+VV_RO},
|
||||||
{VV_NAME("count1", VAR_NUMBER), VV_RO},
|
{VV_NAME("count1", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("prevcount", VAR_NUMBER), VV_RO},
|
{VV_NAME("prevcount", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("errmsg", VAR_STRING), VV_COMPAT},
|
{VV_NAME("errmsg", VAR_STRING), NULL, VV_COMPAT},
|
||||||
{VV_NAME("warningmsg", VAR_STRING), 0},
|
{VV_NAME("warningmsg", VAR_STRING), NULL, 0},
|
||||||
{VV_NAME("statusmsg", VAR_STRING), 0},
|
{VV_NAME("statusmsg", VAR_STRING), NULL, 0},
|
||||||
{VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO},
|
{VV_NAME("shell_error", VAR_NUMBER), NULL, VV_COMPAT+VV_RO},
|
||||||
{VV_NAME("this_session", VAR_STRING), VV_COMPAT},
|
{VV_NAME("this_session", VAR_STRING), NULL, VV_COMPAT},
|
||||||
{VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO},
|
{VV_NAME("version", VAR_NUMBER), NULL, VV_COMPAT+VV_RO},
|
||||||
{VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX},
|
{VV_NAME("lnum", VAR_NUMBER), NULL, VV_RO_SBX},
|
||||||
{VV_NAME("termresponse", VAR_STRING), VV_RO},
|
{VV_NAME("termresponse", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("fname", VAR_STRING), VV_RO},
|
{VV_NAME("fname", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("lang", VAR_STRING), VV_RO},
|
{VV_NAME("lang", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("lc_time", VAR_STRING), VV_RO},
|
{VV_NAME("lc_time", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("ctype", VAR_STRING), VV_RO},
|
{VV_NAME("ctype", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("charconvert_from", VAR_STRING), VV_RO},
|
{VV_NAME("charconvert_from", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("charconvert_to", VAR_STRING), VV_RO},
|
{VV_NAME("charconvert_to", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("fname_in", VAR_STRING), VV_RO},
|
{VV_NAME("fname_in", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("fname_out", VAR_STRING), VV_RO},
|
{VV_NAME("fname_out", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("fname_new", VAR_STRING), VV_RO},
|
{VV_NAME("fname_new", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("fname_diff", VAR_STRING), VV_RO},
|
{VV_NAME("fname_diff", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("cmdarg", VAR_STRING), VV_RO},
|
{VV_NAME("cmdarg", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX},
|
{VV_NAME("foldstart", VAR_NUMBER), NULL, VV_RO_SBX},
|
||||||
{VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX},
|
{VV_NAME("foldend", VAR_NUMBER), NULL, VV_RO_SBX},
|
||||||
{VV_NAME("folddashes", VAR_STRING), VV_RO_SBX},
|
{VV_NAME("folddashes", VAR_STRING), NULL, VV_RO_SBX},
|
||||||
{VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX},
|
{VV_NAME("foldlevel", VAR_NUMBER), NULL, VV_RO_SBX},
|
||||||
{VV_NAME("progname", VAR_STRING), VV_RO},
|
{VV_NAME("progname", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("servername", VAR_STRING), VV_RO},
|
{VV_NAME("servername", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("dying", VAR_NUMBER), VV_RO},
|
{VV_NAME("dying", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("exception", VAR_STRING), VV_RO},
|
{VV_NAME("exception", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("throwpoint", VAR_STRING), VV_RO},
|
{VV_NAME("throwpoint", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("register", VAR_STRING), VV_RO},
|
{VV_NAME("register", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("cmdbang", VAR_NUMBER), VV_RO},
|
{VV_NAME("cmdbang", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("insertmode", VAR_STRING), VV_RO},
|
{VV_NAME("insertmode", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("val", VAR_UNKNOWN), VV_RO},
|
{VV_NAME("val", VAR_UNKNOWN), NULL, VV_RO},
|
||||||
{VV_NAME("key", VAR_UNKNOWN), VV_RO},
|
{VV_NAME("key", VAR_UNKNOWN), NULL, VV_RO},
|
||||||
{VV_NAME("profiling", VAR_NUMBER), VV_RO},
|
{VV_NAME("profiling", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("fcs_reason", VAR_STRING), VV_RO},
|
{VV_NAME("fcs_reason", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("fcs_choice", VAR_STRING), 0},
|
{VV_NAME("fcs_choice", VAR_STRING), NULL, 0},
|
||||||
{VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO},
|
{VV_NAME("beval_bufnr", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("beval_winnr", VAR_NUMBER), VV_RO},
|
{VV_NAME("beval_winnr", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("beval_winid", VAR_NUMBER), VV_RO},
|
{VV_NAME("beval_winid", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("beval_lnum", VAR_NUMBER), VV_RO},
|
{VV_NAME("beval_lnum", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("beval_col", VAR_NUMBER), VV_RO},
|
{VV_NAME("beval_col", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("beval_text", VAR_STRING), VV_RO},
|
{VV_NAME("beval_text", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("scrollstart", VAR_STRING), 0},
|
{VV_NAME("scrollstart", VAR_STRING), NULL, 0},
|
||||||
{VV_NAME("swapname", VAR_STRING), VV_RO},
|
{VV_NAME("swapname", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("swapchoice", VAR_STRING), 0},
|
{VV_NAME("swapchoice", VAR_STRING), NULL, 0},
|
||||||
{VV_NAME("swapcommand", VAR_STRING), VV_RO},
|
{VV_NAME("swapcommand", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("char", VAR_STRING), 0},
|
{VV_NAME("char", VAR_STRING), NULL, 0},
|
||||||
{VV_NAME("mouse_win", VAR_NUMBER), 0},
|
{VV_NAME("mouse_win", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("mouse_winid", VAR_NUMBER), 0},
|
{VV_NAME("mouse_winid", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("mouse_lnum", VAR_NUMBER), 0},
|
{VV_NAME("mouse_lnum", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("mouse_col", VAR_NUMBER), 0},
|
{VV_NAME("mouse_col", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("operator", VAR_STRING), VV_RO},
|
{VV_NAME("operator", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("searchforward", VAR_NUMBER), 0},
|
{VV_NAME("searchforward", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("hlsearch", VAR_NUMBER), 0},
|
{VV_NAME("hlsearch", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("oldfiles", VAR_LIST), 0},
|
{VV_NAME("oldfiles", VAR_LIST), &t_list_string, 0},
|
||||||
{VV_NAME("windowid", VAR_NUMBER), VV_RO},
|
{VV_NAME("windowid", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("progpath", VAR_STRING), VV_RO},
|
{VV_NAME("progpath", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("completed_item", VAR_DICT), VV_RO},
|
{VV_NAME("completed_item", VAR_DICT), &t_dict_string, VV_RO},
|
||||||
{VV_NAME("option_new", VAR_STRING), VV_RO},
|
{VV_NAME("option_new", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("option_old", VAR_STRING), VV_RO},
|
{VV_NAME("option_old", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("option_oldlocal", VAR_STRING), VV_RO},
|
{VV_NAME("option_oldlocal", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("option_oldglobal", VAR_STRING), VV_RO},
|
{VV_NAME("option_oldglobal", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("option_command", VAR_STRING), VV_RO},
|
{VV_NAME("option_command", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("option_type", VAR_STRING), VV_RO},
|
{VV_NAME("option_type", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("errors", VAR_LIST), 0},
|
{VV_NAME("errors", VAR_LIST), &t_list_string, 0},
|
||||||
{VV_NAME("false", VAR_BOOL), VV_RO},
|
{VV_NAME("false", VAR_BOOL), NULL, VV_RO},
|
||||||
{VV_NAME("true", VAR_BOOL), VV_RO},
|
{VV_NAME("true", VAR_BOOL), NULL, VV_RO},
|
||||||
{VV_NAME("none", VAR_SPECIAL), VV_RO},
|
{VV_NAME("none", VAR_SPECIAL), NULL, VV_RO},
|
||||||
{VV_NAME("null", VAR_SPECIAL), VV_RO},
|
{VV_NAME("null", VAR_SPECIAL), NULL, VV_RO},
|
||||||
{VV_NAME("numbermax", VAR_NUMBER), VV_RO},
|
{VV_NAME("numbermax", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("numbermin", VAR_NUMBER), VV_RO},
|
{VV_NAME("numbermin", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("numbersize", VAR_NUMBER), VV_RO},
|
{VV_NAME("numbersize", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO},
|
{VV_NAME("vim_did_enter", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("testing", VAR_NUMBER), 0},
|
{VV_NAME("testing", VAR_NUMBER), NULL, 0},
|
||||||
{VV_NAME("t_number", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_number", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_string", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_string", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_func", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_func", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_list", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_list", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_dict", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_dict", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_float", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_float", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_bool", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_bool", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_none", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_none", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_job", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_job", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_channel", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_channel", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("t_blob", VAR_NUMBER), VV_RO},
|
{VV_NAME("t_blob", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("termrfgresp", VAR_STRING), VV_RO},
|
{VV_NAME("termrfgresp", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("termrbgresp", VAR_STRING), VV_RO},
|
{VV_NAME("termrbgresp", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("termu7resp", VAR_STRING), VV_RO},
|
{VV_NAME("termu7resp", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("termstyleresp", VAR_STRING), VV_RO},
|
{VV_NAME("termstyleresp", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("termblinkresp", VAR_STRING), VV_RO},
|
{VV_NAME("termblinkresp", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("event", VAR_DICT), VV_RO},
|
{VV_NAME("event", VAR_DICT), NULL, VV_RO},
|
||||||
{VV_NAME("versionlong", VAR_NUMBER), VV_RO},
|
{VV_NAME("versionlong", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("echospace", VAR_NUMBER), VV_RO},
|
{VV_NAME("echospace", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("argv", VAR_LIST), VV_RO},
|
{VV_NAME("argv", VAR_LIST), &t_list_string, VV_RO},
|
||||||
{VV_NAME("collate", VAR_STRING), VV_RO},
|
{VV_NAME("collate", VAR_STRING), NULL, VV_RO},
|
||||||
{VV_NAME("exiting", VAR_SPECIAL), VV_RO},
|
{VV_NAME("exiting", VAR_SPECIAL), NULL, VV_RO},
|
||||||
{VV_NAME("colornames", VAR_DICT), VV_RO},
|
{VV_NAME("colornames", VAR_DICT), &t_dict_string, VV_RO},
|
||||||
{VV_NAME("sizeofint", VAR_NUMBER), VV_RO},
|
{VV_NAME("sizeofint", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("sizeoflong", VAR_NUMBER), VV_RO},
|
{VV_NAME("sizeoflong", VAR_NUMBER), NULL, VV_RO},
|
||||||
{VV_NAME("sizeofpointer", VAR_NUMBER), VV_RO},
|
{VV_NAME("sizeofpointer", VAR_NUMBER), NULL, VV_RO},
|
||||||
};
|
};
|
||||||
|
|
||||||
// shorthand
|
// shorthand
|
||||||
#define vv_type vv_di.di_tv.v_type
|
#define vv_tv_type vv_di.di_tv.v_type
|
||||||
#define vv_nr vv_di.di_tv.vval.v_number
|
#define vv_nr vv_di.di_tv.vval.v_number
|
||||||
#define vv_float vv_di.di_tv.vval.v_float
|
#define vv_float vv_di.di_tv.vval.v_float
|
||||||
#define vv_str vv_di.di_tv.vval.v_string
|
#define vv_str vv_di.di_tv.vval.v_string
|
||||||
@@ -214,7 +215,7 @@ evalvars_init(void)
|
|||||||
p->vv_di.di_flags = DI_FLAGS_FIX;
|
p->vv_di.di_flags = DI_FLAGS_FIX;
|
||||||
|
|
||||||
// add to v: scope dict, unless the value is not always available
|
// add to v: scope dict, unless the value is not always available
|
||||||
if (p->vv_type != VAR_UNKNOWN)
|
if (p->vv_tv_type != VAR_UNKNOWN)
|
||||||
hash_add(&vimvarht, p->vv_di.di_key);
|
hash_add(&vimvarht, p->vv_di.di_key);
|
||||||
if (p->vv_flags & VV_COMPAT)
|
if (p->vv_flags & VV_COMPAT)
|
||||||
// add to compat scope dict
|
// add to compat scope dict
|
||||||
@@ -510,7 +511,7 @@ prepare_vimvar(int idx, typval_T *save_tv)
|
|||||||
{
|
{
|
||||||
*save_tv = vimvars[idx].vv_tv;
|
*save_tv = vimvars[idx].vv_tv;
|
||||||
vimvars[idx].vv_str = NULL; // don't free it now
|
vimvars[idx].vv_str = NULL; // don't free it now
|
||||||
if (vimvars[idx].vv_type == VAR_UNKNOWN)
|
if (vimvars[idx].vv_tv_type == VAR_UNKNOWN)
|
||||||
hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
|
hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +526,7 @@ restore_vimvar(int idx, typval_T *save_tv)
|
|||||||
hashitem_T *hi;
|
hashitem_T *hi;
|
||||||
|
|
||||||
vimvars[idx].vv_tv = *save_tv;
|
vimvars[idx].vv_tv = *save_tv;
|
||||||
if (vimvars[idx].vv_type == VAR_UNKNOWN)
|
if (vimvars[idx].vv_tv_type == VAR_UNKNOWN)
|
||||||
{
|
{
|
||||||
hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
|
hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
|
||||||
if (HASHITEM_EMPTY(hi))
|
if (HASHITEM_EMPTY(hi))
|
||||||
@@ -2265,7 +2266,7 @@ find_vim_var(char_u *name, int *di_flags)
|
|||||||
void
|
void
|
||||||
set_vim_var_type(int idx, vartype_T type)
|
set_vim_var_type(int idx, vartype_T type)
|
||||||
{
|
{
|
||||||
vimvars[idx].vv_type = type;
|
vimvars[idx].vv_tv_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2293,6 +2294,14 @@ get_vim_var_tv(int idx)
|
|||||||
return &vimvars[idx].vv_tv;
|
return &vimvars[idx].vv_tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type_T *
|
||||||
|
get_vim_var_type(int idx, garray_T *type_list)
|
||||||
|
{
|
||||||
|
if (vimvars[idx].vv_type != NULL)
|
||||||
|
return vimvars[idx].vv_type;
|
||||||
|
return typval2type_vimvar(&vimvars[idx].vv_tv, type_list);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set v: variable to "tv". Only accepts the same type.
|
* Set v: variable to "tv". Only accepts the same type.
|
||||||
* Takes over the value of "tv".
|
* Takes over the value of "tv".
|
||||||
@@ -2300,7 +2309,7 @@ get_vim_var_tv(int idx)
|
|||||||
int
|
int
|
||||||
set_vim_var_tv(int idx, typval_T *tv)
|
set_vim_var_tv(int idx, typval_T *tv)
|
||||||
{
|
{
|
||||||
if (vimvars[idx].vv_type != tv->v_type)
|
if (vimvars[idx].vv_tv_type != tv->v_type)
|
||||||
{
|
{
|
||||||
emsg(_(e_type_mismatch_for_v_variable));
|
emsg(_(e_type_mismatch_for_v_variable));
|
||||||
clear_tv(tv);
|
clear_tv(tv);
|
||||||
@@ -2430,7 +2439,7 @@ set_vim_var_string(
|
|||||||
int len) // length of "val" to use or -1 (whole string)
|
int len) // length of "val" to use or -1 (whole string)
|
||||||
{
|
{
|
||||||
clear_tv(&vimvars[idx].vv_di.di_tv);
|
clear_tv(&vimvars[idx].vv_di.di_tv);
|
||||||
vimvars[idx].vv_type = VAR_STRING;
|
vimvars[idx].vv_tv_type = VAR_STRING;
|
||||||
if (val == NULL)
|
if (val == NULL)
|
||||||
vimvars[idx].vv_str = NULL;
|
vimvars[idx].vv_str = NULL;
|
||||||
else if (len == -1)
|
else if (len == -1)
|
||||||
@@ -2446,7 +2455,7 @@ set_vim_var_string(
|
|||||||
set_vim_var_list(int idx, list_T *val)
|
set_vim_var_list(int idx, list_T *val)
|
||||||
{
|
{
|
||||||
clear_tv(&vimvars[idx].vv_di.di_tv);
|
clear_tv(&vimvars[idx].vv_di.di_tv);
|
||||||
vimvars[idx].vv_type = VAR_LIST;
|
vimvars[idx].vv_tv_type = VAR_LIST;
|
||||||
vimvars[idx].vv_list = val;
|
vimvars[idx].vv_list = val;
|
||||||
if (val != NULL)
|
if (val != NULL)
|
||||||
++val->lv_refcount;
|
++val->lv_refcount;
|
||||||
@@ -2459,7 +2468,7 @@ set_vim_var_list(int idx, list_T *val)
|
|||||||
set_vim_var_dict(int idx, dict_T *val)
|
set_vim_var_dict(int idx, dict_T *val)
|
||||||
{
|
{
|
||||||
clear_tv(&vimvars[idx].vv_di.di_tv);
|
clear_tv(&vimvars[idx].vv_di.di_tv);
|
||||||
vimvars[idx].vv_type = VAR_DICT;
|
vimvars[idx].vv_tv_type = VAR_DICT;
|
||||||
vimvars[idx].vv_dict = val;
|
vimvars[idx].vv_dict = val;
|
||||||
if (val != NULL)
|
if (val != NULL)
|
||||||
{
|
{
|
||||||
@@ -3925,7 +3934,7 @@ assert_error(garray_T *gap)
|
|||||||
{
|
{
|
||||||
struct vimvar *vp = &vimvars[VV_ERRORS];
|
struct vimvar *vp = &vimvars[VV_ERRORS];
|
||||||
|
|
||||||
if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
|
if (vp->vv_tv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
|
||||||
// Make sure v:errors is a list.
|
// Make sure v:errors is a list.
|
||||||
set_vim_var_list(VV_ERRORS, list_alloc());
|
set_vim_var_list(VV_ERRORS, list_alloc());
|
||||||
list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
|
list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
|
||||||
|
@@ -38,6 +38,7 @@ void set_vim_var_type(int idx, vartype_T type);
|
|||||||
void set_vim_var_nr(int idx, varnumber_T val);
|
void set_vim_var_nr(int idx, varnumber_T val);
|
||||||
char *get_vim_var_name(int idx);
|
char *get_vim_var_name(int idx);
|
||||||
typval_T *get_vim_var_tv(int idx);
|
typval_T *get_vim_var_tv(int idx);
|
||||||
|
type_T *get_vim_var_type(int idx, garray_T *type_list);
|
||||||
int set_vim_var_tv(int idx, typval_T *tv);
|
int set_vim_var_tv(int idx, typval_T *tv);
|
||||||
varnumber_T get_vim_var_nr(int idx);
|
varnumber_T get_vim_var_nr(int idx);
|
||||||
char_u *get_vim_var_str(int idx);
|
char_u *get_vim_var_str(int idx);
|
||||||
@@ -71,7 +72,7 @@ void vars_clear(hashtab_T *ht);
|
|||||||
void vars_clear_ext(hashtab_T *ht, int free_val);
|
void vars_clear_ext(hashtab_T *ht, int free_val);
|
||||||
void delete_var(hashtab_T *ht, hashitem_T *hi);
|
void delete_var(hashtab_T *ht, hashitem_T *hi);
|
||||||
void set_var(char_u *name, typval_T *tv, int copy);
|
void set_var(char_u *name, typval_T *tv, int copy);
|
||||||
void set_var_const(char_u *name, type_T *type, typval_T *tv_arg, int copy, int flags_arg, int var_idx);
|
void set_var_const(char_u *name, type_T *type_arg, typval_T *tv_arg, int copy, int flags_arg, int var_idx);
|
||||||
int var_check_permission(dictitem_T *di, char_u *name);
|
int var_check_permission(dictitem_T *di, char_u *name);
|
||||||
int var_check_ro(int flags, char_u *name, int use_gettext);
|
int var_check_ro(int flags, char_u *name, int use_gettext);
|
||||||
int var_check_lock(int flags, char_u *name, int use_gettext);
|
int var_check_lock(int flags, char_u *name, int use_gettext);
|
||||||
|
@@ -1821,8 +1821,21 @@ def Test_expr7_string()
|
|||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_expr7_vimvar()
|
def Test_expr7_vimvar()
|
||||||
|
v:errors = []
|
||||||
|
var errs: list<string> = v:errors
|
||||||
|
CheckDefFailure(['var errs: list<number> = v:errors'], 'E1012:')
|
||||||
|
|
||||||
var old: list<string> = v:oldfiles
|
var old: list<string> = v:oldfiles
|
||||||
var compl: dict<any> = v:completed_item
|
CheckDefFailure(['var old: list<number> = v:oldfiles'], 'E1012:')
|
||||||
|
|
||||||
|
var compl: dict<string> = v:completed_item
|
||||||
|
CheckDefFailure(['var compl: dict<number> = v:completed_item'], 'E1012:')
|
||||||
|
|
||||||
|
var args: list<string> = v:argv
|
||||||
|
CheckDefFailure(['var args: list<number> = v:argv'], 'E1012:')
|
||||||
|
|
||||||
|
var colors: dict<string> = v:colornames
|
||||||
|
CheckDefFailure(['var colors: dict<number> = v:colornames'], 'E1012:')
|
||||||
|
|
||||||
CheckDefFailure(["var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 1)
|
CheckDefFailure(["var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 1)
|
||||||
CheckScriptFailure(['vim9script', 'v:oldfiles = ["foo"]', "var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 3)
|
CheckScriptFailure(['vim9script', 'v:oldfiles = ["foo"]', "var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 3)
|
||||||
|
@@ -749,6 +749,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 */
|
||||||
|
/**/
|
||||||
|
3890,
|
||||||
/**/
|
/**/
|
||||||
3889,
|
3889,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -946,8 +946,7 @@ generate_LOADV(
|
|||||||
semsg(_(e_variable_not_found_str), name);
|
semsg(_(e_variable_not_found_str), name);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
type = typval2type_vimvar(get_vim_var_tv(vidx), cctx->ctx_type_list);
|
type = get_vim_var_type(vidx, cctx->ctx_type_list);
|
||||||
|
|
||||||
return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, type);
|
return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user