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:
zeertzjq 2023-04-14 14:24:50 +08:00
parent 9c65a18753
commit cf37630d1b
3 changed files with 32 additions and 30 deletions

View File

@ -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);
}
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 };
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)"
///
/// @return OK or FAIL.
static int eval_func(char **const arg, char *const name, const int name_len, typval_T *const rettv,
const int flags, typval_T *const basetv)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
static int eval_func(char **const arg, evalarg_T *const evalarg, char *const name,
const int name_len, typval_T *const rettv, const int flags,
typval_T *const basetv)
FUNC_ATTR_NONNULL_ARG(1, 3, 5)
{
const bool evaluate = flags & EVAL_EVALUATE;
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_partial = partial;
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);
@ -3089,7 +3090,7 @@ static int eval7(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan
ret = FAIL;
} else {
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) {
ret = get_var_tv(s, len, rettv, NULL, true, false);
} 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
/// "v:lua." prefix).
/// @return OK on success, FAIL on failure.
static int call_func_rettv(char **const arg, typval_T *const rettv, const bool evaluate,
dict_T *const selfdict, typval_T *const basetv,
static int call_func_rettv(char **const arg, evalarg_T *const evalarg, typval_T *const rettv,
const bool evaluate, dict_T *const selfdict, typval_T *const basetv,
const char *const lua_funcname)
FUNC_ATTR_NONNULL_ARG(1, 2)
FUNC_ATTR_NONNULL_ARG(1, 3)
{
partial_T *pt = NULL;
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_basetv = basetv;
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
// 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);
ret = FAIL;
} 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
@ -3276,10 +3277,12 @@ static int eval_lambda(char **const arg, typval_T *const rettv, evalarg_T *const
/// @param *arg points to 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)
FUNC_ATTR_NONNULL_ALL
FUNC_ATTR_NONNULL_ARG(1, 2)
{
const bool evaluate = evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE);
// Skip over the ->.
*arg += 2;
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->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 {
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)))
|| (**arg == '-' && (*arg)[1] == '>'))) {
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
// 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);
} else {
// expr->name()
ret = eval_method((char **)arg, rettv, evaluate, verbose);
ret = eval_method((char **)arg, rettv, evalarg, verbose);
}
} else { // **arg == '[' || **arg == '.'
tv_dict_unref(selfdict);

View File

@ -458,15 +458,14 @@ void emsg_funcname(const char *errmsg, const char *name)
/// @param funcexe various values
///
/// @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;
int ret = OK;
typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments
int argcount = 0; // number of arguments found
evalarg_T evalarg = { .eval_flags = funcexe->fe_evaluate ? EVAL_EVALUATE : 0 };
// Get the arguments.
argp = *arg;
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) {
break;
}
if (eval1(&argp, &argvars[argcount], &evalarg) == FAIL) {
if (eval1(&argp, &argvars[argcount], evalarg) == FAIL) {
ret = FAIL;
break;
}
@ -3013,16 +3012,19 @@ void ex_call(exarg_T *eap)
bool failed = false;
funcdict_T fudi;
partial_T *partial = NULL;
evalarg_T evalarg;
fill_evalarg_from_eap(&evalarg, eap, eap->skip);
if (eap->skip) {
// trans_function_name() doesn't work well when skipping, use eval0()
// instead to skip to any following command, e.g. for:
// :if 0 | call dict.foo().bar() | endif.
emsg_skip++;
if (eval0(eap->arg, &rettv, eap, NULL) != FAIL) {
if (eval0(eap->arg, &rettv, eap, &evalarg) != FAIL) {
tv_clear(&rettv);
}
emsg_skip--;
clear_evalarg(&evalarg, eap);
return;
}
@ -3080,7 +3082,7 @@ void ex_call(exarg_T *eap)
funcexe.fe_evaluate = true;
funcexe.fe_partial = partial;
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;
break;
}
@ -3118,6 +3120,7 @@ void ex_call(exarg_T *eap)
eap->nextcmd = check_nextcmd(arg);
}
}
clear_evalarg(&evalarg, eap);
end:
tv_dict_unref(fudi.fd_dict);

View File

@ -792,13 +792,9 @@ void report_discard_pending(int pending, void *value)
void ex_eval(exarg_T *eap)
{
typval_T tv;
evalarg_T evalarg = {
.eval_flags = eap->skip ? 0 : EVAL_EVALUATE,
};
if (getline_equal(eap->getline, eap->cookie, getsourceline)) {
evalarg.eval_getline = eap->getline;
evalarg.eval_cookie = eap->cookie;
}
evalarg_T evalarg;
fill_evalarg_from_eap(&evalarg, eap, eap->skip);
if (eval0(eap->arg, &tv, eap, &evalarg) == OK) {
tv_clear(&tv);