syncat_stylesheet/stylesheet/
query.rs1use 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}