mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 8.1.1044: no way to check the reference count of objects
Problem: No way to check the reference count of objects. Solution: Add test_refcount(). (Ozaki Kiichi, closes #4124)
This commit is contained in:
@@ -2672,6 +2672,7 @@ test_null_partial() Funcref null value for testing
|
|||||||
test_null_string() String null value for testing
|
test_null_string() String null value for testing
|
||||||
test_option_not_set({name}) none reset flag indicating option was set
|
test_option_not_set({name}) none reset flag indicating option was set
|
||||||
test_override({expr}, {val}) none test with Vim internal overrides
|
test_override({expr}, {val}) none test with Vim internal overrides
|
||||||
|
test_refcount({expr}) Number get the reference count of {expr}
|
||||||
test_scrollbar({which}, {value}, {dragging})
|
test_scrollbar({which}, {value}, {dragging})
|
||||||
none scroll in the GUI for testing
|
none scroll in the GUI for testing
|
||||||
test_settime({expr}) none set current time for testing
|
test_settime({expr}) none set current time for testing
|
||||||
@@ -9589,6 +9590,11 @@ test_override({name}, {val}) *test_override()*
|
|||||||
< The value of "starting" is saved. It is restored by: >
|
< The value of "starting" is saved. It is restored by: >
|
||||||
call test_override('starting', 0)
|
call test_override('starting', 0)
|
||||||
|
|
||||||
|
test_refcount({expr}) *test_refcount()*
|
||||||
|
Return the reference count of {expr}. When {expr} is of a
|
||||||
|
type that does not have a reference count, returns -1. Only
|
||||||
|
to be used for testing.
|
||||||
|
|
||||||
test_scrollbar({which}, {value}, {dragging}) *test_scrollbar()*
|
test_scrollbar({which}, {value}, {dragging}) *test_scrollbar()*
|
||||||
Pretend using scrollbar {which} to move it to position
|
Pretend using scrollbar {which} to move it to position
|
||||||
{value}. {which} can be:
|
{value}. {which} can be:
|
||||||
|
@@ -428,6 +428,7 @@ static void f_test_autochdir(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_test_feedinput(typval_T *argvars, typval_T *rettv);
|
static void f_test_feedinput(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_option_not_set(typval_T *argvars, typval_T *rettv);
|
static void f_test_option_not_set(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_override(typval_T *argvars, typval_T *rettv);
|
static void f_test_override(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_test_refcount(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
|
static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
|
static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_test_null_blob(typval_T *argvars, typval_T *rettv);
|
static void f_test_null_blob(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -965,6 +966,7 @@ static struct fst
|
|||||||
{"test_null_string", 0, 0, f_test_null_string},
|
{"test_null_string", 0, 0, f_test_null_string},
|
||||||
{"test_option_not_set", 1, 1, f_test_option_not_set},
|
{"test_option_not_set", 1, 1, f_test_option_not_set},
|
||||||
{"test_override", 2, 2, f_test_override},
|
{"test_override", 2, 2, f_test_override},
|
||||||
|
{"test_refcount", 1, 1, f_test_refcount},
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
{"test_scrollbar", 3, 3, f_test_scrollbar},
|
{"test_scrollbar", 3, 3, f_test_scrollbar},
|
||||||
#endif
|
#endif
|
||||||
@@ -13846,6 +13848,67 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "test_refcount({expr})" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_test_refcount(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
switch (argvars[0].v_type)
|
||||||
|
{
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
case VAR_NUMBER:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_SPECIAL:
|
||||||
|
case VAR_STRING:
|
||||||
|
break;
|
||||||
|
case VAR_JOB:
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (argvars[0].vval.v_job != NULL)
|
||||||
|
retval = argvars[0].vval.v_job->jv_refcount - 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case VAR_CHANNEL:
|
||||||
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
|
if (argvars[0].vval.v_channel != NULL)
|
||||||
|
retval = argvars[0].vval.v_channel->ch_refcount - 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case VAR_FUNC:
|
||||||
|
if (argvars[0].vval.v_string != NULL)
|
||||||
|
{
|
||||||
|
ufunc_T *fp;
|
||||||
|
|
||||||
|
fp = find_func(argvars[0].vval.v_string);
|
||||||
|
if (fp != NULL)
|
||||||
|
retval = fp->uf_refcount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VAR_PARTIAL:
|
||||||
|
if (argvars[0].vval.v_partial != NULL)
|
||||||
|
retval = argvars[0].vval.v_partial->pt_refcount - 1;
|
||||||
|
break;
|
||||||
|
case VAR_BLOB:
|
||||||
|
if (argvars[0].vval.v_blob != NULL)
|
||||||
|
retval = argvars[0].vval.v_blob->bv_refcount - 1;
|
||||||
|
break;
|
||||||
|
case VAR_LIST:
|
||||||
|
if (argvars[0].vval.v_list != NULL)
|
||||||
|
retval = argvars[0].vval.v_list->lv_refcount - 1;
|
||||||
|
break;
|
||||||
|
case VAR_DICT:
|
||||||
|
if (argvars[0].vval.v_dict != NULL)
|
||||||
|
retval = argvars[0].vval.v_dict->dv_refcount - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rettv->v_type = VAR_NUMBER;
|
||||||
|
rettv->vval.v_number = retval;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "test_garbagecollect_now()" function
|
* "test_garbagecollect_now()" function
|
||||||
*/
|
*/
|
||||||
|
@@ -1556,6 +1556,115 @@ func Test_compound_assignment_operators()
|
|||||||
let @/ = ''
|
let @/ = ''
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_refcount()
|
||||||
|
" Immediate values
|
||||||
|
call assert_equal(-1, test_refcount(1))
|
||||||
|
call assert_equal(-1, test_refcount('s'))
|
||||||
|
call assert_equal(-1, test_refcount(v:true))
|
||||||
|
call assert_equal(0, test_refcount([]))
|
||||||
|
call assert_equal(0, test_refcount({}))
|
||||||
|
call assert_equal(0, test_refcount(0zff))
|
||||||
|
call assert_equal(0, test_refcount({-> line('.')}))
|
||||||
|
if has('float')
|
||||||
|
call assert_equal(-1, test_refcount(0.1))
|
||||||
|
endif
|
||||||
|
if has('job')
|
||||||
|
call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
|
||||||
|
endif
|
||||||
|
|
||||||
|
" No refcount types
|
||||||
|
let x = 1
|
||||||
|
call assert_equal(-1, test_refcount(x))
|
||||||
|
let x = 's'
|
||||||
|
call assert_equal(-1, test_refcount(x))
|
||||||
|
let x = v:true
|
||||||
|
call assert_equal(-1, test_refcount(x))
|
||||||
|
if has('float')
|
||||||
|
let x = 0.1
|
||||||
|
call assert_equal(-1, test_refcount(x))
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Check refcount
|
||||||
|
let x = []
|
||||||
|
call assert_equal(1, test_refcount(x))
|
||||||
|
|
||||||
|
let x = {}
|
||||||
|
call assert_equal(1, test_refcount(x))
|
||||||
|
|
||||||
|
let x = 0zff
|
||||||
|
call assert_equal(1, test_refcount(x))
|
||||||
|
|
||||||
|
let X = {-> line('.')}
|
||||||
|
call assert_equal(1, test_refcount(X))
|
||||||
|
let Y = X
|
||||||
|
call assert_equal(2, test_refcount(X))
|
||||||
|
|
||||||
|
if has('job')
|
||||||
|
let job = job_start([&shell, &shellcmdflag, 'echo .'])
|
||||||
|
call assert_equal(1, test_refcount(job))
|
||||||
|
call assert_equal(1, test_refcount(job_getchannel(job)))
|
||||||
|
call assert_equal(1, test_refcount(job))
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Function arguments, copying and unassigning
|
||||||
|
func ExprCheck(x, i)
|
||||||
|
let i = a:i + 1
|
||||||
|
call assert_equal(i, test_refcount(a:x))
|
||||||
|
let Y = a:x
|
||||||
|
call assert_equal(i + 1, test_refcount(a:x))
|
||||||
|
call assert_equal(test_refcount(a:x), test_refcount(Y))
|
||||||
|
let Y = 0
|
||||||
|
call assert_equal(i, test_refcount(a:x))
|
||||||
|
endfunc
|
||||||
|
call ExprCheck([], 0)
|
||||||
|
call ExprCheck({}, 0)
|
||||||
|
call ExprCheck(0zff, 0)
|
||||||
|
call ExprCheck({-> line('.')}, 0)
|
||||||
|
if has('job')
|
||||||
|
call ExprCheck(job, 1)
|
||||||
|
call ExprCheck(job_getchannel(job), 1)
|
||||||
|
call job_stop(job)
|
||||||
|
endif
|
||||||
|
delfunc ExprCheck
|
||||||
|
|
||||||
|
" Regarding function
|
||||||
|
func Func(x) abort
|
||||||
|
call assert_equal(2, test_refcount(function('Func')))
|
||||||
|
call assert_equal(0, test_refcount(funcref('Func')))
|
||||||
|
endfunc
|
||||||
|
call assert_equal(1, test_refcount(function('Func')))
|
||||||
|
call assert_equal(0, test_refcount(function('Func', [1])))
|
||||||
|
call assert_equal(0, test_refcount(funcref('Func')))
|
||||||
|
call assert_equal(0, test_refcount(funcref('Func', [1])))
|
||||||
|
let X = function('Func')
|
||||||
|
let Y = X
|
||||||
|
call assert_equal(1, test_refcount(X))
|
||||||
|
let X = function('Func', [1])
|
||||||
|
let Y = X
|
||||||
|
call assert_equal(2, test_refcount(X))
|
||||||
|
let X = funcref('Func')
|
||||||
|
let Y = X
|
||||||
|
call assert_equal(2, test_refcount(X))
|
||||||
|
let X = funcref('Func', [1])
|
||||||
|
let Y = X
|
||||||
|
call assert_equal(2, test_refcount(X))
|
||||||
|
unlet X
|
||||||
|
unlet Y
|
||||||
|
call Func(1)
|
||||||
|
delfunc Func
|
||||||
|
|
||||||
|
" Function with dict
|
||||||
|
func DictFunc() dict
|
||||||
|
call assert_equal(3, test_refcount(self))
|
||||||
|
endfunc
|
||||||
|
let d = {'Func': function('DictFunc')}
|
||||||
|
call assert_equal(1, test_refcount(d))
|
||||||
|
call assert_equal(0, test_refcount(d.Func))
|
||||||
|
call d.Func()
|
||||||
|
unlet d
|
||||||
|
delfunc DictFunc
|
||||||
|
endfunc
|
||||||
|
|
||||||
"-------------------------------------------------------------------------------
|
"-------------------------------------------------------------------------------
|
||||||
" Modelines {{{1
|
" Modelines {{{1
|
||||||
" vim: ts=8 sw=4 tw=80 fdm=marker
|
" vim: ts=8 sw=4 tw=80 fdm=marker
|
||||||
|
@@ -775,6 +775,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 */
|
||||||
|
/**/
|
||||||
|
1044,
|
||||||
/**/
|
/**/
|
||||||
1043,
|
1043,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user