0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.2.1416: Vim9: boolean evaluation does not work as intended

Problem:    Vim9: boolean evaluation does not work as intended.
Solution:   Use tv2bool() in Vim9 script. (closes #6681)
This commit is contained in:
Bram Moolenaar
2020-08-10 21:57:54 +02:00
parent 6f8f7337c1
commit 3e06a1e2a8
4 changed files with 44 additions and 23 deletions

View File

@@ -192,7 +192,10 @@ eval_to_bool(
*error = FALSE; *error = FALSE;
if (!skip) if (!skip)
{ {
retval = (tv_get_number_chk(&tv, error) != 0); if (in_vim9script())
retval = tv2bool(&tv);
else
retval = (tv_get_number_chk(&tv, error) != 0);
clear_tv(&tv); clear_tv(&tv);
} }
} }
@@ -3098,7 +3101,8 @@ eval7(
// Apply prefixed "-" and "+" now. Matters especially when // Apply prefixed "-" and "+" now. Matters especially when
// "->" follows. // "->" follows.
if (ret == OK && evaluate && end_leader > start_leader) if (ret == OK && evaluate && end_leader > start_leader
&& rettv->v_type != VAR_BLOB)
ret = eval7_leader(rettv, TRUE, start_leader, &end_leader); ret = eval7_leader(rettv, TRUE, start_leader, &end_leader);
break; break;
@@ -3281,7 +3285,10 @@ eval7_leader(
f = rettv->vval.v_float; f = rettv->vval.v_float;
else else
#endif #endif
val = tv_get_number_chk(rettv, &error); if (in_vim9script() && end_leader[-1] == '!')
val = tv2bool(rettv);
else
val = tv_get_number_chk(rettv, &error);
if (error) if (error)
{ {
clear_tv(rettv); clear_tv(rettv);

View File

@@ -1750,31 +1750,35 @@ enddef
def Test_expr7_not() def Test_expr7_not()
assert_equal(true, !'') let lines =<< trim END
assert_equal(true, ![]) assert_equal(true, !'')
assert_equal(false, !'asdf') assert_equal(true, ![])
assert_equal(false, ![2]) assert_equal(false, !'asdf')
assert_equal(true, !!'asdf') assert_equal(false, ![2])
assert_equal(true, !![2]) assert_equal(true, !!'asdf')
assert_equal(true, !![2])
assert_equal(true, !test_null_partial()) assert_equal(true, !test_null_partial())
assert_equal(false, !{-> 'yes'}) assert_equal(false, !{-> 'yes'})
assert_equal(true, !test_null_dict()) assert_equal(true, !test_null_dict())
assert_equal(true, !{}) assert_equal(true, !{})
assert_equal(false, !{'yes': 'no'}) assert_equal(false, !{'yes': 'no'})
if has('channel') if has('channel')
assert_equal(true, !test_null_job()) assert_equal(true, !test_null_job())
assert_equal(true, !test_null_channel()) assert_equal(true, !test_null_channel())
endif endif
assert_equal(true, !test_null_blob()) assert_equal(true, !test_null_blob())
assert_equal(true, !0z) assert_equal(true, !0z)
assert_equal(false, !0z01) assert_equal(false, !0z01)
assert_equal(true, !test_void()) assert_equal(true, !test_void())
assert_equal(true, !test_unknown()) assert_equal(true, !test_unknown())
END
CheckDefSuccess(lines)
CheckScriptSuccess(['vim9script'] + lines)
enddef enddef
func Test_expr7_fails() func Test_expr7_fails()

View File

@@ -1,5 +1,13 @@
" Utility functions for testing vim9 script " Utility functions for testing vim9 script
" Check that "lines" inside ":def" has no error.
func CheckDefSuccess(lines)
call writefile(['def Func()'] + a:lines + ['enddef', 'defcompile'], 'Xdef')
so Xdef
call Func()
call delete('Xdef')
endfunc
" Check that "lines" inside ":def" results in an "error" message. " Check that "lines" inside ":def" results in an "error" message.
func CheckDefFailure(lines, error) func CheckDefFailure(lines, error)
call writefile(['def Func()'] + a:lines + ['enddef', 'defcompile'], 'Xdef') call writefile(['def Func()'] + a:lines + ['enddef', 'defcompile'], 'Xdef')

View File

@@ -754,6 +754,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 */
/**/
1416,
/**/ /**/
1415, 1415,
/**/ /**/