sqry_core/relations/queries/
mod.rs1use std::collections::HashSet;
9
10use tree_sitter::StreamingIterator;
11use tree_sitter::{Node, Query, QueryCursor, Tree};
12
13#[derive(Debug, Clone, Copy)]
16pub struct QuerySpec {
17 pub name: &'static str,
19 pub capture: &'static str,
21 pub source: &'static str,
23}
24
25impl QuerySpec {
26 pub fn run<'tree>(
36 &self,
37 tree: &'tree Tree,
38 content: &[u8],
39 ) -> Result<Vec<Node<'tree>>, String> {
40 let language = tree.language();
41 let query = Query::new(&language, self.source)
42 .map_err(|err| format!("failed to compile query `{}`: {err}", self.name))?;
43 let capture_index = query
44 .capture_names()
45 .iter()
46 .position(|name| *name == self.capture)
47 .ok_or_else(|| format!("query `{}` missing capture `{}`", self.name, self.capture))?;
48
49 let mut cursor = QueryCursor::new();
50 let mut matches = cursor.matches(&query, tree.root_node(), content);
51 let mut seen_offsets = HashSet::new();
52 let mut nodes = Vec::new();
53
54 while let Some(m) = matches.next() {
55 for capture in m.captures {
56 if capture.index as usize == capture_index
57 && seen_offsets.insert(capture.node.start_byte())
58 {
59 nodes.push(capture.node);
60 }
61 }
62 }
63
64 Ok(nodes)
65 }
66}
67
68#[derive(Debug)]
71pub struct ImportQuerySet {
72 pub statements: &'static [QuerySpec],
74}
75
76#[derive(Debug)]
78pub struct ExportQuerySet {
79 pub statements: &'static [QuerySpec],
81}
82
83#[derive(Debug)]
85pub struct CallQuerySet {
86 pub roots: &'static [QuerySpec],
88}
89
90pub mod typescript {
91 use super::{CallQuerySet, ExportQuerySet, ImportQuerySet, QuerySpec};
94
95 pub const IMPORT_QUERIES: ImportQuerySet = ImportQuerySet {
98 statements: &[QuerySpec {
99 name: "typescript_import_statements",
100 capture: "import.statement",
101 source: include_str!("typescript/imports.scm"),
102 }],
103 };
104
105 pub const EXPORT_QUERIES: ExportQuerySet = ExportQuerySet {
107 statements: &[QuerySpec {
108 name: "typescript_export_statements",
109 capture: "export.statement",
110 source: include_str!("typescript/exports.scm"),
111 }],
112 };
113
114 pub const CALL_QUERIES: CallQuerySet = CallQuerySet {
116 roots: &[QuerySpec {
117 name: "typescript_call_roots",
118 capture: "call.root",
119 source: include_str!("typescript/calls.scm"),
120 }],
121 };
122}
123
124pub mod javascript {
125 use super::{CallQuerySet, ExportQuerySet, ImportQuerySet, QuerySpec};
128
129 pub const IMPORT_QUERIES: ImportQuerySet = ImportQuerySet {
131 statements: &[QuerySpec {
132 name: "javascript_import_statements",
133 capture: "import.statement",
134 source: include_str!("javascript/imports.scm"),
135 }],
136 };
137
138 pub const EXPORT_QUERIES: ExportQuerySet = ExportQuerySet {
140 statements: &[QuerySpec {
141 name: "javascript_export_statements",
142 capture: "export.statement",
143 source: include_str!("javascript/exports.scm"),
144 }],
145 };
146
147 pub const CALL_QUERIES: CallQuerySet = CallQuerySet {
149 roots: &[QuerySpec {
150 name: "javascript_call_roots",
151 capture: "call.root",
152 source: include_str!("javascript/calls.scm"),
153 }],
154 };
155}
156
157pub mod csharp {
158 use super::{CallQuerySet, ImportQuerySet, QuerySpec};
161
162 pub const IMPORT_QUERIES: ImportQuerySet = ImportQuerySet {
164 statements: &[QuerySpec {
165 name: "csharp_using_directives",
166 capture: "import.directive",
167 source: include_str!("csharp/imports.scm"),
168 }],
169 };
170
171 pub const CALL_QUERIES: CallQuerySet = CallQuerySet {
173 roots: &[QuerySpec {
174 name: "csharp_call_roots",
175 capture: "call.root",
176 source: include_str!("csharp/calls.scm"),
177 }],
178 };
179}
180
181pub mod go {
182 use super::{CallQuerySet, ExportQuerySet, ImportQuerySet, QuerySpec};
185
186 pub const IMPORT_QUERIES: ImportQuerySet = ImportQuerySet {
188 statements: &[QuerySpec {
189 name: "go_import_declarations",
190 capture: "import.declaration",
191 source: include_str!("go/imports.scm"),
192 }],
193 };
194
195 pub const CALL_QUERIES: CallQuerySet = CallQuerySet {
197 roots: &[QuerySpec {
198 name: "go_call_roots",
199 capture: "call.root",
200 source: include_str!("go/calls.scm"),
201 }],
202 };
203
204 pub const EXPORT_QUERIES: ExportQuerySet = ExportQuerySet {
206 statements: &[QuerySpec {
207 name: "go_export_declarations",
208 capture: "export.declaration",
209 source: include_str!("go/exports.scm"),
210 }],
211 };
212}