mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.0399: using :defer in expression funcref not tested
Problem: Using :defer in expression funcref not tested. Solution: Add a test. Fix uncovered problems.
This commit is contained in:
@@ -4,6 +4,8 @@ void update_has_breakpoint(ufunc_T *ufunc);
|
|||||||
void funcstack_check_refcount(funcstack_T *funcstack);
|
void funcstack_check_refcount(funcstack_T *funcstack);
|
||||||
int set_ref_in_funcstacks(int copyID);
|
int set_ref_in_funcstacks(int copyID);
|
||||||
int in_def_function(void);
|
int in_def_function(void);
|
||||||
|
ectx_T *clear_currrent_ectx(void);
|
||||||
|
void restore_current_ectx(ectx_T *ectx);
|
||||||
int add_defer_function(char_u *name, int argcount, typval_T *argvars);
|
int add_defer_function(char_u *name, int argcount, typval_T *argvars);
|
||||||
char_u *char_from_string(char_u *str, varnumber_T index);
|
char_u *char_from_string(char_u *str, varnumber_T index);
|
||||||
char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive);
|
char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive);
|
||||||
|
@@ -625,5 +625,37 @@ func Test_defer_quitall()
|
|||||||
call assert_false(filereadable('XQuitallTwo'))
|
call assert_false(filereadable('XQuitallTwo'))
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func FuncIndex(idx, val)
|
||||||
|
call writefile([a:idx .. ': ' .. a:val], 'Xentry' .. a:idx, 'D')
|
||||||
|
return a:val == 'c'
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
def DefIndex(idx: number, val: string): bool
|
||||||
|
call writefile([idx .. ': ' .. val], 'Xentry' .. idx, 'D')
|
||||||
|
return val == 'c'
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_defer_in_funcref()
|
||||||
|
assert_equal(2, indexof(['a', 'b', 'c'], function('g:FuncIndex')))
|
||||||
|
assert_false(filereadable('Xentry0'))
|
||||||
|
assert_false(filereadable('Xentry1'))
|
||||||
|
assert_false(filereadable('Xentry2'))
|
||||||
|
|
||||||
|
assert_equal(2, indexof(['a', 'b', 'c'], g:DefIndex))
|
||||||
|
assert_false(filereadable('Xentry0'))
|
||||||
|
assert_false(filereadable('Xentry1'))
|
||||||
|
assert_false(filereadable('Xentry2'))
|
||||||
|
|
||||||
|
assert_equal(2, indexof(['a', 'b', 'c'], function('g:DefIndex')))
|
||||||
|
assert_false(filereadable('Xentry0'))
|
||||||
|
assert_false(filereadable('Xentry1'))
|
||||||
|
assert_false(filereadable('Xentry2'))
|
||||||
|
|
||||||
|
assert_equal(2, indexof(['a', 'b', 'c'], funcref(g:DefIndex)))
|
||||||
|
assert_false(filereadable('Xentry0'))
|
||||||
|
assert_false(filereadable('Xentry1'))
|
||||||
|
assert_false(filereadable('Xentry2'))
|
||||||
|
enddef
|
||||||
|
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -2593,6 +2593,7 @@ call_user_func(
|
|||||||
dict_T *selfdict) // Dictionary for "self"
|
dict_T *selfdict) // Dictionary for "self"
|
||||||
{
|
{
|
||||||
sctx_T save_current_sctx;
|
sctx_T save_current_sctx;
|
||||||
|
ectx_T *save_current_ectx;
|
||||||
int using_sandbox = FALSE;
|
int using_sandbox = FALSE;
|
||||||
int save_sticky_cmdmod_flags = sticky_cmdmod_flags;
|
int save_sticky_cmdmod_flags = sticky_cmdmod_flags;
|
||||||
funccall_T *fc;
|
funccall_T *fc;
|
||||||
@@ -2669,9 +2670,9 @@ call_user_func(
|
|||||||
islambda = fp->uf_flags & FC_LAMBDA;
|
islambda = fp->uf_flags & FC_LAMBDA;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note about using fc->fc_fixvar[]: This is an array of FIXVAR_CNT variables
|
* Note about using fc->fc_fixvar[]: This is an array of FIXVAR_CNT
|
||||||
* with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
|
* variables with names up to VAR_SHORT_LEN long. This avoids having to
|
||||||
* each argument variable and saves a lot of time.
|
* alloc/free each argument variable and saves a lot of time.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Init l: variables.
|
* Init l: variables.
|
||||||
@@ -2885,6 +2886,11 @@ call_user_func(
|
|||||||
// "legacy" does not apply to commands in the function
|
// "legacy" does not apply to commands in the function
|
||||||
sticky_cmdmod_flags = 0;
|
sticky_cmdmod_flags = 0;
|
||||||
|
|
||||||
|
// If called from a compiled :def function the execution context must be
|
||||||
|
// hidden, any deferred functions need to be added to the function being
|
||||||
|
// executed here.
|
||||||
|
save_current_ectx = clear_currrent_ectx();
|
||||||
|
|
||||||
save_current_sctx = current_sctx;
|
save_current_sctx = current_sctx;
|
||||||
current_sctx = fp->uf_script_ctx;
|
current_sctx = fp->uf_script_ctx;
|
||||||
save_did_emsg = did_emsg;
|
save_did_emsg = did_emsg;
|
||||||
@@ -2974,6 +2980,8 @@ call_user_func(
|
|||||||
ESTACK_CHECK_NOW
|
ESTACK_CHECK_NOW
|
||||||
estack_pop();
|
estack_pop();
|
||||||
current_sctx = save_current_sctx;
|
current_sctx = save_current_sctx;
|
||||||
|
restore_current_ectx(save_current_ectx);
|
||||||
|
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES)
|
||||||
script_prof_restore(&profile_info.pi_wait_start);
|
script_prof_restore(&profile_info.pi_wait_start);
|
||||||
|
@@ -703,6 +703,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 */
|
||||||
|
/**/
|
||||||
|
399,
|
||||||
/**/
|
/**/
|
||||||
398,
|
398,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -859,6 +859,27 @@ in_def_function(void)
|
|||||||
return current_ectx != NULL;
|
return current_ectx != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear "current_ectx" and return the previous value. To be used when calling
|
||||||
|
* a user function.
|
||||||
|
*/
|
||||||
|
ectx_T *
|
||||||
|
clear_currrent_ectx(void)
|
||||||
|
{
|
||||||
|
ectx_T *r = current_ectx;
|
||||||
|
|
||||||
|
current_ectx = NULL;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
restore_current_ectx(ectx_T *ectx)
|
||||||
|
{
|
||||||
|
if (current_ectx != NULL)
|
||||||
|
iemsg("Restoring current_ectx while it is not NULL");
|
||||||
|
current_ectx = ectx;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add an entry for a deferred function call to the currently executing
|
* Add an entry for a deferred function call to the currently executing
|
||||||
* function.
|
* function.
|
||||||
|
Reference in New Issue
Block a user