mirror of
https://github.com/neovim/neovim.git
synced 2025-09-18 09:18:19 +00:00
vim-patch:8.2.1110: Vim9: line continuation does not work in function arguments
Problem: Vim9: line continuation does not work in function arguments.
Solution: Pass "evalarg" to get_func_tv(). Fix seeing double quoted string
as comment.
e6b5324e3a
Omit skipwhite_and_linebreak_keep_string(): Vim9 script only.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
@@ -692,7 +692,7 @@ void eval_patch(const char *const origfile, const char *const difffile, const ch
|
|||||||
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
|
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip)
|
void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, bool skip)
|
||||||
{
|
{
|
||||||
*evalarg = (evalarg_T){ .eval_flags = skip ? 0 : EVAL_EVALUATE };
|
*evalarg = (evalarg_T){ .eval_flags = skip ? 0 : EVAL_EVALUATE };
|
||||||
if (eap != NULL && getline_equal(eap->getline, eap->cookie, getsourceline)) {
|
if (eap != NULL && getline_equal(eap->getline, eap->cookie, getsourceline)) {
|
||||||
@@ -2206,9 +2206,10 @@ int pattern_match(const char *pat, const char *text, bool ic)
|
|||||||
/// @param basetv "expr" for "expr->name(arg)"
|
/// @param basetv "expr" for "expr->name(arg)"
|
||||||
///
|
///
|
||||||
/// @return OK or FAIL.
|
/// @return OK or FAIL.
|
||||||
static int eval_func(char **const arg, char *const name, const int name_len, typval_T *const rettv,
|
static int eval_func(char **const arg, evalarg_T *const evalarg, char *const name,
|
||||||
const int flags, typval_T *const basetv)
|
const int name_len, typval_T *const rettv, const int flags,
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
|
typval_T *const basetv)
|
||||||
|
FUNC_ATTR_NONNULL_ARG(1, 3, 5)
|
||||||
{
|
{
|
||||||
const bool evaluate = flags & EVAL_EVALUATE;
|
const bool evaluate = flags & EVAL_EVALUATE;
|
||||||
char *s = name;
|
char *s = name;
|
||||||
@@ -2234,7 +2235,7 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ
|
|||||||
funcexe.fe_evaluate = evaluate;
|
funcexe.fe_evaluate = evaluate;
|
||||||
funcexe.fe_partial = partial;
|
funcexe.fe_partial = partial;
|
||||||
funcexe.fe_basetv = basetv;
|
funcexe.fe_basetv = basetv;
|
||||||
int ret = get_func_tv(s, len, rettv, arg, &funcexe);
|
int ret = get_func_tv(s, len, rettv, arg, evalarg, &funcexe);
|
||||||
|
|
||||||
xfree(s);
|
xfree(s);
|
||||||
|
|
||||||
@@ -3089,7 +3090,7 @@ static int eval7(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan
|
|||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
} else {
|
} else {
|
||||||
if (**arg == '(') { // recursive!
|
if (**arg == '(') { // recursive!
|
||||||
ret = eval_func(arg, s, len, rettv, flags, NULL);
|
ret = eval_func(arg, evalarg, s, len, rettv, flags, NULL);
|
||||||
} else if (evaluate) {
|
} else if (evaluate) {
|
||||||
ret = get_var_tv(s, len, rettv, NULL, true, false);
|
ret = get_var_tv(s, len, rettv, NULL, true, false);
|
||||||
} else {
|
} else {
|
||||||
@@ -3181,10 +3182,10 @@ static int eval7_leader(typval_T *const rettv, const bool numeric_only,
|
|||||||
/// to the name of the Lua function to call (after the
|
/// to the name of the Lua function to call (after the
|
||||||
/// "v:lua." prefix).
|
/// "v:lua." prefix).
|
||||||
/// @return OK on success, FAIL on failure.
|
/// @return OK on success, FAIL on failure.
|
||||||
static int call_func_rettv(char **const arg, typval_T *const rettv, const bool evaluate,
|
static int call_func_rettv(char **const arg, evalarg_T *const evalarg, typval_T *const rettv,
|
||||||
dict_T *const selfdict, typval_T *const basetv,
|
const bool evaluate, dict_T *const selfdict, typval_T *const basetv,
|
||||||
const char *const lua_funcname)
|
const char *const lua_funcname)
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2)
|
FUNC_ATTR_NONNULL_ARG(1, 3)
|
||||||
{
|
{
|
||||||
partial_T *pt = NULL;
|
partial_T *pt = NULL;
|
||||||
typval_T functv;
|
typval_T functv;
|
||||||
@@ -3216,7 +3217,7 @@ static int call_func_rettv(char **const arg, typval_T *const rettv, const bool e
|
|||||||
funcexe.fe_selfdict = selfdict;
|
funcexe.fe_selfdict = selfdict;
|
||||||
funcexe.fe_basetv = basetv;
|
funcexe.fe_basetv = basetv;
|
||||||
const int ret = get_func_tv(funcname, is_lua ? (int)(*arg - funcname) : -1, rettv,
|
const int ret = get_func_tv(funcname, is_lua ? (int)(*arg - funcname) : -1, rettv,
|
||||||
arg, &funcexe);
|
arg, evalarg, &funcexe);
|
||||||
|
|
||||||
// Clear the funcref afterwards, so that deleting it while
|
// Clear the funcref afterwards, so that deleting it while
|
||||||
// evaluating the arguments is possible (see test55).
|
// evaluating the arguments is possible (see test55).
|
||||||
@@ -3259,7 +3260,7 @@ static int eval_lambda(char **const arg, typval_T *const rettv, evalarg_T *const
|
|||||||
tv_clear(rettv);
|
tv_clear(rettv);
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
} else {
|
} else {
|
||||||
ret = call_func_rettv(arg, rettv, evaluate, NULL, &base, NULL);
|
ret = call_func_rettv(arg, evalarg, rettv, evaluate, NULL, &base, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the funcref afterwards, so that deleting it while
|
// Clear the funcref afterwards, so that deleting it while
|
||||||
@@ -3276,10 +3277,12 @@ static int eval_lambda(char **const arg, typval_T *const rettv, evalarg_T *const
|
|||||||
/// @param *arg points to the '-'.
|
/// @param *arg points to the '-'.
|
||||||
///
|
///
|
||||||
/// @return FAIL or OK. "*arg" is advanced to after the ')'.
|
/// @return FAIL or OK. "*arg" is advanced to after the ')'.
|
||||||
static int eval_method(char **const arg, typval_T *const rettv, const bool evaluate,
|
static int eval_method(char **const arg, typval_T *const rettv, evalarg_T *const evalarg,
|
||||||
const bool verbose)
|
const bool verbose)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ARG(1, 2)
|
||||||
{
|
{
|
||||||
|
const bool evaluate = evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE);
|
||||||
|
|
||||||
// Skip over the ->.
|
// Skip over the ->.
|
||||||
*arg += 2;
|
*arg += 2;
|
||||||
typval_T base = *rettv;
|
typval_T base = *rettv;
|
||||||
@@ -3329,9 +3332,9 @@ static int eval_method(char **const arg, typval_T *const rettv, const bool evalu
|
|||||||
rettv->vval.v_partial = vvlua_partial;
|
rettv->vval.v_partial = vvlua_partial;
|
||||||
rettv->vval.v_partial->pt_refcount++;
|
rettv->vval.v_partial->pt_refcount++;
|
||||||
}
|
}
|
||||||
ret = call_func_rettv(arg, rettv, evaluate, NULL, &base, lua_funcname);
|
ret = call_func_rettv(arg, evalarg, rettv, evaluate, NULL, &base, lua_funcname);
|
||||||
} else {
|
} else {
|
||||||
ret = eval_func(arg, name, len, rettv, evaluate ? EVAL_EVALUATE : 0, &base);
|
ret = eval_func(arg, evalarg, name, len, rettv, evaluate ? EVAL_EVALUATE : 0, &base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7081,7 +7084,7 @@ int handle_subscript(const char **const arg, typval_T *rettv, evalarg_T *const e
|
|||||||
&& !ascii_iswhite(*(*arg - 1)))
|
&& !ascii_iswhite(*(*arg - 1)))
|
||||||
|| (**arg == '-' && (*arg)[1] == '>'))) {
|
|| (**arg == '-' && (*arg)[1] == '>'))) {
|
||||||
if (**arg == '(') {
|
if (**arg == '(') {
|
||||||
ret = call_func_rettv((char **)arg, rettv, evaluate, selfdict, NULL, lua_funcname);
|
ret = call_func_rettv((char **)arg, evalarg, rettv, evaluate, selfdict, NULL, lua_funcname);
|
||||||
|
|
||||||
// Stop the expression evaluation when immediately aborting on
|
// Stop the expression evaluation when immediately aborting on
|
||||||
// error, or when an interrupt occurred or an exception was thrown
|
// error, or when an interrupt occurred or an exception was thrown
|
||||||
@@ -7100,7 +7103,7 @@ int handle_subscript(const char **const arg, typval_T *rettv, evalarg_T *const e
|
|||||||
ret = eval_lambda((char **)arg, rettv, evalarg, verbose);
|
ret = eval_lambda((char **)arg, rettv, evalarg, verbose);
|
||||||
} else {
|
} else {
|
||||||
// expr->name()
|
// expr->name()
|
||||||
ret = eval_method((char **)arg, rettv, evaluate, verbose);
|
ret = eval_method((char **)arg, rettv, evalarg, verbose);
|
||||||
}
|
}
|
||||||
} else { // **arg == '[' || **arg == '.'
|
} else { // **arg == '[' || **arg == '.'
|
||||||
tv_dict_unref(selfdict);
|
tv_dict_unref(selfdict);
|
||||||
|
@@ -458,15 +458,14 @@ void emsg_funcname(const char *errmsg, const char *name)
|
|||||||
/// @param funcexe various values
|
/// @param funcexe various values
|
||||||
///
|
///
|
||||||
/// @return OK or FAIL.
|
/// @return OK or FAIL.
|
||||||
int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, funcexe_T *funcexe)
|
int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, evalarg_T *const evalarg,
|
||||||
|
funcexe_T *funcexe)
|
||||||
{
|
{
|
||||||
char *argp;
|
char *argp;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
|
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
|
||||||
int argcount = 0; // number of arguments found
|
int argcount = 0; // number of arguments found
|
||||||
|
|
||||||
evalarg_T evalarg = { .eval_flags = funcexe->fe_evaluate ? EVAL_EVALUATE : 0 };
|
|
||||||
|
|
||||||
// Get the arguments.
|
// Get the arguments.
|
||||||
argp = *arg;
|
argp = *arg;
|
||||||
while (argcount < MAX_FUNC_ARGS
|
while (argcount < MAX_FUNC_ARGS
|
||||||
@@ -475,7 +474,7 @@ int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, funcexe_
|
|||||||
if (*argp == ')' || *argp == ',' || *argp == NUL) {
|
if (*argp == ')' || *argp == ',' || *argp == NUL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (eval1(&argp, &argvars[argcount], &evalarg) == FAIL) {
|
if (eval1(&argp, &argvars[argcount], evalarg) == FAIL) {
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3013,16 +3012,19 @@ void ex_call(exarg_T *eap)
|
|||||||
bool failed = false;
|
bool failed = false;
|
||||||
funcdict_T fudi;
|
funcdict_T fudi;
|
||||||
partial_T *partial = NULL;
|
partial_T *partial = NULL;
|
||||||
|
evalarg_T evalarg;
|
||||||
|
|
||||||
|
fill_evalarg_from_eap(&evalarg, eap, eap->skip);
|
||||||
if (eap->skip) {
|
if (eap->skip) {
|
||||||
// trans_function_name() doesn't work well when skipping, use eval0()
|
// trans_function_name() doesn't work well when skipping, use eval0()
|
||||||
// instead to skip to any following command, e.g. for:
|
// instead to skip to any following command, e.g. for:
|
||||||
// :if 0 | call dict.foo().bar() | endif.
|
// :if 0 | call dict.foo().bar() | endif.
|
||||||
emsg_skip++;
|
emsg_skip++;
|
||||||
if (eval0(eap->arg, &rettv, eap, NULL) != FAIL) {
|
if (eval0(eap->arg, &rettv, eap, &evalarg) != FAIL) {
|
||||||
tv_clear(&rettv);
|
tv_clear(&rettv);
|
||||||
}
|
}
|
||||||
emsg_skip--;
|
emsg_skip--;
|
||||||
|
clear_evalarg(&evalarg, eap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3080,7 +3082,7 @@ void ex_call(exarg_T *eap)
|
|||||||
funcexe.fe_evaluate = true;
|
funcexe.fe_evaluate = true;
|
||||||
funcexe.fe_partial = partial;
|
funcexe.fe_partial = partial;
|
||||||
funcexe.fe_selfdict = fudi.fd_dict;
|
funcexe.fe_selfdict = fudi.fd_dict;
|
||||||
if (get_func_tv(name, -1, &rettv, &arg, &funcexe) == FAIL) {
|
if (get_func_tv(name, -1, &rettv, &arg, &evalarg, &funcexe) == FAIL) {
|
||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3118,6 +3120,7 @@ void ex_call(exarg_T *eap)
|
|||||||
eap->nextcmd = check_nextcmd(arg);
|
eap->nextcmd = check_nextcmd(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
clear_evalarg(&evalarg, eap);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
tv_dict_unref(fudi.fd_dict);
|
tv_dict_unref(fudi.fd_dict);
|
||||||
|
@@ -792,13 +792,9 @@ void report_discard_pending(int pending, void *value)
|
|||||||
void ex_eval(exarg_T *eap)
|
void ex_eval(exarg_T *eap)
|
||||||
{
|
{
|
||||||
typval_T tv;
|
typval_T tv;
|
||||||
evalarg_T evalarg = {
|
evalarg_T evalarg;
|
||||||
.eval_flags = eap->skip ? 0 : EVAL_EVALUATE,
|
|
||||||
};
|
fill_evalarg_from_eap(&evalarg, eap, eap->skip);
|
||||||
if (getline_equal(eap->getline, eap->cookie, getsourceline)) {
|
|
||||||
evalarg.eval_getline = eap->getline;
|
|
||||||
evalarg.eval_cookie = eap->cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eval0(eap->arg, &tv, eap, &evalarg) == OK) {
|
if (eval0(eap->arg, &tv, eap, &evalarg) == OK) {
|
||||||
tv_clear(&tv);
|
tv_clear(&tv);
|
||||||
|
Reference in New Issue
Block a user