mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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:
parent
edce68912e
commit
8de753148f
@ -3875,4 +3875,131 @@ def Test_disassemble_assign_tuple_set_type()
|
||||
unlet g:instr
|
||||
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
|
||||
|
@ -5265,6 +5265,102 @@ def Test_method_call_with_list_arg()
|
||||
v9.CheckSourceSuccess(lines)
|
||||
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.
|
||||
def Test_substitute_cmd()
|
||||
new
|
||||
|
@ -719,6 +719,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1546,
|
||||
/**/
|
||||
1545,
|
||||
/**/
|
||||
|
@ -1233,20 +1233,25 @@ compile_call(
|
||||
&& ((is_has && !dynamic_feature(argvars[0].vval.v_string))
|
||||
|| !is_has))
|
||||
{
|
||||
typval_T *tv = &ppconst->pp_tv[ppconst->pp_used];
|
||||
|
||||
*arg = s + 1;
|
||||
argvars[1].v_type = VAR_UNKNOWN;
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->vval.v_number = 0;
|
||||
if (is_has)
|
||||
f_has(argvars, tv);
|
||||
else if (is_len)
|
||||
f_len(argvars, tv);
|
||||
else
|
||||
f_exists(argvars, tv);
|
||||
|
||||
if (cctx->ctx_skip != SKIP_YES)
|
||||
{
|
||||
typval_T *tv = &ppconst->pp_tv[ppconst->pp_used];
|
||||
|
||||
argvars[1].v_type = VAR_UNKNOWN;
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->vval.v_number = 0;
|
||||
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]);
|
||||
++ppconst->pp_used;
|
||||
return OK;
|
||||
}
|
||||
clear_tv(&argvars[0]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user