mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
fix(eval): skip over v:lua properly (#27517)
Problem: Error when parsing v:lua in a ternary expression. Solution: Set rettv->v_type for v:lua even if not evaluating.
This commit is contained in:
parent
796df966f3
commit
b8c34efe33
@ -3238,6 +3238,13 @@ static int eval7(char **arg, typval_T *rettv, evalarg_T *const evalarg, bool wan
|
|||||||
} else {
|
} else {
|
||||||
// skip the name
|
// skip the name
|
||||||
check_vars(s, (size_t)len);
|
check_vars(s, (size_t)len);
|
||||||
|
// If evaluate is false rettv->v_type was not set, but it's needed
|
||||||
|
// in handle_subscript() to parse v:lua, so set it here.
|
||||||
|
if (rettv->v_type == VAR_UNKNOWN && !evaluate && strnequal(s, "v:lua.", 6)) {
|
||||||
|
rettv->v_type = VAR_PARTIAL;
|
||||||
|
rettv->vval.v_partial = vvlua_partial;
|
||||||
|
rettv->vval.v_partial->pt_refcount++;
|
||||||
|
}
|
||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3442,7 +3449,7 @@ static int eval_method(char **const arg, typval_T *const rettv, evalarg_T *const
|
|||||||
int len;
|
int len;
|
||||||
char *name = *arg;
|
char *name = *arg;
|
||||||
char *lua_funcname = NULL;
|
char *lua_funcname = NULL;
|
||||||
if (strncmp(name, "v:lua.", 6) == 0) {
|
if (strnequal(name, "v:lua.", 6)) {
|
||||||
lua_funcname = name + 6;
|
lua_funcname = name + 6;
|
||||||
*arg = (char *)skip_luafunc_name(lua_funcname);
|
*arg = (char *)skip_luafunc_name(lua_funcname);
|
||||||
*arg = skipwhite(*arg); // to detect trailing whitespace later
|
*arg = skipwhite(*arg); // to detect trailing whitespace later
|
||||||
@ -7614,6 +7621,10 @@ int handle_subscript(const char **const arg, typval_T *rettv, evalarg_T *const e
|
|||||||
const char *lua_funcname = NULL;
|
const char *lua_funcname = NULL;
|
||||||
|
|
||||||
if (tv_is_luafunc(rettv)) {
|
if (tv_is_luafunc(rettv)) {
|
||||||
|
if (!evaluate) {
|
||||||
|
tv_clear(rettv);
|
||||||
|
}
|
||||||
|
|
||||||
if (**arg != '.') {
|
if (**arg != '.') {
|
||||||
tv_clear(rettv);
|
tv_clear(rettv);
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
|
@ -1726,7 +1726,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
n = false; // Trailing garbage.
|
n = false; // Trailing garbage.
|
||||||
}
|
}
|
||||||
} else if (*p == '*') { // Internal or user defined function.
|
} else if (*p == '*') { // Internal or user defined function.
|
||||||
n = strncmp(p, "*v:lua.", 7) == 0 ? nlua_func_exists(p + 7) : function_exists(p + 1, false);
|
n = strnequal(p, "*v:lua.", 7) ? nlua_func_exists(p + 7) : function_exists(p + 1, false);
|
||||||
} else if (*p == ':') {
|
} else if (*p == ':') {
|
||||||
n = cmd_exists(p + 1);
|
n = cmd_exists(p + 1);
|
||||||
} else if (*p == '#') {
|
} else if (*p == '#') {
|
||||||
|
@ -538,6 +538,8 @@ describe('v:lua', function()
|
|||||||
eq('\tbadval', eval("v:lua.require'leftpad'('badval')"))
|
eq('\tbadval', eval("v:lua.require'leftpad'('badval')"))
|
||||||
eq(9003, eval("v:lua.require'bar'.doit()"))
|
eq(9003, eval("v:lua.require'bar'.doit()"))
|
||||||
eq(9004, eval("v:lua.require'baz-quux'.doit()"))
|
eq(9004, eval("v:lua.require'baz-quux'.doit()"))
|
||||||
|
eq(9003, eval("1 ? v:lua.require'bar'.doit() : v:lua.require'baz-quux'.doit()"))
|
||||||
|
eq(9004, eval("0 ? v:lua.require'bar'.doit() : v:lua.require'baz-quux'.doit()"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('throw errors for invalid use', function()
|
it('throw errors for invalid use', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user