@@ -19,6 +19,7 @@ static const uint32_t FIELD_COUNT_PER_NODE = 6;
1919static uint32_t *transfer_buffer = NULL ;
2020static uint32_t transfer_buffer_length = 0 ;
2121static Nan::Persistent<Object> module_exports;
22+ static TSTreeCursor scratch_cursor = {{0 , 0 }, 0 , 0 };
2223
2324static inline void setup_transfer_buffer (uint32_t node_count) {
2425 uint32_t new_length = node_count * FIELD_COUNT_PER_NODE;
@@ -477,6 +478,42 @@ bool symbol_set_from_js(SymbolSet *symbols, const Local<Value> &value, const TSL
477478 return true ;
478479}
479480
481+ static void Children (const Nan::FunctionCallbackInfo<Value> &info) {
482+ const Tree *tree = Tree::UnwrapTree (info[0 ]);
483+ TSNode node = UnmarshalNode (tree);
484+ if (!node.id ) return ;
485+
486+ vector<TSNode> result;
487+ ts_tree_cursor_reset (&scratch_cursor, node);
488+ if (ts_tree_cursor_goto_first_child (&scratch_cursor)) {
489+ do {
490+ TSNode child = ts_tree_cursor_current_node (&scratch_cursor);
491+ result.push_back (child);
492+ } while (ts_tree_cursor_goto_next_sibling (&scratch_cursor));
493+ }
494+
495+ MarshalNodes (info, tree, result.data (), result.size ());
496+ }
497+
498+ static void NamedChildren (const Nan::FunctionCallbackInfo<Value> &info) {
499+ const Tree *tree = Tree::UnwrapTree (info[0 ]);
500+ TSNode node = UnmarshalNode (tree);
501+ if (!node.id ) return ;
502+
503+ vector<TSNode> result;
504+ ts_tree_cursor_reset (&scratch_cursor, node);
505+ if (ts_tree_cursor_goto_first_child (&scratch_cursor)) {
506+ do {
507+ TSNode child = ts_tree_cursor_current_node (&scratch_cursor);
508+ if (ts_node_is_named (child)) {
509+ result.push_back (child);
510+ }
511+ } while (ts_tree_cursor_goto_next_sibling (&scratch_cursor));
512+ }
513+
514+ MarshalNodes (info, tree, result.data (), result.size ());
515+ }
516+
480517static void DescendantsOfType (const Nan::FunctionCallbackInfo<Value> &info) {
481518 const Tree *tree = Tree::UnwrapTree (info[0 ]);
482519 TSNode node = UnmarshalNode (tree);
@@ -501,17 +538,17 @@ static void DescendantsOfType(const Nan::FunctionCallbackInfo<Value> &info) {
501538 }
502539
503540 vector<TSNode> found;
504- TSTreeCursor cursor = ts_tree_cursor_new ( node);
541+ ts_tree_cursor_reset (&scratch_cursor, node);
505542 auto already_visited_children = false ;
506543 while (true ) {
507- TSNode descendant = ts_tree_cursor_current_node (&cursor );
544+ TSNode descendant = ts_tree_cursor_current_node (&scratch_cursor );
508545
509546 if (!already_visited_children) {
510547 if (ts_node_end_point (descendant) <= start_point) {
511- if (ts_tree_cursor_goto_next_sibling (&cursor )) {
548+ if (ts_tree_cursor_goto_next_sibling (&scratch_cursor )) {
512549 already_visited_children = false ;
513550 } else {
514- if (!ts_tree_cursor_goto_parent (&cursor )) break ;
551+ if (!ts_tree_cursor_goto_parent (&scratch_cursor )) break ;
515552 already_visited_children = true ;
516553 }
517554 continue ;
@@ -523,24 +560,23 @@ static void DescendantsOfType(const Nan::FunctionCallbackInfo<Value> &info) {
523560 found.push_back (descendant);
524561 }
525562
526- if (ts_tree_cursor_goto_first_child (&cursor )) {
563+ if (ts_tree_cursor_goto_first_child (&scratch_cursor )) {
527564 already_visited_children = false ;
528- } else if (ts_tree_cursor_goto_next_sibling (&cursor )) {
565+ } else if (ts_tree_cursor_goto_next_sibling (&scratch_cursor )) {
529566 already_visited_children = false ;
530567 } else {
531- if (!ts_tree_cursor_goto_parent (&cursor )) break ;
568+ if (!ts_tree_cursor_goto_parent (&scratch_cursor )) break ;
532569 already_visited_children = true ;
533570 }
534571 } else {
535- if (ts_tree_cursor_goto_next_sibling (&cursor )) {
572+ if (ts_tree_cursor_goto_next_sibling (&scratch_cursor )) {
536573 already_visited_children = false ;
537574 } else {
538- if (!ts_tree_cursor_goto_parent (&cursor )) break ;
575+ if (!ts_tree_cursor_goto_parent (&scratch_cursor )) break ;
539576 }
540577 }
541578 }
542579
543- ts_tree_cursor_delete (&cursor);
544580 MarshalNodes (info, tree, found.data (), found.size ());
545581}
546582
@@ -583,6 +619,8 @@ void Init(Local<Object> exports) {
583619 {" parent" , Parent},
584620 {" child" , Child},
585621 {" namedChild" , NamedChild},
622+ {" children" , Children},
623+ {" namedChildren" , NamedChildren},
586624 {" childCount" , ChildCount},
587625 {" namedChildCount" , NamedChildCount},
588626 {" firstChild" , FirstChild},
0 commit comments