Patch 8.2.2209

3 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 25, 2020, 6:38:59 AM12/25/20
to vim...@googlegroups.com

Patch 8.2.2209
Problem: Vim9: return type of => lambda not parsed.
Solution: Parse and use the return type.
Files: src/vim9compile.c, src/userfunc.c, src/vim9type.c,
src/proto/vim9type.pro, src/vim9script.c, src/eval.c
src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2208/src/vim9compile.c 2020-12-24 21:56:37.647479568 +0100
--- src/vim9compile.c 2020-12-25 12:33:08.507858416 +0100
***************
*** 4118,4128 ****
// Recognize <type>
if (**arg == '<' && eval_isnamec1((*arg)[1]))
{
- int called_emsg_before = called_emsg;
-
++*arg;
! want_type = parse_type(arg, cctx->ctx_type_list);
! if (called_emsg != called_emsg_before)
return FAIL;

if (**arg != '>')
--- 4118,4126 ----
// Recognize <type>
if (**arg == '<' && eval_isnamec1((*arg)[1]))
{
++*arg;
! want_type = parse_type(arg, cctx->ctx_type_list, TRUE);
! if (want_type == NULL)
return FAIL;

if (**arg != '>')
***************
*** 4809,4815 ****
* compile "return [expr]"
*/
static char_u *
! compile_return(char_u *arg, int set_return_type, cctx_T *cctx)
{
char_u *p = arg;
garray_T *stack = &cctx->ctx_type_stack;
--- 4807,4813 ----
* compile "return [expr]"
*/
static char_u *
! compile_return(char_u *arg, int check_return_type, cctx_T *cctx)
{
char_u *p = arg;
garray_T *stack = &cctx->ctx_type_stack;
***************
*** 4824,4831 ****
if (cctx->ctx_skip != SKIP_YES)
{
stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
! if (set_return_type)
cctx->ctx_ufunc->uf_ret_type = stack_type;
else
{
if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
--- 4822,4831 ----
if (cctx->ctx_skip != SKIP_YES)
{
stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
! if (check_return_type && cctx->ctx_ufunc->uf_ret_type == NULL)
! {
cctx->ctx_ufunc->uf_ret_type = stack_type;
+ }
else
{
if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID
***************
*** 4843,4849 ****
}
else
{
! // "set_return_type" cannot be TRUE, only used for a lambda which
// always has an argument.
if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
&& cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
--- 4843,4849 ----
}
else
{
! // "check_return_type" cannot be TRUE, only used for a lambda which
// always has an argument.
if (cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_VOID
&& cctx->ctx_ufunc->uf_ret_type->tt_type != VAR_UNKNOWN)
***************
*** 5636,5642 ****
goto theend;
}
p = skipwhite(var_end + 1);
! type = parse_type(&p, cctx->ctx_type_list);
has_type = TRUE;
}
else if (lvar != NULL)
--- 5636,5644 ----
goto theend;
}
p = skipwhite(var_end + 1);
! type = parse_type(&p, cctx->ctx_type_list, TRUE);
! if (type == NULL)
! goto theend;
has_type = TRUE;
}
else if (lvar != NULL)
***************
*** 7417,7431 ****
* After ex_function() has collected all the function lines: parse and compile
* the lines into instructions.
* Adds the function to "def_functions".
! * When "set_return_type" is set then set ufunc->uf_ret_type to the type of the
! * return statement (used for lambda).
* "outer_cctx" is set for a nested function.
* This can be used recursively through compile_lambda(), which may reallocate
* "def_functions".
* Returns OK or FAIL.
*/
int
! compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
{
char_u *line = NULL;
char_u *p;
--- 7419,7434 ----
* After ex_function() has collected all the function lines: parse and compile
* the lines into instructions.
* Adds the function to "def_functions".
! * When "check_return_type" is set then set ufunc->uf_ret_type to the type of
! * the return statement (used for lambda). When uf_ret_type is already set
! * then check that it matches.
* "outer_cctx" is set for a nested function.
* This can be used recursively through compile_lambda(), which may reallocate
* "def_functions".
* Returns OK or FAIL.
*/
int
! compile_def_function(ufunc_T *ufunc, int check_return_type, cctx_T *outer_cctx)
{
char_u *line = NULL;
char_u *p;
***************
*** 7797,7803 ****
goto erret;

case CMD_return:
! line = compile_return(p, set_return_type, &cctx);
cctx.ctx_had_return = TRUE;
break;

--- 7800,7806 ----
goto erret;

case CMD_return:
! line = compile_return(p, check_return_type, &cctx);
cctx.ctx_had_return = TRUE;
break;

*** ../vim-8.2.2208/src/userfunc.c 2020-12-24 16:05:54.339860228 +0100
--- src/userfunc.c 2020-12-25 12:09:31.763975556 +0100
***************
*** 349,355 ****
// will get the type from the default value
type = &t_unknown;
else
! type = parse_type(&p, &fp->uf_type_list);
if (type == NULL)
return FAIL;
fp->uf_arg_types[i] = type;
--- 349,355 ----
// will get the type from the default value
type = &t_unknown;
else
! type = parse_type(&p, &fp->uf_type_list, TRUE);
if (type == NULL)
return FAIL;
fp->uf_arg_types[i] = type;
***************
*** 369,375 ****
// todo: get type from default value
fp->uf_va_type = &t_any;
else
! fp->uf_va_type = parse_type(&p, &fp->uf_type_list);
if (fp->uf_va_type == NULL)
return FAIL;
}
--- 369,375 ----
// todo: get type from default value
fp->uf_va_type = &t_any;
else
! fp->uf_va_type = parse_type(&p, &fp->uf_type_list, TRUE);
if (fp->uf_va_type == NULL)
return FAIL;
}
***************
*** 460,476 ****

/*
* Skip over "->" or "=>" after the arguments of a lambda.
* Return NULL if no valid arrow found.
*/
static char_u *
! skip_arrow(char_u *start, int equal_arrow)
{
char_u *s = start;

if (equal_arrow)
{
if (*s == ':')
! s = skip_type(skipwhite(s + 1), TRUE);
s = skipwhite(s);
if (*s != '=')
return NULL;
--- 460,481 ----

/*
* Skip over "->" or "=>" after the arguments of a lambda.
+ * If ": type" is found make "ret_type" point to "type".
* Return NULL if no valid arrow found.
*/
static char_u *
! skip_arrow(char_u *start, int equal_arrow, char_u **ret_type)
{
char_u *s = start;

if (equal_arrow)
{
if (*s == ':')
! {
! s = skipwhite(s + 1);
! *ret_type = s;
! s = skip_type(s, TRUE);
! }
s = skipwhite(s);
if (*s != '=')
return NULL;
***************
*** 503,508 ****
--- 508,514 ----
ufunc_T *fp = NULL;
partial_T *pt = NULL;
int varargs;
+ char_u *ret_type = NULL;
int ret;
char_u *s;
char_u *start, *end;
***************
*** 517,535 ****
ga_init(&newargs);
ga_init(&newlines);

! // First, check if this is a lambda expression. "->" or "=>" must exist.
s = skipwhite(*arg + 1);
ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
types_optional ? &argtypes : NULL, types_optional,
NULL, NULL, TRUE, NULL, NULL);
! if (ret == FAIL || skip_arrow(s, equal_arrow) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
return NOTDONE;
}

! // Parse the arguments again.
if (evaluate)
pnewargs = &newargs;
else
--- 523,542 ----
ga_init(&newargs);
ga_init(&newlines);

! // First, check if this is really a lambda expression. "->" or "=>" must
! // be found after the arguments.
s = skipwhite(*arg + 1);
ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
types_optional ? &argtypes : NULL, types_optional,
NULL, NULL, TRUE, NULL, NULL);
! if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
return NOTDONE;
}

! // Parse the arguments for real.
if (evaluate)
pnewargs = &newargs;
else
***************
*** 538,544 ****
ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
types_optional ? &argtypes : NULL, types_optional,
&varargs, NULL, FALSE, NULL, NULL);
! if (ret == FAIL || (*arg = skip_arrow(*arg, equal_arrow)) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
--- 545,552 ----
ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
types_optional ? &argtypes : NULL, types_optional,
&varargs, NULL, FALSE, NULL, NULL);
! if (ret == FAIL
! || (*arg = skip_arrow(*arg, equal_arrow, &ret_type)) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
***************
*** 551,561 ****

*arg = skipwhite_and_linebreak(*arg, evalarg);

! // Only recognize "{" as the start of a function body when followed by
! // white space, "{key: val}" is a dict.
! if (equal_arrow && **arg == '{' && IS_WHITE_OR_NUL((*arg)[1]))
{
// TODO: process the function body upto the "}".
emsg("Lambda function body not supported yet");
goto errret;
}
--- 559,569 ----

*arg = skipwhite_and_linebreak(*arg, evalarg);

! // Recognize "{" as the start of a function body.
! if (equal_arrow && **arg == '{')
{
// TODO: process the function body upto the "}".
+ // Return type is required then.
emsg("Lambda function body not supported yet");
goto errret;
}
***************
*** 619,627 ****
hash_add(&func_hashtab, UF2HIKEY(fp));
fp->uf_args = newargs;
ga_init(&fp->uf_def_args);
! if (types_optional
! && parse_argument_types(fp, &argtypes, FALSE) == FAIL)
! goto errret;

fp->uf_lines = newlines;
if (current_funccal != NULL && eval_lavars)
--- 627,644 ----
hash_add(&func_hashtab, UF2HIKEY(fp));
fp->uf_args = newargs;
ga_init(&fp->uf_def_args);
! if (types_optional)
! {
! if (parse_argument_types(fp, &argtypes, FALSE) == FAIL)
! goto errret;
! if (ret_type != NULL)
! {
! fp->uf_ret_type = parse_type(&ret_type,
! &fp->uf_type_list, TRUE);
! if (fp->uf_ret_type == NULL)
! goto errret;
! }
! }

fp->uf_lines = newlines;
if (current_funccal != NULL && eval_lavars)
***************
*** 3752,3758 ****
else
{
p = ret_type;
! fp->uf_ret_type = parse_type(&p, &fp->uf_type_list);
}
SOURCING_LNUM = lnum_save;
}
--- 3769,3775 ----
else
{
p = ret_type;
! fp->uf_ret_type = parse_type(&p, &fp->uf_type_list, TRUE);
}
SOURCING_LNUM = lnum_save;
}
*** ../vim-8.2.2208/src/vim9type.c 2020-11-16 20:08:32.395713947 +0100
--- src/vim9type.c 2020-12-25 12:09:26.867986864 +0100
***************
*** 596,623 ****
* Returns NULL in case of failure.
*/
static type_T *
! parse_type_member(char_u **arg, type_T *type, garray_T *type_gap)
{
type_T *member_type;
int prev_called_emsg = called_emsg;

if (**arg != '<')
{
! if (*skipwhite(*arg) == '<')
! semsg(_(e_no_white_space_allowed_before_str), "<");
! else
! emsg(_(e_missing_type));
! return type;
}
*arg = skipwhite(*arg + 1);

! member_type = parse_type(arg, type_gap);

*arg = skipwhite(*arg);
if (**arg != '>' && called_emsg == prev_called_emsg)
{
! emsg(_(e_missing_gt_after_type));
! return type;
}
++*arg;

--- 596,633 ----
* Returns NULL in case of failure.
*/
static type_T *
! parse_type_member(
! char_u **arg,
! type_T *type,
! garray_T *type_gap,
! int give_error)
{
type_T *member_type;
int prev_called_emsg = called_emsg;

if (**arg != '<')
{
! if (give_error)
! {
! if (*skipwhite(*arg) == '<')
! semsg(_(e_no_white_space_allowed_before_str), "<");
! else
! emsg(_(e_missing_type));
! }
! return NULL;
}
*arg = skipwhite(*arg + 1);

! member_type = parse_type(arg, type_gap, give_error);
! if (member_type == NULL)
! return NULL;

*arg = skipwhite(*arg);
if (**arg != '>' && called_emsg == prev_called_emsg)
{
! if (give_error)
! emsg(_(e_missing_gt_after_type));
! return NULL;
}
++*arg;

***************
*** 628,637 ****

/*
* Parse a type at "arg" and advance over it.
! * Return &t_any for failure.
*/
type_T *
! parse_type(char_u **arg, garray_T *type_gap)
{
char_u *p = *arg;
size_t len;
--- 638,648 ----

/*
* Parse a type at "arg" and advance over it.
! * When "give_error" is TRUE give error messages, otherwise be quiet.
! * Return NULL for failure.
*/
type_T *
! parse_type(char_u **arg, garray_T *type_gap, int give_error)
{
char_u *p = *arg;
size_t len;
***************
*** 673,679 ****
if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
{
*arg += len;
! return parse_type_member(arg, &t_dict_any, type_gap);
}
break;
case 'f':
--- 684,691 ----
if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
{
*arg += len;
! return parse_type_member(arg, &t_dict_any,
! type_gap, give_error);
}
break;
case 'f':
***************
*** 683,690 ****
*arg += len;
return &t_float;
#else
! emsg(_(e_this_vim_is_not_compiled_with_float_support));
! return &t_any;
#endif
}
if (len == 4 && STRNCMP(*arg, "func", len) == 0)
--- 695,703 ----
*arg += len;
return &t_float;
#else
! if (give_error)
! emsg(_(e_this_vim_is_not_compiled_with_float_support));
! return NULL;
#endif
}
if (len == 4 && STRNCMP(*arg, "func", len) == 0)
***************
*** 721,731 ****
}
else if (first_optional != -1)
{
! emsg(_(e_mandatory_argument_after_optional_argument));
! return &t_any;
}

! arg_type[argcount++] = parse_type(&p, type_gap);

// Nothing comes after "...{type}".
if (flags & TTFLAG_VARARGS)
--- 734,748 ----
}
else if (first_optional != -1)
{
! if (give_error)
! emsg(_(e_mandatory_argument_after_optional_argument));
! return NULL;
}

! type = parse_type(&p, type_gap, give_error);
! if (type == NULL)
! return NULL;
! arg_type[argcount++] = type;

// Nothing comes after "...{type}".
if (flags & TTFLAG_VARARGS)
***************
*** 733,763 ****

if (*p != ',' && *skipwhite(p) == ',')
{
! semsg(_(e_no_white_space_allowed_before_str), ",");
! return &t_any;
}
if (*p == ',')
{
++p;
if (!VIM_ISWHITE(*p))
{
! semsg(_(e_white_space_required_after_str), ",");
! return &t_any;
}
}
p = skipwhite(p);
if (argcount == MAX_FUNC_ARGS)
{
! emsg(_(e_too_many_argument_types));
! return &t_any;
}
}

p = skipwhite(p);
if (*p != ')')
{
! emsg(_(e_missing_close));
! return &t_any;
}
*arg = p + 1;
}
--- 750,784 ----

if (*p != ',' && *skipwhite(p) == ',')
{
! if (give_error)
! semsg(_(e_no_white_space_allowed_before_str), ",");
! return NULL;
}
if (*p == ',')
{
++p;
if (!VIM_ISWHITE(*p))
{
! if (give_error)
! semsg(_(e_white_space_required_after_str), ",");
! return NULL;
}
}
p = skipwhite(p);
if (argcount == MAX_FUNC_ARGS)
{
! if (give_error)
! emsg(_(e_too_many_argument_types));
! return NULL;
}
}

p = skipwhite(p);
if (*p != ')')
{
! if (give_error)
! emsg(_(e_missing_close));
! return NULL;
}
*arg = p + 1;
}
***************
*** 765,774 ****
{
// parse return type
++*arg;
! if (!VIM_ISWHITE(**arg))
semsg(_(e_white_space_required_after_str), ":");
*arg = skipwhite(*arg);
! ret_type = parse_type(arg, type_gap);
}
if (flags == 0 && first_optional == -1 && argcount <= 0)
type = get_func_type(ret_type, argcount, type_gap);
--- 786,797 ----
{
// parse return type
++*arg;
! if (!VIM_ISWHITE(**arg) && give_error)
semsg(_(e_white_space_required_after_str), ":");
*arg = skipwhite(*arg);
! ret_type = parse_type(arg, type_gap, give_error);
! if (ret_type == NULL)
! return NULL;
}
if (flags == 0 && first_optional == -1 && argcount <= 0)
type = get_func_type(ret_type, argcount, type_gap);
***************
*** 783,789 ****
? argcount : first_optional;
if (func_type_add_arg_types(type, argcount,
type_gap) == FAIL)
! return &t_any;
mch_memmove(type->tt_args, arg_type,
sizeof(type_T *) * argcount);
}
--- 806,812 ----
? argcount : first_optional;
if (func_type_add_arg_types(type, argcount,
type_gap) == FAIL)
! return NULL;
mch_memmove(type->tt_args, arg_type,
sizeof(type_T *) * argcount);
}
***************
*** 802,808 ****
if (len == 4 && STRNCMP(*arg, "list", len) == 0)
{
*arg += len;
! return parse_type_member(arg, &t_list_any, type_gap);
}
break;
case 'n':
--- 825,832 ----
if (len == 4 && STRNCMP(*arg, "list", len) == 0)
{
*arg += len;
! return parse_type_member(arg, &t_list_any,
! type_gap, give_error);
}
break;
case 'n':
***************
*** 828,835 ****
break;
}

! semsg(_(e_type_not_recognized_str), *arg);
! return &t_any;
}

/*
--- 852,860 ----
break;
}

! if (give_error)
! semsg(_(e_type_not_recognized_str), *arg);
! return NULL;
}

/*
***************
*** 1016,1024 ****
char *
type_name(type_T *type, char **tofree)
{
! char *name = vartype_name(type->tt_type);

*tofree = NULL;
if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
{
char *member_free;
--- 1041,1052 ----
char *
type_name(type_T *type, char **tofree)
{
! char *name;

*tofree = NULL;
+ if (type == NULL)
+ return "[unknown]";
+ name = vartype_name(type->tt_type);
if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
{
char *member_free;
*** ../vim-8.2.2208/src/proto/vim9type.pro 2020-11-16 20:08:32.395713947 +0100
--- src/proto/vim9type.pro 2020-12-25 12:04:20.552586070 +0100
***************
*** 17,23 ****
int check_type(type_T *expected, type_T *actual, int give_msg, int argidx);
int check_arg_type(type_T *expected, type_T *actual, int argidx);
char_u *skip_type(char_u *start, int optional);
! type_T *parse_type(char_u **arg, garray_T *type_gap);
void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap);
type_T *get_member_type_from_stack(type_T **stack_top, int count, int skip, garray_T *type_gap);
char *vartype_name(vartype_T type);
--- 17,23 ----
int check_type(type_T *expected, type_T *actual, int give_msg, int argidx);
int check_arg_type(type_T *expected, type_T *actual, int argidx);
char_u *skip_type(char_u *start, int optional);
! type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
void common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap);
type_T *get_member_type_from_stack(type_T **stack_top, int count, int skip, garray_T *type_gap);
char *vartype_name(vartype_T type);
*** ../vim-8.2.2208/src/vim9script.c 2020-12-05 14:44:33.512669314 +0100
--- src/vim9script.c 2020-12-25 12:01:59.572766021 +0100
***************
*** 511,517 ****
char_u *name;
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
type_T *type;
- int called_emsg_before = called_emsg;
typval_T init_tv;

if (eap->cmdidx == CMD_final || eap->cmdidx == CMD_const)
--- 511,516 ----
***************
*** 548,555 ****

// parse type
p = skipwhite(p + 1);
! type = parse_type(&p, &si->sn_type_list);
! if (called_emsg != called_emsg_before)
{
vim_free(name);
return p;
--- 547,554 ----

// parse type
p = skipwhite(p + 1);
! type = parse_type(&p, &si->sn_type_list, TRUE);
! if (type == NULL)
{
vim_free(name);
return p;
*** ../vim-8.2.2208/src/eval.c 2020-12-24 17:15:49.909113037 +0100
--- src/eval.c 2020-12-25 11:53:57.617883182 +0100
***************
*** 868,874 ****
char_u *tp = skipwhite(p + 1);

// parse the type after the name
! lp->ll_type = parse_type(&tp, &si->sn_type_list);
lp->ll_name_end = tp;
}
}
--- 868,876 ----
char_u *tp = skipwhite(p + 1);

// parse the type after the name
! lp->ll_type = parse_type(&tp, &si->sn_type_list, !quiet);
! if (lp->ll_type == NULL && !quiet)
! return NULL;
lp->ll_name_end = tp;
}
}
*** ../vim-8.2.2208/src/testdir/test_vim9_expr.vim 2020-12-24 15:13:35.850860411 +0100
--- src/testdir/test_vim9_expr.vim 2020-12-25 12:34:12.367693002 +0100
***************
*** 1951,1957 ****
assert_equal([1, 3, 5], res)

# Lambda returning a dict
! var Lmb = () => {key: 42}
assert_equal({key: 42}, Lmb())
END
CheckDefSuccess(lines)
--- 1951,1957 ----
assert_equal([1, 3, 5], res)

# Lambda returning a dict
! var Lmb = () => ({key: 42})
assert_equal({key: 42}, Lmb())
END
CheckDefSuccess(lines)
***************
*** 1960,1970 ****
CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')

CheckDefFailure(["filter([1, 2], (k,v) => 1)"], 'E1069:', 1)
# error is in first line of the lambda
CheckDefFailure(["var L = (a) -> a + b"], 'E1001:', 1)

! # TODO: lambda after -> doesn't work yet
# assert_equal('xxxyyy', 'xxx'->((a, b) => a .. b)('yyy'))

# CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
--- 1960,1975 ----
CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')

+ CheckDefSuccess(["var Ref: func(number): string = (a: number): string => 'x'"])
+ CheckDefSuccess(["var Ref: func(number): any = (a: number): any => 'x'"])
+ CheckDefFailure(["var Ref: func(number): number = (a: number): string => 'x'"], 'E1012:')
+ CheckDefFailure(["var Ref: func(number): string = (a: number): string => 99"], 'E1012:')
+
CheckDefFailure(["filter([1, 2], (k,v) => 1)"], 'E1069:', 1)
# error is in first line of the lambda
CheckDefFailure(["var L = (a) -> a + b"], 'E1001:', 1)

! # TODO: ->(lambda)() doesn't work yet
# assert_equal('xxxyyy', 'xxx'->((a, b) => a .. b)('yyy'))

# CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
***************
*** 1973,1981 ****
# 'E1106: 2 arguments too many')
# CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)

! CheckDefSuccess(['var Fx = (a) => {k1: 0,', ' k2: 1}'])
! CheckDefFailure(['var Fx = (a) => {k1: 0', ' k2: 1}'], 'E722:', 2)
! CheckDefFailure(['var Fx = (a) => {k1: 0,', ' k2 1}'], 'E720:', 2)

CheckDefSuccess(['var Fx = (a) => [0,', ' 1]'])
CheckDefFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
--- 1978,1986 ----
# 'E1106: 2 arguments too many')
# CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)

! CheckDefSuccess(['var Fx = (a) => ({k1: 0,', ' k2: 1})'])
! CheckDefFailure(['var Fx = (a) => ({k1: 0', ' k2: 1})'], 'E722:', 2)
! CheckDefFailure(['var Fx = (a) => ({k1: 0,', ' k2 1})'], 'E720:', 2)

CheckDefSuccess(['var Fx = (a) => [0,', ' 1]'])
CheckDefFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
*** ../vim-8.2.2208/src/version.c 2020-12-24 21:56:37.647479568 +0100
--- src/version.c 2020-12-25 12:37:04.083228394 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2209,
/**/

--
"Making it up? Why should I want to make anything up? Life's bad enough
as it is without wanting to invent any more of it."
-- Marvin, the Paranoid Android in Douglas Adams'
"The Hitchhiker's Guide to the Galaxy"

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages