diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-05-23 07:32:37 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-23 07:32:37 +0800 |
commit | 8802bf875a497d1ce47d74cc2fa33d3ab28c11c0 (patch) | |
tree | da83f728d2e6fe6c2bb49708dc9126f4f7d5c3c7 /src | |
parent | a599183a274e5102b1244c9aaa7ac6c76d5ba5df (diff) | |
download | rneovim-8802bf875a497d1ce47d74cc2fa33d3ab28c11c0.tar.gz rneovim-8802bf875a497d1ce47d74cc2fa33d3ab28c11c0.tar.bz2 rneovim-8802bf875a497d1ce47d74cc2fa33d3ab28c11c0.zip |
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)
https://github.com/vim/vim/commit/ea125393af01ecaf75cee8e085a57f8143f3ae3e
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 152 |
1 files changed, 88 insertions, 64 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2f774f7b9d..18e5dc7cbd 100644 --- a/src/nvim/eval.c +++ b/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; } +/// 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". /// /// @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; switch (tv->v_type) { - case VAR_DICT: { - dict_T *dd = tv->vval.v_dict; - if (dd != NULL && dd->dv_copyID != copyID) { - // Didn't see this dict yet. - 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_DICT: + return set_ref_in_item_dict(tv->vval.v_dict, copyID, ht_stack, list_stack); + case VAR_LIST: + return set_ref_in_item_list(tv->vval.v_list, copyID, ht_stack, list_stack); case VAR_FUNC: abort = set_ref_in_func(tv->vval.v_string, NULL, copyID); break; + case VAR_PARTIAL: + return set_ref_in_item_partial(tv->vval.v_partial, copyID, ht_stack, list_stack); case VAR_UNKNOWN: case VAR_BOOL: case VAR_SPECIAL: |