forked from aniani/vim
patch 8.2.2219: Vim9: method call with expression not supported
Problem: Vim9: method call with expression not supported. Solution: Implement expr->(expr)().
This commit is contained in:
parent
fc0e8f5c3e
commit
7e3682068b
@ -2560,6 +2560,39 @@ def Test_expr7_call()
|
|||||||
delete('Xruntime', 'rf')
|
delete('Xruntime', 'rf')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_expr7_method_call()
|
||||||
|
new
|
||||||
|
setline(1, ['first', 'last'])
|
||||||
|
'second'->append(1)
|
||||||
|
"third"->append(2)
|
||||||
|
assert_equal(['first', 'second', 'third', 'last'], getline(1, '$'))
|
||||||
|
bwipe!
|
||||||
|
|
||||||
|
var bufnr = bufnr()
|
||||||
|
var loclist = [{bufnr: bufnr, lnum: 42, col: 17, text: 'wrong'}]
|
||||||
|
loclist->setloclist(0)
|
||||||
|
assert_equal([{bufnr: bufnr,
|
||||||
|
lnum: 42,
|
||||||
|
col: 17,
|
||||||
|
text: 'wrong',
|
||||||
|
pattern: '',
|
||||||
|
valid: 1,
|
||||||
|
vcol: 0,
|
||||||
|
nr: 0,
|
||||||
|
type: '',
|
||||||
|
module: ''}
|
||||||
|
], getloclist(0))
|
||||||
|
|
||||||
|
var result: bool = get({n: 0}, 'n', 0)
|
||||||
|
assert_equal(false, result)
|
||||||
|
|
||||||
|
assert_equal('+string+', 'string'->((s) => '+' .. s .. '+')())
|
||||||
|
assert_equal('-text-', 'text'->((s, c) => c .. s .. c)('-'))
|
||||||
|
|
||||||
|
var Join = (l) => join(l, 'x')
|
||||||
|
assert_equal('axb', ['a', 'b']->(Join)())
|
||||||
|
enddef
|
||||||
|
|
||||||
|
|
||||||
def Test_expr7_not()
|
def Test_expr7_not()
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
@ -2852,33 +2885,6 @@ def Test_expr7_subscript_linebreak()
|
|||||||
one)
|
one)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_expr7_method_call()
|
|
||||||
new
|
|
||||||
setline(1, ['first', 'last'])
|
|
||||||
'second'->append(1)
|
|
||||||
"third"->append(2)
|
|
||||||
assert_equal(['first', 'second', 'third', 'last'], getline(1, '$'))
|
|
||||||
bwipe!
|
|
||||||
|
|
||||||
var bufnr = bufnr()
|
|
||||||
var loclist = [{bufnr: bufnr, lnum: 42, col: 17, text: 'wrong'}]
|
|
||||||
loclist->setloclist(0)
|
|
||||||
assert_equal([{bufnr: bufnr,
|
|
||||||
lnum: 42,
|
|
||||||
col: 17,
|
|
||||||
text: 'wrong',
|
|
||||||
pattern: '',
|
|
||||||
valid: 1,
|
|
||||||
vcol: 0,
|
|
||||||
nr: 0,
|
|
||||||
type: '',
|
|
||||||
module: ''}
|
|
||||||
], getloclist(0))
|
|
||||||
|
|
||||||
var result: bool = get({n: 0}, 'n', 0)
|
|
||||||
assert_equal(false, result)
|
|
||||||
enddef
|
|
||||||
|
|
||||||
func Test_expr7_trailing_fails()
|
func Test_expr7_trailing_fails()
|
||||||
call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)}'], 'E107:', 2)
|
call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)}'], 'E107:', 2)
|
||||||
call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274:', 2)
|
call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274:', 2)
|
||||||
|
@ -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 */
|
||||||
|
/**/
|
||||||
|
2219,
|
||||||
/**/
|
/**/
|
||||||
2218,
|
2218,
|
||||||
/**/
|
/**/
|
||||||
|
@ -2817,9 +2817,8 @@ compile_call(
|
|||||||
&& compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK)
|
&& compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK)
|
||||||
{
|
{
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
type_T *type;
|
type_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
|
|
||||||
type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
|
||||||
res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
|
res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
@ -3429,6 +3428,19 @@ get_compare_type(char_u *p, int *len, int *type_is)
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip over an expression, ignoring most errors.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
skip_expr_cctx(char_u **arg, cctx_T *cctx)
|
||||||
|
{
|
||||||
|
evalarg_T evalarg;
|
||||||
|
|
||||||
|
CLEAR_FIELD(evalarg);
|
||||||
|
evalarg.eval_cctx = cctx;
|
||||||
|
skip_expr(arg, &evalarg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compile code to apply '-', '+' and '!'.
|
* Compile code to apply '-', '+' and '!'.
|
||||||
* When "numeric_only" is TRUE do not apply '!'.
|
* When "numeric_only" is TRUE do not apply '!'.
|
||||||
@ -3487,6 +3499,38 @@ compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile "(expression)": recursive!
|
||||||
|
* Return FAIL/OK.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*arg = skipwhite(*arg + 1);
|
||||||
|
if (ppconst->pp_used <= PPSIZE - 10)
|
||||||
|
{
|
||||||
|
ret = compile_expr1(arg, cctx, ppconst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not enough space in ppconst, flush constants.
|
||||||
|
if (generate_ppconst(cctx, ppconst) == FAIL)
|
||||||
|
return FAIL;
|
||||||
|
ret = compile_expr0(arg, cctx);
|
||||||
|
}
|
||||||
|
*arg = skipwhite(*arg);
|
||||||
|
if (**arg == ')')
|
||||||
|
++*arg;
|
||||||
|
else if (ret == OK)
|
||||||
|
{
|
||||||
|
emsg(_(e_missing_close));
|
||||||
|
ret = FAIL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compile whatever comes after "name" or "name()".
|
* Compile whatever comes after "name" or "name()".
|
||||||
* Advances "*arg" only when something was recognized.
|
* Advances "*arg" only when something was recognized.
|
||||||
@ -3572,10 +3616,42 @@ compile_subscript(
|
|||||||
}
|
}
|
||||||
else if (**arg == '(')
|
else if (**arg == '(')
|
||||||
{
|
{
|
||||||
// Funcref call: list->(Refs[2])()
|
int argcount = 1;
|
||||||
// or lambda: list->((arg) => expr)()
|
char_u *expr;
|
||||||
// TODO: make this work
|
garray_T *stack;
|
||||||
if (compile_lambda_call(arg, cctx) == FAIL)
|
type_T *type;
|
||||||
|
|
||||||
|
// Funcref call: list->(Refs[2])(arg)
|
||||||
|
// or lambda: list->((arg) => expr)(arg)
|
||||||
|
// Fist compile the arguments.
|
||||||
|
expr = *arg;
|
||||||
|
*arg = skipwhite(*arg + 1);
|
||||||
|
skip_expr_cctx(arg, cctx);
|
||||||
|
*arg = skipwhite(*arg);
|
||||||
|
if (**arg != ')')
|
||||||
|
{
|
||||||
|
semsg(_(e_missing_paren), *arg);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
++*arg;
|
||||||
|
if (**arg != '(')
|
||||||
|
{
|
||||||
|
semsg(_(e_missing_paren), *arg);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*arg = skipwhite(*arg + 1);
|
||||||
|
if (compile_arguments(arg, cctx, &argcount) == FAIL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
// Compile the function expression.
|
||||||
|
if (compile_parenthesis(&expr, cctx, ppconst) == FAIL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
stack = &cctx->ctx_type_stack;
|
||||||
|
type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
|
if (generate_PCALL(cctx, argcount,
|
||||||
|
(char_u *)"[expression]", type, FALSE) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3998,28 +4074,7 @@ compile_expr7(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret = compile_parenthesis(arg, cctx, ppconst);
|
||||||
// (expression): recursive!
|
|
||||||
*arg = skipwhite(*arg + 1);
|
|
||||||
if (ppconst->pp_used <= PPSIZE - 10)
|
|
||||||
{
|
|
||||||
ret = compile_expr1(arg, cctx, ppconst);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Not enough space in ppconst, flush constants.
|
|
||||||
if (generate_ppconst(cctx, ppconst) == FAIL)
|
|
||||||
return FAIL;
|
|
||||||
ret = compile_expr0(arg, cctx);
|
|
||||||
}
|
|
||||||
*arg = skipwhite(*arg);
|
|
||||||
if (**arg == ')')
|
|
||||||
++*arg;
|
|
||||||
else if (ret == OK)
|
|
||||||
{
|
|
||||||
emsg(_(e_missing_close));
|
|
||||||
ret = FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4597,7 +4652,7 @@ compile_expr2(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
|||||||
* end:
|
* end:
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int ppconst_used = ppconst->pp_used;
|
int ppconst_used = ppconst->pp_used;
|
||||||
@ -4606,11 +4661,7 @@ compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
|||||||
// Ignore all kinds of errors when not producing code.
|
// Ignore all kinds of errors when not producing code.
|
||||||
if (cctx->ctx_skip == SKIP_YES)
|
if (cctx->ctx_skip == SKIP_YES)
|
||||||
{
|
{
|
||||||
evalarg_T evalarg;
|
skip_expr_cctx(arg, cctx);
|
||||||
|
|
||||||
CLEAR_FIELD(evalarg);
|
|
||||||
evalarg.eval_cctx = cctx;
|
|
||||||
skip_expr(arg, &evalarg);
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user