mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:9.0.1175: the set_ref_in_item() function is too long (#28926)
Problem: The set_ref_in_item() function is too long.
Solution: Use a separate function for more complicated types. (Yegappan
Lakshmanan, closes vim/vim#11802)
ea125393af
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
parent
a599183a27
commit
8802bf875a
152
src/nvim/eval.c
152
src/nvim/eval.c
@ -4778,6 +4778,88 @@ bool set_ref_in_list_items(list_T *l, int copyID, ht_stack_T **ht_stack)
|
|||||||
return abort;
|
return abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark the dict "dd" with "copyID".
|
||||||
|
/// Also see set_ref_in_item().
|
||||||
|
static bool set_ref_in_item_dict(dict_T *dd, int copyID, ht_stack_T **ht_stack,
|
||||||
|
list_stack_T **list_stack)
|
||||||
|
{
|
||||||
|
if (dd == NULL || dd->dv_copyID == copyID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't see this dict yet.
|
||||||
|
dd->dv_copyID = copyID;
|
||||||
|
if (ht_stack == NULL) {
|
||||||
|
return set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T));
|
||||||
|
newitem->ht = &dd->dv_hashtab;
|
||||||
|
newitem->prev = *ht_stack;
|
||||||
|
*ht_stack = newitem;
|
||||||
|
|
||||||
|
QUEUE *w = NULL;
|
||||||
|
DictWatcher *watcher = NULL;
|
||||||
|
QUEUE_FOREACH(w, &dd->watchers, {
|
||||||
|
watcher = tv_dict_watcher_node_data(w);
|
||||||
|
set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack);
|
||||||
|
})
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark the list "ll" with "copyID".
|
||||||
|
/// Also see set_ref_in_item().
|
||||||
|
static bool set_ref_in_item_list(list_T *ll, int copyID, ht_stack_T **ht_stack,
|
||||||
|
list_stack_T **list_stack)
|
||||||
|
{
|
||||||
|
if (ll == NULL || ll->lv_copyID == copyID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't see this list yet.
|
||||||
|
ll->lv_copyID = copyID;
|
||||||
|
if (list_stack == NULL) {
|
||||||
|
return set_ref_in_list_items(ll, copyID, ht_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_stack_T *const newitem = xmalloc(sizeof(list_stack_T));
|
||||||
|
newitem->list = ll;
|
||||||
|
newitem->prev = *list_stack;
|
||||||
|
*list_stack = newitem;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark the partial "pt" with "copyID".
|
||||||
|
/// Also see set_ref_in_item().
|
||||||
|
static bool set_ref_in_item_partial(partial_T *pt, int copyID, ht_stack_T **ht_stack,
|
||||||
|
list_stack_T **list_stack)
|
||||||
|
{
|
||||||
|
if (pt == NULL || pt->pt_copyID == copyID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't see this partial yet.
|
||||||
|
pt->pt_copyID = copyID;
|
||||||
|
|
||||||
|
bool abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
|
||||||
|
|
||||||
|
if (pt->pt_dict != NULL) {
|
||||||
|
typval_T dtv;
|
||||||
|
|
||||||
|
dtv.v_type = VAR_DICT;
|
||||||
|
dtv.vval.v_dict = pt->pt_dict;
|
||||||
|
abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < pt->pt_argc; i++) {
|
||||||
|
abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID, ht_stack, list_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
|
|
||||||
/// Mark all lists and dicts referenced through typval "tv" with "copyID".
|
/// Mark all lists and dicts referenced through typval "tv" with "copyID".
|
||||||
///
|
///
|
||||||
/// @param tv Typval content will be marked.
|
/// @param tv Typval content will be marked.
|
||||||
@ -4792,73 +4874,15 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack
|
|||||||
bool abort = false;
|
bool abort = false;
|
||||||
|
|
||||||
switch (tv->v_type) {
|
switch (tv->v_type) {
|
||||||
case VAR_DICT: {
|
case VAR_DICT:
|
||||||
dict_T *dd = tv->vval.v_dict;
|
return set_ref_in_item_dict(tv->vval.v_dict, copyID, ht_stack, list_stack);
|
||||||
if (dd != NULL && dd->dv_copyID != copyID) {
|
case VAR_LIST:
|
||||||
// Didn't see this dict yet.
|
return set_ref_in_item_list(tv->vval.v_list, copyID, ht_stack, list_stack);
|
||||||
dd->dv_copyID = copyID;
|
|
||||||
if (ht_stack == NULL) {
|
|
||||||
abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
|
|
||||||
} else {
|
|
||||||
ht_stack_T *const newitem = xmalloc(sizeof(ht_stack_T));
|
|
||||||
newitem->ht = &dd->dv_hashtab;
|
|
||||||
newitem->prev = *ht_stack;
|
|
||||||
*ht_stack = newitem;
|
|
||||||
}
|
|
||||||
|
|
||||||
QUEUE *w = NULL;
|
|
||||||
DictWatcher *watcher = NULL;
|
|
||||||
QUEUE_FOREACH(w, &dd->watchers, {
|
|
||||||
watcher = tv_dict_watcher_node_data(w);
|
|
||||||
set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VAR_LIST: {
|
|
||||||
list_T *ll = tv->vval.v_list;
|
|
||||||
if (ll != NULL && ll->lv_copyID != copyID) {
|
|
||||||
// Didn't see this list yet.
|
|
||||||
ll->lv_copyID = copyID;
|
|
||||||
if (list_stack == NULL) {
|
|
||||||
abort = set_ref_in_list_items(ll, copyID, ht_stack);
|
|
||||||
} else {
|
|
||||||
list_stack_T *const newitem = xmalloc(sizeof(list_stack_T));
|
|
||||||
newitem->list = ll;
|
|
||||||
newitem->prev = *list_stack;
|
|
||||||
*list_stack = newitem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case VAR_PARTIAL: {
|
|
||||||
partial_T *pt = tv->vval.v_partial;
|
|
||||||
|
|
||||||
if (pt != NULL && pt->pt_copyID != copyID) {
|
|
||||||
// Didn't see this partial yet.
|
|
||||||
pt->pt_copyID = copyID;
|
|
||||||
|
|
||||||
abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
|
|
||||||
if (pt->pt_dict != NULL) {
|
|
||||||
typval_T dtv;
|
|
||||||
|
|
||||||
dtv.v_type = VAR_DICT;
|
|
||||||
dtv.vval.v_dict = pt->pt_dict;
|
|
||||||
abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < pt->pt_argc; i++) {
|
|
||||||
abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
|
|
||||||
ht_stack, list_stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
|
abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
|
||||||
break;
|
break;
|
||||||
|
case VAR_PARTIAL:
|
||||||
|
return set_ref_in_item_partial(tv->vval.v_partial, copyID, ht_stack, list_stack);
|
||||||
case VAR_UNKNOWN:
|
case VAR_UNKNOWN:
|
||||||
case VAR_BOOL:
|
case VAR_BOOL:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
|
Loading…
Reference in New Issue
Block a user