syncat_stylesheet/stylesheet/
query.rs

1use super::Matches;
2use crate::ast::{Node, NodeKind, NodeModifier};
3use std::ops::{Index, IndexMut};
4
5#[derive(Clone, Debug)]
6pub struct Query<'s> {
7    kind: &'s str,
8    text: &'s str,
9    children: Vec<Query<'s>>,
10}
11
12impl<'s> From<&'s str> for Query<'s> {
13    fn from(kind: &'s str) -> Self {
14        Self {
15            kind,
16            text: kind,
17            children: vec![],
18        }
19    }
20}
21
22impl<'s> From<(&tree_sitter::Node<'_>, &'s str)> for Query<'s> {
23    fn from((node, source): (&tree_sitter::Node, &'s str)) -> Self {
24        Self {
25            kind: node.kind(),
26            text: node.utf8_text(source.as_ref()).unwrap(),
27            children: vec![],
28        }
29    }
30}
31
32impl<'s> Query<'s> {
33    pub fn new(kind: &'s str, text: &'s str) -> Self {
34        Self {
35            kind,
36            text,
37            children: vec![],
38        }
39    }
40
41    pub fn add_child<Q: Into<Self>>(&mut self, child: Q) {
42        self.children.push(child.into())
43    }
44
45    fn matches<'k, 'a: 's>(&'a self, node: &'k NodeKind) -> Option<Matches<'k, 's>> {
46        match node {
47            NodeKind::Any => Some(Matches::default()),
48            NodeKind::Kind(kind) => {
49                if self.kind == kind {
50                    Some(Matches::default())
51                } else {
52                    None
53                }
54            }
55            NodeKind::Token(token) => {
56                if self.children.is_empty() && self.text == token {
57                    Some(Matches::default())
58                } else {
59                    None
60                }
61            }
62            NodeKind::TokenPattern(pattern) => {
63                if !self.children.is_empty() {
64                    return None;
65                }
66                let captures = pattern.captures(self.text)?;
67                let mut matches = Matches::default();
68                matches.push(captures);
69                Some(matches)
70            }
71            NodeKind::Group(None, selector) => selector.matches(self),
72            NodeKind::Group(Some(name), selector) => {
73                let mut matches = selector.matches(self)?;
74                matches.insert(name, self.text);
75                Some(matches)
76            }
77            NodeKind::Not(node) => {
78                if self.matches(node).is_some() {
79                    None
80                } else {
81                    Some(Matches::default())
82                }
83            }
84        }
85    }
86
87    fn indices(&self) -> Vec<usize> {
88        let len = self.children.len();
89        if len != 0 {
90            let mut indices = self.children.last().unwrap().indices();
91            indices.insert(0, len - 1);
92            indices
93        } else {
94            vec![]
95        }
96    }
97}
98
99impl<'a> Index<&[usize]> for Query<'a> {
100    type Output = Query<'a>;
101
102    fn index(&self, index: &[usize]) -> &Self::Output {
103        if index.is_empty() {
104            self
105        } else {
106            &self.children[index[0]][&index[1..]]
107        }
108    }
109}
110
111impl IndexMut<&[usize]> for Query<'_> {
112    fn index_mut(&mut self, index: &[usize]) -> &mut Self::Output {
113        if index.is_empty() {
114            self
115        } else {
116            &mut self.children[index[0]][&index[1..]]
117        }
118    }
119}
120
121#[derive(Clone)]
122pub(crate) struct QuerySlice<'s, 'a: 's> {
123    query: &'a Query<'s>,
124    indices: Vec<usize>,
125}
126
127impl<'a, 's> QuerySlice<'s, 'a> {
128    pub(crate) fn new(query: &'a Query<'s>, modifier: NodeModifier) -> Self {
129        let mut indices = query.indices();
130        match modifier {
131            NodeModifier::Child | NodeModifier::DirectChild => indices.push(0),
132            NodeModifier::Sibling | NodeModifier::DirectSibling => {
133                *indices.last_mut().unwrap() += 1
134            }
135            NodeModifier::Also => {}
136        }
137        Self { query, indices }
138    }
139
140    pub(crate) fn find<'k>(&self, node: &'k Node) -> Option<(Self, Matches<'k, 's>)> {
141        match node.modifier {
142            NodeModifier::Child => self.find_child(&node.kind),
143            NodeModifier::DirectChild => self.find_direct_child(&node.kind).ok(),
144            NodeModifier::Sibling => self.find_sibling(&node.kind),
145            NodeModifier::DirectSibling => self.find_direct_sibling(&node.kind).ok(),
146            NodeModifier::Also => self.find_here(&node.kind).ok(),
147        }
148    }
149
150    fn pop(&self) -> Option<Self> {
151        let mut indices = self.indices.clone();
152        indices.pop()?;
153        Some(Self {
154            query: self.query,
155            indices,
156        })
157    }
158
159    fn shift(&self) -> Option<Self> {
160        let mut indices = self.indices.clone();
161        let last = indices.last_mut()?;
162        *last = last.checked_sub(1)?;
163        Some(Self {
164            query: self.query,
165            indices,
166        })
167    }
168
169    fn find_here<'k>(&self, node: &'k NodeKind) -> Result<(Self, Matches<'k, 's>), Option<Self>> {
170        let query = &self.query[&self.indices];
171        if let Some(matches) = query.matches(node) {
172            Ok((self.clone(), matches))
173        } else {
174            Err(Some(self.clone()))
175        }
176    }
177
178    fn find_child<'k>(&self, node: &'k NodeKind) -> Option<(Self, Matches<'k, 's>)> {
179        match node {
180            NodeKind::Not(node) => match self.find_child(node) {
181                None => Some((self.clone(), Matches::default())),
182                Some(..) => None,
183            },
184            node => match self.find_direct_child(node) {
185                Ok(result) => Some(result),
186                Err(query) => query?.find_child(node),
187            },
188        }
189    }
190
191    fn find_direct_child<'k>(
192        &self,
193        node: &'k NodeKind,
194    ) -> Result<(Self, Matches<'k, 's>), Option<Self>> {
195        match node {
196            NodeKind::Not(node) => {
197                let index = match self.pop() {
198                    Some(index) => index,
199                    None => return Ok((self.clone(), Matches::default())),
200                };
201                let query = &self.query[&index.indices];
202                match query.matches(node) {
203                    Some(..) => Err(Some(index)),
204                    None => Ok((index, Matches::default())),
205                }
206            }
207            node => {
208                let index = self.pop().ok_or(None)?;
209                let query = &self.query[&index.indices];
210                if let Some(matches) = query.matches(node) {
211                    Ok((index, matches))
212                } else {
213                    Err(Some(index))
214                }
215            }
216        }
217    }
218
219    fn find_sibling<'k>(&self, node: &'k NodeKind) -> Option<(Self, Matches<'k, 's>)> {
220        match node {
221            NodeKind::Not(node) => match self.find_sibling(node) {
222                None => Some((self.clone(), Matches::default())),
223                Some(..) => None,
224            },
225            node => match self.find_direct_sibling(node) {
226                Ok(result) => Some(result),
227                Err(query) => query?.find_sibling(node),
228            },
229        }
230    }
231
232    fn find_direct_sibling<'k>(
233        &self,
234        node: &'k NodeKind,
235    ) -> Result<(Self, Matches<'k, 's>), Option<Self>> {
236        match node {
237            NodeKind::Not(node) => {
238                let index = match self.shift() {
239                    Some(index) => index,
240                    None => return Ok((self.clone(), Matches::default())),
241                };
242                let query = &self.query[&index.indices];
243                match query.matches(node) {
244                    Some(..) => Err(Some(index)),
245                    None => Ok((index, Matches::default())),
246                }
247            }
248            node => {
249                let index = self.shift().ok_or(None)?;
250                let query = &self.query[&index.indices];
251                if let Some(matches) = query.matches(node) {
252                    Ok((index, matches))
253                } else {
254                    Err(Some(index))
255                }
256            }
257        }
258    }
259}