0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.1053: default constructor arguments are not optional

Problem:    Default constructor arguments are not optional.
Solution:   Use "= v:none" to make constructor arguments optional.
This commit is contained in:
Bram Moolenaar
2022-12-13 18:43:22 +00:00
parent 692fe0889c
commit 65b0d16768
11 changed files with 174 additions and 35 deletions

View File

@@ -2195,8 +2195,13 @@ push_default_value(
* Return "arg" if it does not look like a variable list.
*/
static char_u *
compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
compile_assignment(
char_u *arg_start,
exarg_T *eap,
cmdidx_T cmdidx,
cctx_T *cctx)
{
char_u *arg = arg_start;
char_u *var_start;
char_u *p;
char_u *end = arg;
@@ -2206,6 +2211,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
int semicolon = 0;
int did_generate_slice = FALSE;
garray_T *instr = &cctx->ctx_instr;
int jump_instr_idx = instr->ga_len;
char_u *op;
int oplen = 0;
int heredoc = FALSE;
@@ -2216,6 +2222,23 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
lhs_T lhs;
long start_lnum = SOURCING_LNUM;
int has_arg_is_set_prefix = STRNCMP(arg, "ifargisset ", 11) == 0;
if (has_arg_is_set_prefix)
{
arg += 11;
int def_idx = getdigits(&arg);
arg = skipwhite(arg);
// Use a JUMP_IF_ARG_NOT_SET instruction to skip if the value was not
// given and the default value is "v:none".
int off = STACK_FRAME_SIZE + (cctx->ctx_ufunc->uf_va_name != NULL
? 1 : 0);
int count = cctx->ctx_ufunc->uf_def_args.ga_len;
if (generate_JUMP_IF_ARG(cctx, ISN_JUMP_IF_ARG_NOT_SET,
def_idx - count - off) == FAIL)
goto theend;
}
// Skip over the "varname" or "[varname, varname]" to get to any "=".
p = skip_var_list(arg, TRUE, &var_count, &semicolon, TRUE);
if (p == NULL)
@@ -2636,6 +2659,13 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
if (var_idx + 1 < var_count)
var_start = skipwhite(lhs.lhs_end + 1);
if (has_arg_is_set_prefix)
{
// set instruction index in JUMP_IF_ARG_SET to here
isn_T *isn = ((isn_T *)instr->ga_data) + jump_instr_idx;
isn->isn_arg.jumparg.jump_where = instr->ga_len;
}
}
// For "[var, var] = expr" drop the "expr" value.
@@ -2711,9 +2741,9 @@ may_compile_assignment(exarg_T *eap, char_u **line, cctx_T *cctx)
}
}
if (*eap->cmd == '[')
// might be "[var, var] = expr" or "ifargisset this.member = expr"
if (*eap->cmd == '[' || STRNCMP(eap->cmd, "ifargisset ", 11) == 0)
{
// might be "[var, var] = expr"
*line = compile_assignment(eap->cmd, eap, CMD_SIZE, cctx);
if (*line == NULL)
return FAIL;
@@ -2994,7 +3024,6 @@ compile_def_function(
int count = ufunc->uf_def_args.ga_len;
int first_def_arg = ufunc->uf_args.ga_len - count;
int i;
char_u *arg;
int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
int did_set_arg_type = FALSE;
@@ -3002,23 +3031,27 @@ compile_def_function(
SOURCING_LNUM = 0; // line number unknown
for (i = 0; i < count; ++i)
{
char_u *arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
if (STRCMP(arg, "v:none") == 0)
// "arg = v:none" means the argument is optional without
// setting a value when the argument is missing.
continue;
type_T *val_type;
int arg_idx = first_def_arg + i;
where_T where = WHERE_INIT;
int r;
int jump_instr_idx = instr->ga_len;
isn_T *isn;
// Use a JUMP_IF_ARG_SET instruction to skip if the value was given.
if (generate_JUMP_IF_ARG_SET(&cctx, i - count - off) == FAIL)
if (generate_JUMP_IF_ARG(&cctx, ISN_JUMP_IF_ARG_SET,
i - count - off) == FAIL)
goto erret;
// Make sure later arguments are not found.
ufunc->uf_args_visible = arg_idx;
arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
r = compile_expr0(&arg, &cctx);
int r = compile_expr0(&arg, &cctx);
if (r == FAIL)
goto erret;