use tree_sitter::{Language, Node, Query};
pub struct CachedQuery {
pub query: Query,
}
impl CachedQuery {
pub fn new(language: &Language, pattern: &str) -> Self {
let query = Query::new(language, pattern)
.unwrap_or_else(|e| panic!("invalid tree-sitter query: {e}\npattern: {pattern}"));
Self { query }
}
pub fn try_new(language: &Language, pattern: &str) -> Option<Self> {
Query::new(language, pattern)
.ok()
.map(|query| Self { query })
}
pub fn capture_index(&self, name: &str) -> u32 {
self.query
.capture_index_for_name(name)
.unwrap_or_else(|| panic!("capture @{name} not found in query"))
}
}
pub fn is_inside_nested_scope(node: Node, root: Node, scope_kinds: &[&str]) -> bool {
let mut current = node.parent();
while let Some(p) = current {
if p.id() == root.id() {
return false;
}
if scope_kinds.contains(&p.kind()) {
return true;
}
current = p.parent();
}
false
}
#[cfg(test)]
mod tests {
use super::*;
use tree_sitter::Language;
#[test]
fn test_cached_query_compiles() {
let lang = Language::new(tree_sitter_python::LANGUAGE);
let q = CachedQuery::new(&lang, "(call function: (identifier) @callee)");
assert_eq!(q.capture_index("callee"), 0);
}
}