chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* lsp_node_iter.h — O(n) child enumeration for the per-language LSP walkers.
|
||||
*
|
||||
* tree-sitter's ts_node_child(node, i) is O(i): it walks the child iterator
|
||||
* from the first child every call. So the common idiom
|
||||
*
|
||||
* uint32_t nc = ts_node_child_count(node);
|
||||
* for (uint32_t i = 0; i < nc; i++) { TSNode c = ts_node_child(node, i); ... }
|
||||
*
|
||||
* is O(n²) over a node's children — catastrophic on a wide root (e.g. a program
|
||||
* node holding hundreds of thousands of top-level statements, as in TS's
|
||||
* reallyLargeFile.ts fixture: 583K comment lines made the per-file LSP passes
|
||||
* run for ~133 minutes). cbm_lsp_collect_children() enumerates the children in
|
||||
* a single O(n) cursor pass into an arena array; callers then index the array.
|
||||
*/
|
||||
#ifndef CBM_LSP_NODE_ITER_H
|
||||
#define CBM_LSP_NODE_ITER_H
|
||||
|
||||
#include "../arena.h"
|
||||
#include "tree_sitter/api.h"
|
||||
|
||||
/* Collect `node`'s children into an arena array (source order) via one O(n)
|
||||
* cursor pass. Returns NULL and sets *out_n=0 for a childless node or on OOM. */
|
||||
static inline TSNode* cbm_lsp_collect_children(CBMArena* arena, TSNode node, uint32_t* out_n) {
|
||||
uint32_t nc = ts_node_child_count(node);
|
||||
*out_n = 0;
|
||||
if (nc == 0) return NULL;
|
||||
TSNode* kids = (TSNode*)cbm_arena_alloc(arena, (size_t)nc * sizeof(TSNode));
|
||||
if (!kids) return NULL;
|
||||
uint32_t kn = 0;
|
||||
TSTreeCursor cur = ts_tree_cursor_new(node);
|
||||
if (ts_tree_cursor_goto_first_child(&cur)) {
|
||||
do {
|
||||
kids[kn++] = ts_tree_cursor_current_node(&cur);
|
||||
} while (kn < nc && ts_tree_cursor_goto_next_sibling(&cur));
|
||||
}
|
||||
ts_tree_cursor_delete(&cur);
|
||||
*out_n = kn;
|
||||
return kids;
|
||||
}
|
||||
|
||||
#endif /* CBM_LSP_NODE_ITER_H */
|
||||
Reference in New Issue
Block a user