1use std::{
2 borrow::Cow,
3 ops::{Index, IndexMut},
4};
5
6use hashbrown::HashMap;
7use kstring::KString;
8use ropey::RopeSlice;
9use tree_sitter::{Capture, InactiveQueryCursor};
10
11use crate::{LanguageConfig, LanguageLoader, Layer, Range, Syntax, TREE_SITTER_MATCH_LIMIT};
12
13#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
14pub struct Scope(u32);
15
16impl Scope {
17 const ROOT: Scope = Scope(0);
18 fn idx(self) -> usize {
19 self.0 as usize
20 }
21}
22
23#[derive(Debug)]
24pub struct Locals {
25 scopes: Vec<ScopeData>,
26}
27
28impl Default for Locals {
29 fn default() -> Self {
30 let mut scopes = Vec::with_capacity(4);
31 scopes.push(ScopeData {
32 definitions: HashMap::new(),
33 range: 0..u32::MAX,
34 inherit: false,
35 children: Vec::new(),
36 parent: None,
37 });
38
39 Self { scopes }
40 }
41}
42
43impl Locals {
44 fn push(&mut self, scope: ScopeData) -> Scope {
45 let new_scope_id = Scope(self.scopes.len() as u32);
46 let parent = scope
47 .parent
48 .expect("push cannot be used for the root layer");
49 self[parent].children.push(new_scope_id);
50 self.scopes.push(scope);
51 new_scope_id
52 }
53
54 pub fn lookup_reference(&self, mut scope: Scope, name: &str) -> Option<&Definition> {
55 loop {
56 let scope_data = &self[scope];
57 if let Some(def) = scope_data.definitions.get(name) {
58 return Some(def);
59 }
60 if !scope_data.inherit {
61 break;
62 }
63 scope = scope_data.parent?;
64 }
65
66 None
67 }
68
69 pub fn scope_cursor(&self, pos: u32) -> ScopeCursor<'_> {
70 let mut scope = Scope::ROOT;
71 let mut scope_stack = Vec::with_capacity(8);
72 loop {
73 let scope_data = &self[scope];
74 let child_idx = scope_data
75 .children
76 .partition_point(|&child| self[child].range.end < pos);
77 scope_stack.push((scope, child_idx as u32));
78 let Some(&child) = scope_data.children.get(child_idx) else {
79 break;
80 };
81 if pos < self[child].range.start {
82 break;
83 }
84 scope = child;
85 }
86 ScopeCursor {
87 locals: self,
88 scope_stack,
89 }
90 }
91}
92
93impl Index<Scope> for Locals {
94 type Output = ScopeData;
95
96 fn index(&self, scope: Scope) -> &Self::Output {
97 &self.scopes[scope.idx()]
98 }
99}
100
101impl IndexMut<Scope> for Locals {
102 fn index_mut(&mut self, scope: Scope) -> &mut Self::Output {
103 &mut self.scopes[scope.idx()]
104 }
105}
106
107#[derive(Debug)]
108pub struct ScopeCursor<'a> {
109 pub locals: &'a Locals,
110 scope_stack: Vec<(Scope, u32)>,
111}
112
113impl ScopeCursor<'_> {
114 pub fn advance(&mut self, to: u32) -> Scope {
115 let (mut active_scope, mut child_idx) = self.scope_stack.pop().unwrap();
116 loop {
117 let scope_data = &self.locals[active_scope];
118 if to < scope_data.range.end {
119 break;
120 }
121 (active_scope, child_idx) = self.scope_stack.pop().unwrap();
122 child_idx += 1;
123 }
124 'outer: loop {
125 let scope_data = &self.locals[active_scope];
126 loop {
127 let Some(&child) = scope_data.children.get(child_idx as usize) else {
128 break 'outer;
129 };
130 if self.locals[child].range.start > to {
131 break 'outer;
132 }
133 if to < self.locals[child].range.end {
134 self.scope_stack.push((active_scope, child_idx));
135 active_scope = child;
136 child_idx = 0;
137 break;
138 }
139 child_idx += 1;
140 }
141 }
142 self.scope_stack.push((active_scope, child_idx));
143 active_scope
144 }
145
146 pub fn current_scope(&self) -> Scope {
147 self.scope_stack.last().unwrap().0
149 }
150}
151
152#[derive(Debug)]
153pub struct Definition {
154 pub capture: Capture,
155 pub range: Range,
156}
157
158#[derive(Debug)]
159pub struct ScopeData {
160 definitions: HashMap<KString, Definition>,
161 range: Range,
162 inherit: bool,
163 children: Vec<Scope>,
168 parent: Option<Scope>,
169}
170
171impl Syntax {
172 pub(crate) fn run_local_query(
173 &mut self,
174 layer: Layer,
175 source: RopeSlice<'_>,
176 loader: &impl LanguageLoader,
177 ) {
178 let layer_data = &mut self.layer_mut(layer);
179 let Some(LanguageConfig {
180 ref injection_query,
181 ..
182 }) = loader.get_config(layer_data.language)
183 else {
184 return;
185 };
186 let definition_captures = injection_query.local_definition_captures.load();
187 if definition_captures.is_empty() {
188 return;
189 }
190
191 let root = layer_data.parse_tree.as_ref().unwrap().root_node();
192 let mut cursor = InactiveQueryCursor::new(0..u32::MAX, TREE_SITTER_MATCH_LIMIT)
193 .execute_query(&injection_query.local_query, &root, source);
194 let mut locals = Locals::default();
195 let mut scope = Scope::ROOT;
196
197 while let Some((query_match, node_idx)) = cursor.next_matched_node() {
198 let matched_node = query_match.matched_node(node_idx);
199 let range = matched_node.node.byte_range();
200 let capture = matched_node.capture;
201
202 while range.start >= locals[scope].range.end {
203 scope = locals[scope].parent.expect("root node covers entire range");
204 }
205
206 if Some(capture) == injection_query.local_scope_capture {
207 scope = locals.push(ScopeData {
208 definitions: HashMap::new(),
209 range: matched_node.node.byte_range(),
210 inherit: !injection_query
211 .not_scope_inherits
212 .contains(&query_match.pattern()),
213 children: Vec::new(),
214 parent: Some(scope),
215 });
216 } else if definition_captures.contains_key(&capture) {
217 let text = match source
218 .byte_slice(range.start as usize..range.end as usize)
219 .into()
220 {
221 Cow::Borrowed(inner) => KString::from_ref(inner),
222 Cow::Owned(inner) => KString::from_string(inner),
223 };
224 locals[scope]
225 .definitions
226 .insert(text, Definition { capture, range });
227 }
228 }
231
232 layer_data.locals = locals;
233 }
234}
235
236#[cfg(test)]
237mod test {
238 use super::*;
239
240 #[test]
241 fn cursor() {
242 let mut locals = Locals::default();
243 let scope1 = locals.push(ScopeData {
244 definitions: Default::default(),
245 range: 5..105,
246 inherit: true,
247 children: Default::default(),
249 parent: Some(Scope::ROOT),
250 });
251 let scope2 = locals.push(ScopeData {
252 definitions: Default::default(),
253 range: 10..100,
254 inherit: true,
255 children: Default::default(),
256 parent: Some(scope1),
257 });
258
259 let mut cursor = locals.scope_cursor(0);
260 assert_eq!(cursor.current_scope(), Scope::ROOT);
261 assert_eq!(cursor.advance(3), Scope::ROOT);
262 assert_eq!(cursor.advance(5), scope1);
263 assert_eq!(cursor.advance(8), scope1);
264 assert_eq!(cursor.advance(10), scope2);
265 assert_eq!(cursor.advance(50), scope2);
266 assert_eq!(cursor.advance(100), scope1);
267 assert_eq!(cursor.advance(105), Scope::ROOT);
268 assert_eq!(cursor.advance(110), Scope::ROOT);
269
270 let mut cursor = locals.scope_cursor(8);
271 assert_eq!(cursor.current_scope(), scope1);
272 assert_eq!(cursor.advance(10), scope2);
273 assert_eq!(cursor.advance(100), scope1);
274 assert_eq!(cursor.advance(110), Scope::ROOT);
275
276 let mut cursor = locals.scope_cursor(10);
277 assert_eq!(cursor.current_scope(), scope2);
278 assert_eq!(cursor.advance(100), scope1);
279 assert_eq!(cursor.advance(110), Scope::ROOT);
280 }
281}