mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.2227: Vim9: recognizing lambda is too complicated
Problem: Vim9: recognizing lambda is too complicated. Solution: Call compile_lambda() and check for NOTDONE.
This commit is contained in:
@@ -1863,9 +1863,9 @@ def Test_expr7_lambda()
|
|||||||
END
|
END
|
||||||
CheckDefAndScriptSuccess(lines)
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
CheckDefFailure(["var Ref = {a->a + 1}"], 'E720:')
|
CheckDefFailure(["var Ref = {a->a + 1}"], 'E1004:')
|
||||||
CheckDefFailure(["var Ref = {a-> a + 1}"], 'E720:')
|
CheckDefFailure(["var Ref = {a-> a + 1}"], 'E1004:')
|
||||||
CheckDefFailure(["var Ref = {a ->a + 1}"], 'E720:')
|
CheckDefFailure(["var Ref = {a ->a + 1}"], 'E1004:')
|
||||||
|
|
||||||
CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
|
CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
|
||||||
# error is in first line of the lambda
|
# error is in first line of the lambda
|
||||||
@@ -1964,13 +1964,9 @@ def Test_expr7_new_lambda()
|
|||||||
END
|
END
|
||||||
CheckDefAndScriptSuccess(lines)
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
CheckDefFailure(["var Ref = (a)=>a + 1"], 'E1001:')
|
CheckDefAndScriptFailure(["var Ref = (a)=>a + 1"], 'E1004:')
|
||||||
CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
|
CheckDefAndScriptFailure(["var Ref = (a)=> a + 1"], 'E1004:')
|
||||||
CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')
|
CheckDefAndScriptFailure(["var Ref = (a) =>a + 1"], 'E1004:')
|
||||||
|
|
||||||
CheckScriptFailure(["vim9script", "var Ref = (a)=>a + 1"], 'E1004:')
|
|
||||||
CheckScriptFailure(["vim9script", "var Ref = (a)=> a + 1"], 'E1004:')
|
|
||||||
CheckScriptFailure(["vim9script", "var Ref = (a) =>a + 1"], 'E1004:')
|
|
||||||
|
|
||||||
CheckDefFailure(["var Ref: func(number): number = (a: number): string => 'x'"], 'E1012:')
|
CheckDefFailure(["var Ref: func(number): number = (a: number): string => 'x'"], 'E1012:')
|
||||||
CheckDefFailure(["var Ref: func(number): string = (a: number): string => 99"], 'E1012:')
|
CheckDefFailure(["var Ref: func(number): string = (a: number): string => 99"], 'E1012:')
|
||||||
@@ -2682,7 +2678,7 @@ func Test_expr7_fails()
|
|||||||
call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
|
call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
|
||||||
|
|
||||||
call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
|
call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
|
||||||
call CheckDefExecFailure(["{a: 1->len()"], 'E723:', 2)
|
call CheckDefExecFailure(["{a: 1->len()"], 'E1004:', 1)
|
||||||
call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
|
call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
@@ -570,7 +570,7 @@ get_lambda_tv(
|
|||||||
&varargs, NULL, FALSE, NULL, NULL);
|
&varargs, NULL, FALSE, NULL, NULL);
|
||||||
if (ret == FAIL
|
if (ret == FAIL
|
||||||
|| (s = skip_arrow(*arg, equal_arrow, &ret_type,
|
|| (s = skip_arrow(*arg, equal_arrow, &ret_type,
|
||||||
equal_arrow ? &white_error : NULL)) == NULL)
|
equal_arrow || in_vim9script() ? &white_error : NULL)) == NULL)
|
||||||
{
|
{
|
||||||
if (types_optional)
|
if (types_optional)
|
||||||
ga_clear_strings(&argtypes);
|
ga_clear_strings(&argtypes);
|
||||||
|
@@ -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 */
|
||||||
|
/**/
|
||||||
|
2227,
|
||||||
/**/
|
/**/
|
||||||
2226,
|
2226,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2949,10 +2949,12 @@ compile_list(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
|||||||
/*
|
/*
|
||||||
* parse a lambda: "{arg, arg -> expr}" or "(arg, arg) => expr"
|
* parse a lambda: "{arg, arg -> expr}" or "(arg, arg) => expr"
|
||||||
* "*arg" points to the '{'.
|
* "*arg" points to the '{'.
|
||||||
|
* Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
compile_lambda(char_u **arg, cctx_T *cctx)
|
compile_lambda(char_u **arg, cctx_T *cctx)
|
||||||
{
|
{
|
||||||
|
int r;
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
ufunc_T *ufunc;
|
ufunc_T *ufunc;
|
||||||
evalarg_T evalarg;
|
evalarg_T evalarg;
|
||||||
@@ -2962,10 +2964,11 @@ compile_lambda(char_u **arg, cctx_T *cctx)
|
|||||||
evalarg.eval_cctx = cctx;
|
evalarg.eval_cctx = cctx;
|
||||||
|
|
||||||
// Get the funcref in "rettv".
|
// Get the funcref in "rettv".
|
||||||
if (get_lambda_tv(arg, &rettv, TRUE, &evalarg) != OK)
|
r = get_lambda_tv(arg, &rettv, TRUE, &evalarg);
|
||||||
|
if (r != OK)
|
||||||
{
|
{
|
||||||
clear_evalarg(&evalarg, NULL);
|
clear_evalarg(&evalarg, NULL);
|
||||||
return FAIL;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "rettv" will now be a partial referencing the function.
|
// "rettv" will now be a partial referencing the function.
|
||||||
@@ -4001,26 +4004,13 @@ compile_expr7(
|
|||||||
* Lambda: {arg, arg -> expr}
|
* Lambda: {arg, arg -> expr}
|
||||||
* Dictionary: {'key': val, 'key': val}
|
* Dictionary: {'key': val, 'key': val}
|
||||||
*/
|
*/
|
||||||
case '{': {
|
case '{': // Try parsing as a lambda, if NOTDONE is returned it
|
||||||
char_u *start = skipwhite(*arg + 1);
|
// must be a dict.
|
||||||
char_u *after = start;
|
// TODO: if we go with the "(arg) => expr" syntax remove
|
||||||
garray_T ga_arg;
|
// this
|
||||||
|
|
||||||
// Find out what comes after the arguments.
|
|
||||||
ret = get_function_args(&after, '-', NULL,
|
|
||||||
&ga_arg, TRUE, NULL, NULL,
|
|
||||||
TRUE, NULL, NULL);
|
|
||||||
if (ret != FAIL && after[0] == '>'
|
|
||||||
&& ((after > start + 2
|
|
||||||
&& VIM_ISWHITE(after[-2]))
|
|
||||||
|| after == start + 1)
|
|
||||||
&& IS_WHITE_OR_NUL(after[1]))
|
|
||||||
// TODO: if we go with the "(arg) => expr" syntax
|
|
||||||
// remove this
|
|
||||||
ret = compile_lambda(arg, cctx);
|
ret = compile_lambda(arg, cctx);
|
||||||
else
|
if (ret == NOTDONE)
|
||||||
ret = compile_dict(arg, cctx, ppconst);
|
ret = compile_dict(arg, cctx, ppconst);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4051,32 +4041,10 @@ compile_expr7(
|
|||||||
* lambda: (arg, arg) => expr
|
* lambda: (arg, arg) => expr
|
||||||
* funcref: (arg, arg) => { statement }
|
* funcref: (arg, arg) => { statement }
|
||||||
*/
|
*/
|
||||||
case '(': {
|
case '(': // if compile_lambda returns NOTDONE then it must be (expr)
|
||||||
char_u *start = skipwhite(*arg + 1);
|
|
||||||
char_u *after = start;
|
|
||||||
garray_T ga_arg;
|
|
||||||
|
|
||||||
// Find out if "=>" comes after the ().
|
|
||||||
ret = get_function_args(&after, ')', NULL,
|
|
||||||
&ga_arg, TRUE, NULL, NULL,
|
|
||||||
TRUE, NULL, NULL);
|
|
||||||
if (ret == OK && VIM_ISWHITE(
|
|
||||||
*after == ':' ? after[1] : *after))
|
|
||||||
{
|
|
||||||
if (*after == ':')
|
|
||||||
// Skip over type in "(arg): type".
|
|
||||||
after = skip_type(skipwhite(after + 1), TRUE);
|
|
||||||
|
|
||||||
after = skipwhite(after);
|
|
||||||
if (after[0] == '=' && after[1] == '>'
|
|
||||||
&& IS_WHITE_OR_NUL(after[2]))
|
|
||||||
{
|
|
||||||
ret = compile_lambda(arg, cctx);
|
ret = compile_lambda(arg, cctx);
|
||||||
break;
|
if (ret == NOTDONE)
|
||||||
}
|
|
||||||
}
|
|
||||||
ret = compile_parenthesis(arg, cctx, ppconst);
|
ret = compile_parenthesis(arg, cctx, ppconst);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: ret = NOTDONE;
|
default: ret = NOTDONE;
|
||||||
|
Reference in New Issue
Block a user