mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.2.1067: expression "!expr->func()" does not work (#22585)
Problem: Expression "!expr->func()" does not work.
Solution: Apply plus and minus earlier. (closes vim/vim#6348)
0b1cd52ff6
Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
parent
89a525de9f
commit
3ad8458824
@ -2906,6 +2906,12 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
|
||||
case '8':
|
||||
case '9':
|
||||
ret = get_number_tv(arg, rettv, evaluate, want_string);
|
||||
|
||||
// Apply prefixed "-" and "+" now. Matters especially when
|
||||
// "->" follows.
|
||||
if (ret == OK && evaluate && end_leader > start_leader) {
|
||||
ret = eval7_leader(rettv, true, start_leader, &end_leader);
|
||||
}
|
||||
break;
|
||||
|
||||
// String constant: "string".
|
||||
@ -3011,13 +3017,12 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
|
||||
// Handle following '[', '(' and '.' for expr[expr], expr.name,
|
||||
// expr(expr), expr->name(expr)
|
||||
if (ret == OK) {
|
||||
ret = handle_subscript((const char **)arg, rettv, evaluate, true,
|
||||
(char *)start_leader, &end_leader);
|
||||
ret = handle_subscript((const char **)arg, rettv, evaluate, true);
|
||||
}
|
||||
|
||||
// Apply logical NOT and unary '-', from right to left, ignore '+'.
|
||||
if (ret == OK && evaluate && end_leader > start_leader) {
|
||||
ret = eval7_leader(rettv, (char *)start_leader, &end_leader);
|
||||
ret = eval7_leader(rettv, false, start_leader, &end_leader);
|
||||
}
|
||||
|
||||
recurse--;
|
||||
@ -3027,9 +3032,11 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
|
||||
/// Apply the leading "!" and "-" before an eval7 expression to "rettv".
|
||||
/// Adjusts "end_leaderp" until it is at "start_leader".
|
||||
///
|
||||
/// @param numeric_only if true only handle "+" and "-".
|
||||
///
|
||||
/// @return OK on success, FAIL on failure.
|
||||
static int eval7_leader(typval_T *const rettv, const char *const start_leader,
|
||||
const char **const end_leaderp)
|
||||
static int eval7_leader(typval_T *const rettv, const bool numeric_only,
|
||||
const char *const start_leader, const char **const end_leaderp)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
const char *end_leader = (char *)(*end_leaderp);
|
||||
@ -3050,6 +3057,10 @@ static int eval7_leader(typval_T *const rettv, const char *const start_leader,
|
||||
while (end_leader > start_leader) {
|
||||
end_leader--;
|
||||
if (*end_leader == '!') {
|
||||
if (numeric_only) {
|
||||
end_leader++;
|
||||
break;
|
||||
}
|
||||
if (rettv->v_type == VAR_FLOAT) {
|
||||
f = !(bool)f;
|
||||
} else {
|
||||
@ -6899,8 +6910,7 @@ int check_luafunc_name(const char *const str, const bool paren)
|
||||
/// @param verbose give error messages
|
||||
/// @param start_leader start of '!' and '-' prefixes
|
||||
/// @param end_leaderp end of '!' and '-' prefixes
|
||||
int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose,
|
||||
const char *const start_leader, const char **const end_leaderp)
|
||||
int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int verbose)
|
||||
{
|
||||
int ret = OK;
|
||||
dict_T *selfdict = NULL;
|
||||
@ -6944,11 +6954,6 @@ int handle_subscript(const char **const arg, typval_T *rettv, int evaluate, int
|
||||
tv_dict_unref(selfdict);
|
||||
selfdict = NULL;
|
||||
} else if (**arg == '-') {
|
||||
// Expression "-1.0->method()" applies the leader "-" before
|
||||
// applying ->.
|
||||
if (evaluate && *end_leaderp > start_leader) {
|
||||
ret = eval7_leader(rettv, (char *)start_leader, end_leaderp);
|
||||
}
|
||||
if (ret == OK) {
|
||||
if ((*arg)[2] == '{') {
|
||||
// expr->{lambda}()
|
||||
|
@ -3075,8 +3075,7 @@ void ex_call(exarg_T *eap)
|
||||
}
|
||||
|
||||
// Handle a function returning a Funcref, Dictionary or List.
|
||||
if (handle_subscript((const char **)&arg, &rettv, true, true,
|
||||
(const char *)name, (const char **)&name)
|
||||
if (handle_subscript((const char **)&arg, &rettv, true, true)
|
||||
== FAIL) {
|
||||
failed = true;
|
||||
break;
|
||||
|
@ -508,7 +508,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
|
||||
} else {
|
||||
// handle d.key, l[idx], f(expr)
|
||||
const char *const arg_subsc = arg;
|
||||
if (handle_subscript(&arg, &tv, true, true, name, &name) == FAIL) {
|
||||
if (handle_subscript(&arg, &tv, true, true) == FAIL) {
|
||||
error = true;
|
||||
} else {
|
||||
if (arg == arg_subsc && len == 2 && name[1] == ':') {
|
||||
@ -1715,7 +1715,7 @@ bool var_exists(const char *var)
|
||||
n = get_var_tv(name, len, &tv, NULL, false, true) == OK;
|
||||
if (n) {
|
||||
// Handle d.key, l[idx], f(expr).
|
||||
n = handle_subscript(&var, &tv, true, false, name, &name) == OK;
|
||||
n = handle_subscript(&var, &tv, true, false) == OK;
|
||||
if (n) {
|
||||
tv_clear(&tv);
|
||||
}
|
||||
|
@ -111,6 +111,13 @@ func Test_special_char()
|
||||
call assert_fails('echo "\<C-">')
|
||||
endfunc
|
||||
|
||||
func Test_method_with_prefix()
|
||||
call assert_equal(1, !range(5)->empty())
|
||||
call assert_equal([0, 1, 2], --3->range())
|
||||
call assert_equal(0, !-3)
|
||||
call assert_equal(1, !+-+0)
|
||||
endfunc
|
||||
|
||||
func Test_option_value()
|
||||
" boolean
|
||||
set bri
|
||||
|
Loading…
Reference in New Issue
Block a user