Skip to content

Commit 1886249

Browse files
committed
Add TsQuery::captures_by
1 parent 56d34f0 commit 1886249

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,35 @@ impl Namespace {
4545
)
4646
(call
4747
function: (identifier) @fn_name
48-
arguments: (arguments (argument value: (identifier) @bulk_imported))
48+
arguments: (arguments (argument value: (identifier) @imported_pkgs))
4949
(#eq? @fn_name "import")
5050
)
5151
"#;
5252
let mut ts_query = TsQuery::new(query_str)?;
5353

54-
let all_captures = ts_query.all_captures(root_node, contents.as_bytes());
54+
let captures = ts_query.captures_by(
55+
root_node,
56+
&["exported", "imported", "imported_pkgs"],
57+
contents.as_bytes(),
58+
);
5559

56-
let filter_captures = |capture_name: &str| -> Vec<String> {
57-
all_captures
60+
let as_strings = |nodes: &Vec<tree_sitter::Node>| {
61+
nodes
5862
.iter()
59-
.filter(|(name, _)| name == capture_name)
60-
.map(|(_, node)| {
63+
.map(|node| {
6164
node.utf8_text(contents.as_bytes())
6265
.unwrap_or("")
6366
.to_string()
6467
})
65-
.collect()
68+
.collect::<Vec<_>>()
6669
};
6770

68-
let mut exports = filter_captures("exported");
69-
let mut imports = filter_captures("imported");
70-
let mut package_imports = filter_captures("bulk_imported");
71+
let mut exports = captures.get("exported").map(as_strings).unwrap_or_default();
72+
let mut imports = captures.get("imported").map(as_strings).unwrap_or_default();
73+
let mut package_imports = captures
74+
.get("imported_pkgs")
75+
.map(as_strings)
76+
.unwrap_or_default();
7177

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

crates/ark/src/treesitter.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashMap;
2+
13
use anyhow::anyhow;
24
use tree_sitter::Node;
35

@@ -694,6 +696,29 @@ impl TsQuery {
694696
})
695697
.collect()
696698
}
699+
700+
/// Run the query on `contents` and filter captures that match `capture_names`.
701+
/// They are returned in a hashmap keyed by capture name.
702+
pub(crate) fn captures_by<'tree>(
703+
&mut self,
704+
node: tree_sitter::Node<'tree>,
705+
capture_names: &[&str],
706+
contents: &[u8],
707+
) -> HashMap<String, Vec<tree_sitter::Node<'tree>>> {
708+
let mut result: HashMap<String, Vec<tree_sitter::Node<'tree>>> = HashMap::new();
709+
710+
for &name in capture_names {
711+
result.insert(name.to_string(), Vec::new());
712+
}
713+
714+
for (name, node) in self.all_captures(node, contents) {
715+
if let Some(nodes) = result.get_mut(&name) {
716+
nodes.push(node);
717+
}
718+
}
719+
720+
result
721+
}
697722
}
698723

699724
#[cfg(test)]

0 commit comments

Comments
 (0)