Skip to content

Commit 4a2f804

Browse files
committed
Optimize .children and .namedChildren getters
1 parent 5e9af6b commit 4a2f804

File tree

3 files changed

+57
-23
lines changed

3 files changed

+57
-23
lines changed

index.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,17 @@ class SyntaxNode {
9292
}
9393

9494
get children() {
95-
const {childCount} = this;
96-
const result = new Array(childCount);
97-
for (let i = 0; i < childCount; i++) {
98-
result[i] = this.child(i);
99-
}
100-
return result;
95+
marshalNode(this);
96+
const nodes = NodeMethods.children(this.tree);
97+
unmarshalNodes(this.tree, nodes);
98+
return nodes
10199
}
102100

103101
get namedChildren() {
104-
const {namedChildCount} = this;
105-
const result = new Array(namedChildCount);
106-
for (let i = 0; i < namedChildCount; i++) {
107-
result[i] = this.namedChild(i);
108-
}
109-
return result;
102+
marshalNode(this);
103+
const nodes = NodeMethods.namedChildren(this.tree);
104+
unmarshalNodes(this.tree, nodes);
105+
return nodes
110106
}
111107

112108
get childCount() {

src/node.cc

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ static const uint32_t FIELD_COUNT_PER_NODE = 6;
1919
static uint32_t *transfer_buffer = NULL;
2020
static uint32_t transfer_buffer_length = 0;
2121
static Nan::Persistent<Object> module_exports;
22+
static TSTreeCursor scratch_cursor = {{0, 0}, 0, 0};
2223

2324
static 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+
480517
static 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},

vendor/tree-sitter

0 commit comments

Comments
 (0)