Skip to content

Commit 56d34f0

Browse files
committed
Add TsQuery::all_captures()
1 parent 144c4dc commit 56d34f0

File tree

2 files changed

+44
-39
lines changed

2 files changed

+44
-39
lines changed

crates/ark/src/lsp/inputs/package_namespace.rs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,23 @@ impl Namespace {
5151
"#;
5252
let mut ts_query = TsQuery::new(query_str)?;
5353

54-
let mut exports = Vec::new();
55-
for capture in ts_query.captures_for(root_node, "exported", contents.as_bytes()) {
56-
let symbol = capture
57-
.utf8_text(contents.as_bytes())
58-
.unwrap_or("")
59-
.to_string();
60-
exports.push(symbol);
61-
}
62-
63-
let mut imports = Vec::new();
64-
for capture in ts_query.captures_for(root_node, "imported", contents.as_bytes()) {
65-
let symbol = capture
66-
.utf8_text(contents.as_bytes())
67-
.unwrap_or("")
68-
.to_string();
69-
imports.push(symbol);
70-
}
71-
72-
let mut package_imports = Vec::new();
73-
for capture in ts_query.captures_for(root_node, "bulk_imported", contents.as_bytes()) {
74-
let symbol = capture
75-
.utf8_text(contents.as_bytes())
76-
.unwrap_or("")
77-
.to_string();
78-
package_imports.push(symbol);
79-
}
54+
let all_captures = ts_query.all_captures(root_node, contents.as_bytes());
55+
56+
let filter_captures = |capture_name: &str| -> Vec<String> {
57+
all_captures
58+
.iter()
59+
.filter(|(name, _)| name == capture_name)
60+
.map(|(_, node)| {
61+
node.utf8_text(contents.as_bytes())
62+
.unwrap_or("")
63+
.to_string()
64+
})
65+
.collect()
66+
};
67+
68+
let mut exports = filter_captures("exported");
69+
let mut imports = filter_captures("imported");
70+
let mut package_imports = filter_captures("bulk_imported");
8071

8172
// Take unique values of imports and exports. In the future we'll lint
8273
// this but for now just be defensive.

crates/ark/src/treesitter.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -659,26 +659,40 @@ impl TsQuery {
659659
Self { query, cursor }
660660
}
661661

662-
/// Match query against `contents` and collect all nodes captured with the
663-
/// given capture name
662+
/// Run the query on `contents` and collect all captures as (capture_name, node) pairs
663+
pub(crate) fn all_captures<'tree>(
664+
&mut self,
665+
node: tree_sitter::Node<'tree>,
666+
contents: &[u8],
667+
) -> Vec<(String, tree_sitter::Node<'tree>)> {
668+
self.cursor
669+
.matches(&self.query, node, contents)
670+
.flat_map(|m| {
671+
m.captures.iter().map(|cap| {
672+
let cap_name = self.query.capture_names()[cap.index as usize].to_string();
673+
(cap_name, cap.node)
674+
})
675+
})
676+
.collect()
677+
}
678+
679+
/// Run the query on `contents` and filter captures that match `capture_name`
664680
pub(crate) fn captures_for<'tree>(
665681
&mut self,
666682
node: tree_sitter::Node<'tree>,
667683
capture_name: &str,
668684
contents: &[u8],
669685
) -> Vec<tree_sitter::Node<'tree>> {
670-
let mut result = Vec::new();
671-
672-
for m in self.cursor.matches(&self.query, node, contents) {
673-
for cap in m.captures.iter() {
674-
let cap_name = &self.query.capture_names()[cap.index as usize];
675-
if *cap_name == capture_name {
676-
result.push(cap.node);
686+
self.all_captures(node, contents)
687+
.into_iter()
688+
.filter_map(|(name, node)| {
689+
if name == capture_name {
690+
Some(node)
691+
} else {
692+
None
677693
}
678-
}
679-
}
680-
681-
result
694+
})
695+
.collect()
682696
}
683697
}
684698

0 commit comments

Comments
 (0)