patch 9.1.1546: Vim9: error with has() and short circuit evaluation
Problem: Vim9: error with has() and short circuit evaluation Solution: Only eval, if ctx_skip is not SKIP_YES (Yegappan Lakshmanan). fixes: #17750 closes: #17755 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
edce68912e
commit
8de753148f
@ -3875,4 +3875,131 @@ def Test_disassemble_assign_tuple_set_type()
|
|||||||
unlet g:instr
|
unlet g:instr
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
" Disassemble the code generated for a has() function call
|
||||||
|
def Test_disassemble_has_shortcircuit()
|
||||||
|
# true && false condition check
|
||||||
|
var lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Fn(): string
|
||||||
|
if has('jumplist') && has('foobar')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
g:instr = execute('disassemble Fn')
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
assert_match('<SNR>\d\+_Fn\_s*' ..
|
||||||
|
'if has(''jumplist'') && has(''foobar'')\_s*' ..
|
||||||
|
'return ''present''\_s*' ..
|
||||||
|
'endif\_s*' ..
|
||||||
|
'return ''missing''\_s*' ..
|
||||||
|
'0 PUSHS "missing"\_s*' ..
|
||||||
|
'1 RETURN', g:instr)
|
||||||
|
|
||||||
|
# false && true condition check
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Fn(): string
|
||||||
|
if has('foobar') && has('jumplist')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
g:instr = execute('disassemble Fn')
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
assert_match('<SNR>\d\+_Fn\_s*' ..
|
||||||
|
'if has(''foobar'') && has(''jumplist'')\_s*' ..
|
||||||
|
'return ''present''\_s*' ..
|
||||||
|
'endif\_s*' ..
|
||||||
|
'return ''missing''\_s*' ..
|
||||||
|
'0 PUSHS "missing"\_s*' ..
|
||||||
|
'1 RETURN', g:instr)
|
||||||
|
|
||||||
|
# false && false condition check
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Fn(): string
|
||||||
|
if has('foobar') && has('foobaz')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
g:instr = execute('disassemble Fn')
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
assert_match('<SNR>\d\+_Fn\_s*' ..
|
||||||
|
'if has(''foobar'') && has(''foobaz'')\_s*' ..
|
||||||
|
'return ''present''\_s*' ..
|
||||||
|
'endif\_s*' ..
|
||||||
|
'return ''missing''\_s*' ..
|
||||||
|
'0 PUSHS "missing"\_s*' ..
|
||||||
|
'1 RETURN', g:instr)
|
||||||
|
|
||||||
|
# true || false condition check
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Fn(): string
|
||||||
|
if has('jumplist') || has('foobar')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
g:instr = execute('disassemble Fn')
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
assert_match('<SNR>\d\+_Fn\_s*' ..
|
||||||
|
'if has(''jumplist'') || has(''foobar'')\_s*' ..
|
||||||
|
'return ''present''\_s*' ..
|
||||||
|
'0 PUSHS "present"\_s*' ..
|
||||||
|
'1 RETURN\_s*' ..
|
||||||
|
'endif\_s*' ..
|
||||||
|
'return ''missing''\_s*' ..
|
||||||
|
'2 PUSHS "missing"\_s*' ..
|
||||||
|
'3 RETURN', g:instr)
|
||||||
|
|
||||||
|
# false || true condition check
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Fn(): string
|
||||||
|
if has('foobar') || has('jumplist')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
g:instr = execute('disassemble Fn')
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
assert_match('<SNR>\d\+_Fn\_s*' ..
|
||||||
|
'if has(''foobar'') || has(''jumplist'')\_s*' ..
|
||||||
|
'return ''present''\_s*' ..
|
||||||
|
'0 PUSHS "present"\_s*' ..
|
||||||
|
'1 RETURN\_s*' ..
|
||||||
|
'endif\_s*' ..
|
||||||
|
'return ''missing''\_s*' ..
|
||||||
|
'2 PUSHS "missing"\_s*' ..
|
||||||
|
'3 RETURN', g:instr)
|
||||||
|
|
||||||
|
# false || false condition check
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Fn(): string
|
||||||
|
if has('foobar') || has('foobaz')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
g:instr = execute('disassemble Fn')
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
assert_match('<SNR>\d\+_Fn\_s*' ..
|
||||||
|
'if has(''foobar'') || has(''foobaz'')\_s*' ..
|
||||||
|
'return ''present''\_s*' ..
|
||||||
|
'endif\_s*' ..
|
||||||
|
'return ''missing''\_s*' ..
|
||||||
|
'0 PUSHS "missing"\_s*' ..
|
||||||
|
'1 RETURN', g:instr)
|
||||||
|
enddef
|
||||||
|
|
||||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
|||||||
@ -5265,6 +5265,102 @@ def Test_method_call_with_list_arg()
|
|||||||
v9.CheckSourceSuccess(lines)
|
v9.CheckSourceSuccess(lines)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
" Test for using more than one has() check in a compound if condition.
|
||||||
|
def Test_has_func_shortcircuit()
|
||||||
|
def Has_And1_Cond(): string
|
||||||
|
# true && false
|
||||||
|
if has('jumplist') && has('foobar')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
assert_equal('missing', Has_And1_Cond())
|
||||||
|
|
||||||
|
def Has_And2_Cond(): string
|
||||||
|
# false && true
|
||||||
|
if has('foobar') && has('jumplist')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
assert_equal('missing', Has_And2_Cond())
|
||||||
|
|
||||||
|
def Has_And3_Cond(): string
|
||||||
|
# false && false
|
||||||
|
if has('foobar') && has('foobaz')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
assert_equal('missing', Has_And3_Cond())
|
||||||
|
|
||||||
|
def Has_Or1_Cond(): string
|
||||||
|
# true || false
|
||||||
|
if has('jumplist') || has('foobar')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
assert_equal('present', Has_Or1_Cond())
|
||||||
|
|
||||||
|
def Has_Or2_Cond(): string
|
||||||
|
# false || true
|
||||||
|
if has('foobar') || has('jumplist')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
assert_equal('present', Has_Or2_Cond())
|
||||||
|
|
||||||
|
def Has_Or3_Cond(): string
|
||||||
|
# false || false
|
||||||
|
if has('foobar') || has('foobaz')
|
||||||
|
return 'present'
|
||||||
|
endif
|
||||||
|
return 'missing'
|
||||||
|
enddef
|
||||||
|
assert_equal('missing', Has_Or3_Cond())
|
||||||
|
enddef
|
||||||
|
|
||||||
|
" Test for using more than one len() function in a compound if condition.
|
||||||
|
def Test_len_func_shortcircuit()
|
||||||
|
def Len_And1_Cond(): string
|
||||||
|
# true && false
|
||||||
|
if len('xxx') == 3 && len('yyy') == 2
|
||||||
|
return 'match'
|
||||||
|
endif
|
||||||
|
return 'nomatch'
|
||||||
|
enddef
|
||||||
|
assert_equal('nomatch', Len_And1_Cond())
|
||||||
|
|
||||||
|
def Len_And2_Cond(): string
|
||||||
|
# false && true
|
||||||
|
if len('xxx') == 2 && len('yyy') == 3
|
||||||
|
return 'match'
|
||||||
|
endif
|
||||||
|
return 'nomatch'
|
||||||
|
enddef
|
||||||
|
assert_equal('nomatch', Len_And2_Cond())
|
||||||
|
|
||||||
|
def Len_Or1_Cond(): string
|
||||||
|
# true || false
|
||||||
|
if len('xxx') == 3 || len('yyy') == 2
|
||||||
|
return 'match'
|
||||||
|
endif
|
||||||
|
return 'nomatch'
|
||||||
|
enddef
|
||||||
|
assert_equal('match', Len_Or1_Cond())
|
||||||
|
|
||||||
|
def Len_Or2_Cond(): string
|
||||||
|
# false || true
|
||||||
|
if len('xxx') == 2 || len('yyy') == 3
|
||||||
|
return 'match'
|
||||||
|
endif
|
||||||
|
return 'nomatch'
|
||||||
|
enddef
|
||||||
|
assert_equal('match', Len_Or2_Cond())
|
||||||
|
enddef
|
||||||
|
|
||||||
" Keep this last, it messes up highlighting.
|
" Keep this last, it messes up highlighting.
|
||||||
def Test_substitute_cmd()
|
def Test_substitute_cmd()
|
||||||
new
|
new
|
||||||
|
|||||||
@ -719,6 +719,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 */
|
||||||
|
/**/
|
||||||
|
1546,
|
||||||
/**/
|
/**/
|
||||||
1545,
|
1545,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@ -1233,20 +1233,25 @@ compile_call(
|
|||||||
&& ((is_has && !dynamic_feature(argvars[0].vval.v_string))
|
&& ((is_has && !dynamic_feature(argvars[0].vval.v_string))
|
||||||
|| !is_has))
|
|| !is_has))
|
||||||
{
|
{
|
||||||
typval_T *tv = &ppconst->pp_tv[ppconst->pp_used];
|
|
||||||
|
|
||||||
*arg = s + 1;
|
*arg = s + 1;
|
||||||
argvars[1].v_type = VAR_UNKNOWN;
|
|
||||||
tv->v_type = VAR_NUMBER;
|
if (cctx->ctx_skip != SKIP_YES)
|
||||||
tv->vval.v_number = 0;
|
{
|
||||||
if (is_has)
|
typval_T *tv = &ppconst->pp_tv[ppconst->pp_used];
|
||||||
f_has(argvars, tv);
|
|
||||||
else if (is_len)
|
argvars[1].v_type = VAR_UNKNOWN;
|
||||||
f_len(argvars, tv);
|
tv->v_type = VAR_NUMBER;
|
||||||
else
|
tv->vval.v_number = 0;
|
||||||
f_exists(argvars, tv);
|
if (is_has)
|
||||||
|
f_has(argvars, tv);
|
||||||
|
else if (is_len)
|
||||||
|
f_len(argvars, tv);
|
||||||
|
else
|
||||||
|
f_exists(argvars, tv);
|
||||||
|
++ppconst->pp_used;
|
||||||
|
}
|
||||||
clear_tv(&argvars[0]);
|
clear_tv(&argvars[0]);
|
||||||
++ppconst->pp_used;
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
clear_tv(&argvars[0]);
|
clear_tv(&argvars[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user